From 082a0130c295668d4c31da3dacc68cfd92a5953a Mon Sep 17 00:00:00 2001 From: Polonkai Gergely Date: Sun, 1 Jul 2012 09:52:20 +0200 Subject: [PATCH] Initial commit with Symfony 2.1+Vendors Signed-off-by: Gergely POLONKAI (W00d5t0ck) --- LICENSE | 19 + README.md | 174 + app/.htaccess | 1 + app/AppCache.php | 9 + app/AppKernel.php | 38 + app/Resources/views/base.html.twig | 13 + app/SymfonyRequirements.php | 580 ++++ app/autoload.php | 32 + app/bootstrap.php.cache | 1455 ++++++++ app/cache/.gitkeep | 0 app/check.php | 55 + app/config/config.yml | 60 + app/config/config_dev.yml | 26 + app/config/config_prod.yml | 19 + app/config/config_test.yml | 14 + app/config/parameters.yml | 15 + app/config/routing.yml | 4 + app/config/routing_dev.yml | 27 + app/config/security.yml | 43 + app/console | 22 + app/logs/.gitkeep | 0 app/phpunit.xml.dist | 41 + composer.json | 41 + composer.lock | 144 + src/.htaccess | 1 + src/Acme/DemoBundle/AcmeDemoBundle.php | 9 + .../DemoBundle/Controller/DemoController.php | 57 + .../Controller/SecuredController.php | 69 + .../Controller/WelcomeController.php | 18 + .../DependencyInjection/AcmeDemoExtension.php | 22 + .../EventListener/ControllerListener.php | 25 + src/Acme/DemoBundle/Form/ContactType.php | 20 + .../DemoBundle/Resources/config/services.xml | 18 + .../DemoBundle/Resources/public/css/demo.css | 294 ++ .../Resources/public/images/blue-arrow.png | Bin 0 -> 181 bytes .../public/images/field-background.gif | Bin 0 -> 63 bytes .../Resources/public/images/logo.gif | Bin 0 -> 1698 bytes .../Resources/public/images/search.png | Bin 0 -> 737 bytes .../public/images/welcome-configure.gif | Bin 0 -> 3530 bytes .../Resources/public/images/welcome-demo.gif | Bin 0 -> 4053 bytes .../public/images/welcome-quick-tour.gif | Bin 0 -> 4770 bytes .../Resources/views/Demo/contact.html.twig | 15 + .../Resources/views/Demo/hello.html.twig | 9 + .../Resources/views/Demo/index.html.twig | 14 + .../Resources/views/Secured/hello.html.twig | 11 + .../views/Secured/helloadmin.html.twig | 9 + .../Resources/views/Secured/layout.html.twig | 6 + .../Resources/views/Secured/login.html.twig | 29 + .../Resources/views/Welcome/index.html.twig | 63 + .../Resources/views/layout.html.twig | 49 + .../Tests/Controller/DemoControllerTest.php | 17 + .../Twig/Extension/DemoExtension.php | 80 + vendor/ClassLoader.php | 203 ++ vendor/autoload.php | 27 + vendor/autoload_classmap.php | 9 + vendor/autoload_namespaces.php | 32 + vendor/composer/ClassLoader.php | 205 ++ vendor/composer/autoload_classmap.php | 9 + vendor/composer/autoload_namespaces.php | 31 + vendor/composer/installed.json | 1171 +++++++ vendor/composer/installed_dev.json | 3 + vendor/doctrine/common/.travis.yml | 5 + vendor/doctrine/common/LICENSE | 504 +++ vendor/doctrine/common/README.md | 12 + vendor/doctrine/common/UPGRADE_TO_2_1 | 39 + vendor/doctrine/common/UPGRADE_TO_2_2 | 61 + vendor/doctrine/common/composer.json | 21 + .../Common/Annotations/Annotation.php | 75 + .../Annotations/Annotation/Attribute.php | 47 + .../Annotations/Annotation/Attributes.php | 37 + .../Annotation/IgnoreAnnotation.php | 44 + .../Annotations/Annotation/Required.php | 33 + .../Common/Annotations/Annotation/Target.php | 105 + .../Annotations/AnnotationException.php | 111 + .../Common/Annotations/AnnotationReader.php | 301 ++ .../Common/Annotations/AnnotationRegistry.php | 129 + .../Common/Annotations/CachedReader.php | 179 + .../Doctrine/Common/Annotations/DocLexer.php | 140 + .../Doctrine/Common/Annotations/DocParser.php | 891 +++++ .../Common/Annotations/FileCacheReader.php | 209 ++ .../Common/Annotations/IndexedReader.php | 94 + .../Doctrine/Common/Annotations/PhpParser.php | 203 ++ .../Doctrine/Common/Annotations/Reader.php | 35 + .../Annotations/SimpleAnnotationReader.php | 152 + .../lib/Doctrine/Common/Cache/ApcCache.php | 97 + .../lib/Doctrine/Common/Cache/ArrayCache.php | 96 + .../lib/Doctrine/Common/Cache/Cache.php | 102 + .../Doctrine/Common/Cache/CacheProvider.php | 188 + .../Doctrine/Common/Cache/MemcacheCache.php | 121 + .../Doctrine/Common/Cache/MemcachedCache.php | 124 + .../Doctrine/Common/Cache/WinCacheCache.php | 92 + .../lib/Doctrine/Common/Cache/XcacheCache.php | 110 + .../Doctrine/Common/Cache/ZendDataCache.php | 84 + .../lib/Doctrine/Common/ClassLoader.php | 262 ++ .../Common/Collections/ArrayCollection.php | 447 +++ .../Common/Collections/Collection.php | 243 ++ .../lib/Doctrine/Common/CommonException.php | 28 + .../common/lib/Doctrine/Common/Comparable.php | 47 + .../common/lib/Doctrine/Common/EventArgs.php | 69 + .../lib/Doctrine/Common/EventManager.php | 136 + .../lib/Doctrine/Common/EventSubscriber.php | 45 + .../common/lib/Doctrine/Common/Lexer.php | 266 ++ .../Doctrine/Common/NotifyPropertyChanged.php | 45 + .../Persistence/AbstractManagerRegistry.php | 218 ++ .../Common/Persistence/ConnectionRegistry.php | 63 + .../Persistence/Event/LifecycleEventArgs.php | 77 + .../Event/LoadClassMetadataEventArgs.php | 76 + .../Persistence/Event/ManagerEventArgs.php | 59 + .../Persistence/Event/OnClearEventArgs.php | 84 + .../Persistence/Event/PreUpdateEventArgs.php | 129 + .../Common/Persistence/ManagerRegistry.php | 112 + .../Mapping/AbstractClassMetadataFactory.php | 359 ++ .../Persistence/Mapping/ClassMetadata.php | 165 + .../Mapping/ClassMetadataFactory.php | 74 + .../Mapping/Driver/AnnotationDriver.php | 214 ++ .../Mapping/Driver/DefaultFileLocator.php | 169 + .../Persistence/Mapping/Driver/FileDriver.php | 178 + .../Mapping/Driver/FileLocator.php | 69 + .../Mapping/Driver/MappingDriver.php | 56 + .../Mapping/Driver/MappingDriverChain.php | 125 + .../Persistence/Mapping/Driver/PHPDriver.php | 70 + .../Mapping/Driver/StaticPHPDriver.php | 131 + .../Mapping/Driver/SymfonyFileLocator.php | 198 ++ .../Persistence/Mapping/MappingException.php | 57 + .../Persistence/Mapping/ReflectionService.php | 80 + .../Mapping/RuntimeReflectionService.php | 102 + .../Mapping/StaticReflectionService.php | 107 + .../Common/Persistence/ObjectManager.php | 143 + .../Common/Persistence/ObjectManagerAware.php | 49 + .../Common/Persistence/ObjectRepository.php | 78 + .../Common/Persistence/PersistentObject.php | 233 ++ .../lib/Doctrine/Common/Persistence/Proxy.php | 60 + .../Common/PropertyChangedListener.php | 48 + .../lib/Doctrine/Common/Util/ClassUtils.php | 103 + .../common/lib/Doctrine/Common/Util/Debug.php | 123 + .../lib/Doctrine/Common/Util/Inflector.php | 72 + .../common/lib/Doctrine/Common/Version.php | 55 + vendor/doctrine/common/phpunit.xml.dist | 31 + vendor/doctrine/dbal/.travis.yml | 20 + vendor/doctrine/dbal/LICENSE | 504 +++ vendor/doctrine/dbal/README.md | 14 + vendor/doctrine/dbal/UPGRADE | 72 + vendor/doctrine/dbal/composer.json | 21 + .../Doctrine/DBAL/Cache/ArrayStatement.php | 98 + .../Doctrine/DBAL/Cache/CacheException.php | 37 + .../Doctrine/DBAL/Cache/QueryCacheProfile.php | 131 + .../DBAL/Cache/ResultCacheStatement.php | 255 ++ .../dbal/lib/Doctrine/DBAL/Configuration.php | 113 + .../dbal/lib/Doctrine/DBAL/Connection.php | 1168 +++++++ .../lib/Doctrine/DBAL/ConnectionException.php | 54 + .../Connections/MasterSlaveConnection.php | 329 ++ .../dbal/lib/Doctrine/DBAL/DBALException.php | 88 + .../dbal/lib/Doctrine/DBAL/Driver.php | 72 + .../lib/Doctrine/DBAL/Driver/Connection.php | 42 + .../DBAL/Driver/IBMDB2/DB2Connection.php | 115 + .../Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php | 111 + .../DBAL/Driver/IBMDB2/DB2Exception.php | 27 + .../DBAL/Driver/IBMDB2/DB2Statement.php | 215 ++ .../Doctrine/DBAL/Driver/Mysqli/Driver.php | 69 + .../DBAL/Driver/Mysqli/MysqliConnection.php | 146 + .../DBAL/Driver/Mysqli/MysqliException.php | 26 + .../DBAL/Driver/Mysqli/MysqliStatement.php | 335 ++ .../lib/Doctrine/DBAL/Driver/OCI8/Driver.php | 95 + .../DBAL/Driver/OCI8/OCI8Connection.php | 172 + .../DBAL/Driver/OCI8/OCI8Exception.php | 30 + .../DBAL/Driver/OCI8/OCI8Statement.php | 258 ++ .../Doctrine/DBAL/Driver/PDOConnection.php | 40 + .../Doctrine/DBAL/Driver/PDOIbm/Driver.php | 126 + .../Doctrine/DBAL/Driver/PDOMySql/Driver.php | 102 + .../Doctrine/DBAL/Driver/PDOOracle/Driver.php | 98 + .../Doctrine/DBAL/Driver/PDOPgSql/Driver.php | 70 + .../Doctrine/DBAL/Driver/PDOSqlite/Driver.php | 116 + .../DBAL/Driver/PDOSqlsrv/Connection.php | 45 + .../Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php | 88 + .../lib/Doctrine/DBAL/Driver/PDOStatement.php | 50 + .../Doctrine/DBAL/Driver/ResultStatement.php | 113 + .../lib/Doctrine/DBAL/Driver/Statement.php | 124 + .../dbal/lib/Doctrine/DBAL/DriverManager.php | 165 + .../DBAL/Event/ConnectionEventArgs.php | 79 + .../DBAL/Event/Listeners/MysqlSessionInit.php | 74 + .../Event/Listeners/OracleSessionInit.php | 79 + .../DBAL/Event/Listeners/SQLSessionInit.php | 63 + .../SchemaAlterTableAddColumnEventArgs.php | 114 + .../SchemaAlterTableChangeColumnEventArgs.php | 114 + .../DBAL/Event/SchemaAlterTableEventArgs.php | 99 + .../SchemaAlterTableRemoveColumnEventArgs.php | 114 + .../SchemaAlterTableRenameColumnEventArgs.php | 129 + .../Event/SchemaColumnDefinitionEventArgs.php | 137 + .../SchemaCreateTableColumnEventArgs.php | 114 + .../DBAL/Event/SchemaCreateTableEventArgs.php | 128 + .../DBAL/Event/SchemaDropTableEventArgs.php | 98 + .../Doctrine/DBAL/Event/SchemaEventArgs.php | 56 + .../Event/SchemaIndexDefinitionEventArgs.php | 122 + .../dbal/lib/Doctrine/DBAL/Events.php | 48 + .../dbal/lib/Doctrine/DBAL/LockMode.php | 42 + .../lib/Doctrine/DBAL/Logging/DebugStack.php | 67 + .../Doctrine/DBAL/Logging/EchoSQLLogger.php | 61 + .../lib/Doctrine/DBAL/Logging/LoggerChain.php | 64 + .../lib/Doctrine/DBAL/Logging/SQLLogger.php | 54 + .../DBAL/Platforms/AbstractPlatform.php | 2645 ++++++++++++++ .../Doctrine/DBAL/Platforms/DB2Platform.php | 587 ++++ .../DBAL/Platforms/Keywords/DB2Keywords.php | 438 +++ .../DBAL/Platforms/Keywords/KeywordList.php | 63 + .../DBAL/Platforms/Keywords/MsSQLKeywords.php | 243 ++ .../DBAL/Platforms/Keywords/MySQLKeywords.php | 268 ++ .../Platforms/Keywords/OracleKeywords.php | 156 + .../Platforms/Keywords/PostgreSQLKeywords.php | 131 + .../Keywords/ReservedKeywordsValidator.php | 116 + .../Platforms/Keywords/SQLiteKeywords.php | 164 + .../Doctrine/DBAL/Platforms/MySqlPlatform.php | 768 ++++ .../DBAL/Platforms/OraclePlatform.php | 840 +++++ .../DBAL/Platforms/PostgreSqlPlatform.php | 792 +++++ .../DBAL/Platforms/SQLServer2005Platform.php | 52 + .../DBAL/Platforms/SQLServer2008Platform.php | 90 + .../DBAL/Platforms/SQLServerPlatform.php | 865 +++++ .../DBAL/Platforms/SqlitePlatform.php | 519 +++ .../Doctrine/DBAL/Portability/Connection.php | 113 + .../Doctrine/DBAL/Portability/Statement.php | 191 + .../Query/Expression/CompositeExpression.php | 130 + .../Query/Expression/ExpressionBuilder.php | 264 ++ .../lib/Doctrine/DBAL/Query/QueryBuilder.php | 1091 ++++++ .../Doctrine/DBAL/Query/QueryException.php | 40 + .../dbal/lib/Doctrine/DBAL/README.markdown | 0 .../dbal/lib/Doctrine/DBAL/SQLParserUtils.php | 179 + .../Doctrine/DBAL/Schema/AbstractAsset.php | 204 ++ .../DBAL/Schema/AbstractSchemaManager.php | 890 +++++ .../dbal/lib/Doctrine/DBAL/Schema/Column.php | 423 +++ .../lib/Doctrine/DBAL/Schema/ColumnDiff.php | 58 + .../lib/Doctrine/DBAL/Schema/Comparator.php | 399 +++ .../lib/Doctrine/DBAL/Schema/Constraint.php | 38 + .../Doctrine/DBAL/Schema/DB2SchemaManager.php | 214 ++ .../DBAL/Schema/ForeignKeyConstraint.php | 164 + .../dbal/lib/Doctrine/DBAL/Schema/Index.php | 188 + .../DBAL/Schema/MySqlSchemaManager.php | 211 ++ .../DBAL/Schema/OracleSchemaManager.php | 286 ++ .../DBAL/Schema/PostgreSqlSchemaManager.php | 359 ++ .../DBAL/Schema/SQLServerSchemaManager.php | 247 ++ .../dbal/lib/Doctrine/DBAL/Schema/Schema.php | 367 ++ .../lib/Doctrine/DBAL/Schema/SchemaConfig.php | 98 + .../lib/Doctrine/DBAL/Schema/SchemaDiff.php | 176 + .../Doctrine/DBAL/Schema/SchemaException.php | 126 + .../lib/Doctrine/DBAL/Schema/Sequence.php | 87 + .../DBAL/Schema/SqliteSchemaManager.php | 190 + .../dbal/lib/Doctrine/DBAL/Schema/Table.php | 645 ++++ .../lib/Doctrine/DBAL/Schema/TableDiff.php | 136 + .../dbal/lib/Doctrine/DBAL/Schema/View.php | 53 + .../Visitor/CreateSchemaSqlCollector.php | 147 + .../Schema/Visitor/DropSchemaSqlCollector.php | 159 + .../Doctrine/DBAL/Schema/Visitor/Graphviz.php | 151 + .../Schema/Visitor/RemoveNamespacedAssets.php | 113 + .../Doctrine/DBAL/Schema/Visitor/Visitor.php | 75 + .../dbal/lib/Doctrine/DBAL/Statement.php | 247 ++ .../Tools/Console/Command/ImportCommand.php | 124 + .../Console/Command/ReservedWordsCommand.php | 133 + .../Tools/Console/Command/RunSqlCommand.php | 87 + .../Tools/Console/Helper/ConnectionHelper.php | 74 + .../lib/Doctrine/DBAL/Types/ArrayType.php | 57 + .../lib/Doctrine/DBAL/Types/BigIntType.php | 48 + .../dbal/lib/Doctrine/DBAL/Types/BlobType.php | 67 + .../lib/Doctrine/DBAL/Types/BooleanType.php | 57 + .../DBAL/Types/ConversionException.php | 65 + .../lib/Doctrine/DBAL/Types/DateTimeType.php | 59 + .../Doctrine/DBAL/Types/DateTimeTzType.php | 79 + .../dbal/lib/Doctrine/DBAL/Types/DateType.php | 59 + .../lib/Doctrine/DBAL/Types/DecimalType.php | 45 + .../lib/Doctrine/DBAL/Types/FloatType.php | 54 + .../lib/Doctrine/DBAL/Types/IntegerType.php | 53 + .../lib/Doctrine/DBAL/Types/ObjectType.php | 57 + .../lib/Doctrine/DBAL/Types/SmallIntType.php | 52 + .../lib/Doctrine/DBAL/Types/StringType.php | 50 + .../dbal/lib/Doctrine/DBAL/Types/TextType.php | 56 + .../dbal/lib/Doctrine/DBAL/Types/TimeType.php | 68 + .../dbal/lib/Doctrine/DBAL/Types/Type.php | 274 ++ .../Doctrine/DBAL/Types/VarDateTimeType.php | 60 + .../dbal/lib/Doctrine/DBAL/Version.php | 55 + vendor/doctrine/dbal/phpunit.xml.dist | 51 + vendor/doctrine/dbal/run-all.sh | 21 + .../Bundle/DoctrineBundle/.travis.yml | 10 + .../Command/CreateDatabaseDoctrineCommand.php | 76 + .../Command/DoctrineCommand.php | 55 + .../Command/DropDatabaseDoctrineCommand.php | 88 + .../GenerateEntitiesDoctrineCommand.php | 134 + .../Command/ImportMappingDoctrineCommand.php | 126 + .../ClearMetadataCacheDoctrineCommand.php | 58 + .../Proxy/ClearQueryCacheDoctrineCommand.php | 58 + .../Proxy/ClearResultCacheDoctrineCommand.php | 73 + .../Proxy/ConvertMappingDoctrineCommand.php | 68 + .../Proxy/CreateSchemaDoctrineCommand.php | 63 + .../Command/Proxy/DoctrineCommandHelper.php | 48 + .../Proxy/DropSchemaDoctrineCommand.php | 63 + ...nsureProductionSettingsDoctrineCommand.php | 58 + .../Command/Proxy/InfoDoctrineCommand.php | 57 + .../Command/Proxy/RunDqlDoctrineCommand.php | 63 + .../Command/Proxy/RunSqlDoctrineCommand.php | 53 + .../Proxy/UpdateSchemaDoctrineCommand.php | 67 + .../Command/Proxy/ValidateSchemaCommand.php | 59 + .../DoctrineBundle/ConnectionFactory.php | 85 + .../Controller/ProfilerController.php | 67 + .../DependencyInjection/Configuration.php | 388 +++ .../DependencyInjection/DoctrineExtension.php | 437 +++ .../Bundle/DoctrineBundle/DoctrineBundle.php | 120 + .../Doctrine/Bundle/DoctrineBundle/LICENSE | 13 + .../DoctrineBundle/ManagerConfigurator.php | 59 + .../Mapping/ClassMetadataCollection.php | 55 + .../Mapping/DisconnectedMetadataFactory.php | 26 + .../Mapping/MetadataFactory.php | 180 + .../Doctrine/Bundle/DoctrineBundle/README.md | 56 + .../Bundle/DoctrineBundle/Registry.php | 155 + .../DoctrineBundle/Resources/config/dbal.xml | 62 + .../DoctrineBundle/Resources/config/orm.xml | 97 + .../Resources/config/schema/doctrine-1.0.xsd | 190 + .../Resources/doc/configuration.rst | 305 ++ .../Resources/doc/installation.rst | 43 + .../Resources/views/Collector/db.html.twig | 122 + .../views/Collector/explain.html.twig | 20 + .../DoctrineBundle/Tests/BundleTest.php | 47 + .../DoctrineBundle/Tests/ContainerTest.php | 59 + .../AbstractDoctrineExtensionTest.php | 854 +++++ .../AnnotationsBundle/AnnotationsBundle.php | 21 + .../Bundles/AnnotationsBundle/Entity/Test.php | 19 + .../AnnotationsBundle/AnnotationsBundle.php | 21 + .../Vendor/AnnotationsBundle/Entity/Test.php | 19 + .../Bundles/XmlBundle/Entity/Test.php | 19 + .../Resources/config/doctrine/Test.orm.xml | 0 .../Fixtures/Bundles/XmlBundle/XmlBundle.php | 21 + .../Bundles/YamlBundle/Entity/Test.php | 20 + .../Resources/config/doctrine/Test.orm.yml | 5 + .../Bundles/YamlBundle/YamlBundle.php | 21 + .../Fixtures/config/xml/dbal_logging.xml | 29 + .../xml/dbal_service_multiple_connections.xml | 33 + .../xml/dbal_service_single_connection.xml | 12 + ...service_single_master_slave_connection.xml | 14 + .../Fixtures/config/xml/dbal_types.xml | 15 + .../Fixtures/config/xml/orm_filters.xml | 18 + .../Fixtures/config/xml/orm_functions.xml | 25 + .../config/xml/orm_hydration_mode.xml | 21 + .../Fixtures/config/xml/orm_imports.xml | 16 + .../config/xml/orm_imports_import.xml | 23 + .../xml/orm_multiple_em_bundle_mappings.xml | 27 + .../Fixtures/config/xml/orm_proxy.xml | 12 + .../config/xml/orm_resolve_target_entity.xml | 18 + .../orm_service_multiple_entity_managers.xml | 40 + ...m_service_simple_single_entity_manager.xml | 26 + .../xml/orm_service_single_entity_manager.xml | 39 + .../xml/orm_single_em_bundle_mappings.xml | 23 + .../xml/orm_single_em_dql_functions.xml | 20 + .../Fixtures/config/yml/dbal_logging.yml | 13 + .../yml/dbal_service_multiple_connections.yml | 18 + .../yml/dbal_service_single_connection.yml | 6 + ...service_single_master_slave_connection.yml | 12 + .../Fixtures/config/yml/dbal_types.yml | 7 + .../Fixtures/config/yml/orm_filters.yml | 12 + .../Fixtures/config/yml/orm_functions.yml | 19 + .../config/yml/orm_hydration_mode.yml | 14 + .../Fixtures/config/yml/orm_imports.yml | 6 + .../config/yml/orm_imports_import.yml | 15 + .../yml/orm_multiple_em_bundle_mappings.yml | 23 + .../config/yml/orm_resolve_target_entity.yml | 10 + .../orm_service_multiple_entity_managers.yml | 34 + ...m_service_simple_single_entity_manager.yml | 19 + .../yml/orm_service_single_entity_manager.yml | 27 + .../yml/orm_single_em_bundle_mappings.yml | 18 + .../yml/orm_single_em_dql_functions.yml | 11 + .../TestDatetimeFunction.php | 32 + .../Tests/DependencyInjection/TestFilter.php | 30 + .../TestNumericFunction.php | 32 + .../TestStringFunction.php | 32 + .../Tests/DependencyInjection/TestType.php | 30 + .../DependencyInjection/XMLSchemaTest.php | 66 + .../XmlDoctrineExtensionTest.php | 28 + .../YamlDoctrineExtensionTest.php | 28 + .../Tests/Mapping/MetadataFactoryTest.php | 41 + .../DoctrineBundle/Tests/RegistryTest.php | 149 + .../Bundle/DoctrineBundle/Tests/TestCase.php | 83 + .../Bundle/DoctrineBundle/Tests/bootstrap.php | 8 + .../Bundle/DoctrineBundle/composer.json | 45 + .../Bundle/DoctrineBundle/phpunit.xml.dist | 35 + vendor/doctrine/orm/.travis.yml | 19 + vendor/doctrine/orm/LICENSE | 504 +++ vendor/doctrine/orm/README.markdown | 18 + vendor/doctrine/orm/composer.json | 23 + vendor/doctrine/orm/doctrine-mapping.xsd | 409 +++ .../orm/lib/Doctrine/ORM/AbstractQuery.php | 820 +++++ .../orm/lib/Doctrine/ORM/Configuration.php | 573 +++ .../orm/lib/Doctrine/ORM/EntityManager.php | 834 +++++ .../Doctrine/ORM/EntityNotFoundException.php | 34 + .../orm/lib/Doctrine/ORM/EntityRepository.php | 265 ++ .../Doctrine/ORM/Event/LifecycleEventArgs.php | 77 + .../ORM/Event/LoadClassMetadataEventArgs.php | 76 + .../Doctrine/ORM/Event/OnClearEventArgs.php | 84 + .../Doctrine/ORM/Event/OnFlushEventArgs.php | 86 + .../Doctrine/ORM/Event/PostFlushEventArgs.php | 61 + .../Doctrine/ORM/Event/PreFlushEventArgs.php | 53 + .../Doctrine/ORM/Event/PreUpdateEventArgs.php | 131 + .../doctrine/orm/lib/Doctrine/ORM/Events.php | 148 + .../Doctrine/ORM/Id/AbstractIdGenerator.php | 48 + .../lib/Doctrine/ORM/Id/AssignedGenerator.php | 71 + .../lib/Doctrine/ORM/Id/IdentityGenerator.php | 59 + .../lib/Doctrine/ORM/Id/SequenceGenerator.php | 106 + .../lib/Doctrine/ORM/Id/TableGenerator.php | 81 + .../ORM/Internal/CommitOrderCalculator.php | 118 + .../Internal/Hydration/AbstractHydrator.php | 389 +++ .../ORM/Internal/Hydration/ArrayHydrator.php | 289 ++ .../Internal/Hydration/HydrationException.php | 26 + .../ORM/Internal/Hydration/IterableResult.php | 104 + .../ORM/Internal/Hydration/ObjectHydrator.php | 536 +++ .../ORM/Internal/Hydration/ScalarHydrator.php | 57 + .../Hydration/SimpleObjectHydrator.php | 183 + .../Hydration/SingleScalarHydrator.php | 56 + .../lib/Doctrine/ORM/Mapping/Annotation.php | 24 + .../Mapping/Builder/AssociationBuilder.php | 167 + .../Mapping/Builder/ClassMetadataBuilder.php | 470 +++ .../ORM/Mapping/Builder/FieldBuilder.php | 223 ++ .../Builder/ManyToManyAssociationBuilder.php | 86 + .../Builder/OneToManyAssociationBuilder.php | 62 + .../ORM/Mapping/ChangeTrackingPolicy.php | 30 + .../Doctrine/ORM/Mapping/ClassMetadata.php | 44 + .../ORM/Mapping/ClassMetadataFactory.php | 593 ++++ .../ORM/Mapping/ClassMetadataInfo.php | 2340 +++++++++++++ .../orm/lib/Doctrine/ORM/Mapping/Column.php | 46 + .../ORM/Mapping/DiscriminatorColumn.php | 36 + .../Doctrine/ORM/Mapping/DiscriminatorMap.php | 30 + .../ORM/Mapping/Driver/AbstractFileDriver.php | 213 ++ .../ORM/Mapping/Driver/AnnotationDriver.php | 592 ++++ .../ORM/Mapping/Driver/DatabaseDriver.php | 417 +++ .../Mapping/Driver/DoctrineAnnotations.php | 54 + .../Doctrine/ORM/Mapping/Driver/Driver.php | 59 + .../ORM/Mapping/Driver/DriverChain.php | 126 + .../Doctrine/ORM/Mapping/Driver/PHPDriver.php | 69 + .../Mapping/Driver/SimplifiedXmlDriver.php | 176 + .../Mapping/Driver/SimplifiedYamlDriver.php | 181 + .../ORM/Mapping/Driver/StaticPHPDriver.php | 138 + .../Doctrine/ORM/Mapping/Driver/XmlDriver.php | 536 +++ .../ORM/Mapping/Driver/YamlDriver.php | 512 +++ .../ORM/Mapping/ElementCollection.php | 31 + .../orm/lib/Doctrine/ORM/Mapping/Entity.php | 32 + .../Doctrine/ORM/Mapping/GeneratedValue.php | 30 + .../ORM/Mapping/HasLifecycleCallbacks.php | 28 + .../orm/lib/Doctrine/ORM/Mapping/Id.php | 28 + .../orm/lib/Doctrine/ORM/Mapping/Index.php | 32 + .../Doctrine/ORM/Mapping/InheritanceType.php | 30 + .../lib/Doctrine/ORM/Mapping/JoinColumn.php | 42 + .../lib/Doctrine/ORM/Mapping/JoinColumns.php | 30 + .../lib/Doctrine/ORM/Mapping/JoinTable.php | 36 + .../lib/Doctrine/ORM/Mapping/ManyToMany.php | 42 + .../lib/Doctrine/ORM/Mapping/ManyToOne.php | 36 + .../Doctrine/ORM/Mapping/MappedSuperclass.php | 30 + .../Doctrine/ORM/Mapping/MappingException.php | 332 ++ .../lib/Doctrine/ORM/Mapping/NamedQueries.php | 30 + .../lib/Doctrine/ORM/Mapping/NamedQuery.php | 32 + .../lib/Doctrine/ORM/Mapping/OneToMany.php | 40 + .../orm/lib/Doctrine/ORM/Mapping/OneToOne.php | 40 + .../orm/lib/Doctrine/ORM/Mapping/OrderBy.php | 30 + .../orm/lib/Doctrine/ORM/Mapping/PostLoad.php | 28 + .../lib/Doctrine/ORM/Mapping/PostPersist.php | 28 + .../lib/Doctrine/ORM/Mapping/PostRemove.php | 28 + .../lib/Doctrine/ORM/Mapping/PostUpdate.php | 28 + .../orm/lib/Doctrine/ORM/Mapping/PreFlush.php | 28 + .../lib/Doctrine/ORM/Mapping/PrePersist.php | 28 + .../lib/Doctrine/ORM/Mapping/PreRemove.php | 28 + .../lib/Doctrine/ORM/Mapping/PreUpdate.php | 28 + .../ORM/Mapping/SequenceGenerator.php | 34 + .../orm/lib/Doctrine/ORM/Mapping/Table.php | 36 + .../Doctrine/ORM/Mapping/UniqueConstraint.php | 32 + .../orm/lib/Doctrine/ORM/Mapping/Version.php | 28 + .../orm/lib/Doctrine/ORM/NativeQuery.php | 76 + .../lib/Doctrine/ORM/NoResultException.php | 34 + .../Doctrine/ORM/NonUniqueResultException.php | 28 + .../orm/lib/Doctrine/ORM/ORMException.php | 152 + .../ORM/ORMInvalidArgumentException.php | 107 + .../Doctrine/ORM/OptimisticLockException.php | 64 + .../lib/Doctrine/ORM/PersistentCollection.php | 792 +++++ .../AbstractCollectionPersister.php | 207 ++ .../AbstractEntityInheritancePersister.php | 83 + .../ORM/Persisters/BasicEntityPersister.php | 1605 +++++++++ .../Persisters/ElementCollectionPersister.php | 33 + .../Persisters/JoinedSubclassPersister.php | 487 +++ .../ORM/Persisters/ManyToManyPersister.php | 425 +++ .../ORM/Persisters/OneToManyPersister.php | 212 ++ .../ORM/Persisters/SingleTablePersister.php | 146 + .../ORM/Persisters/UnionSubclassPersister.php | 8 + .../Doctrine/ORM/PessimisticLockException.php | 40 + .../orm/lib/Doctrine/ORM/Proxy/Autoloader.php | 78 + .../orm/lib/Doctrine/ORM/Proxy/Proxy.php | 30 + .../lib/Doctrine/ORM/Proxy/ProxyException.php | 51 + .../lib/Doctrine/ORM/Proxy/ProxyFactory.php | 403 +++ .../doctrine/orm/lib/Doctrine/ORM/Query.php | 614 ++++ .../Doctrine/ORM/Query/AST/ASTException.php | 13 + .../ORM/Query/AST/AggregateExpression.php | 52 + .../ORM/Query/AST/ArithmeticExpression.php | 54 + .../ORM/Query/AST/ArithmeticFactor.php | 67 + .../Doctrine/ORM/Query/AST/ArithmeticTerm.php | 48 + .../ORM/Query/AST/BetweenExpression.php | 54 + .../ORM/Query/AST/CoalesceExpression.php | 47 + .../Query/AST/CollectionMemberExpression.php | 52 + .../ORM/Query/AST/ComparisonExpression.php | 57 + .../ORM/Query/AST/ConditionalExpression.php | 48 + .../ORM/Query/AST/ConditionalFactor.php | 49 + .../ORM/Query/AST/ConditionalPrimary.php | 54 + .../ORM/Query/AST/ConditionalTerm.php | 48 + .../Doctrine/ORM/Query/AST/DeleteClause.php | 50 + .../ORM/Query/AST/DeleteStatement.php | 49 + .../EmptyCollectionComparisonExpression.php | 50 + .../ORM/Query/AST/ExistsExpression.php | 50 + .../lib/Doctrine/ORM/Query/AST/FromClause.php | 45 + .../ORM/Query/AST/Functions/AbsFunction.php | 62 + .../Query/AST/Functions/BitAndFunction.php | 63 + .../ORM/Query/AST/Functions/BitOrFunction.php | 63 + .../Query/AST/Functions/ConcatFunction.php | 67 + .../AST/Functions/CurrentDateFunction.php | 54 + .../AST/Functions/CurrentTimeFunction.php | 54 + .../Functions/CurrentTimestampFunction.php | 54 + .../Query/AST/Functions/DateAddFunction.php | 71 + .../Query/AST/Functions/DateDiffFunction.php | 58 + .../Query/AST/Functions/DateSubFunction.php | 58 + .../ORM/Query/AST/Functions/FunctionNode.php | 52 + .../Query/AST/Functions/IdentityFunction.php | 68 + .../Query/AST/Functions/LengthFunction.php | 62 + .../Query/AST/Functions/LocateFunction.php | 81 + .../ORM/Query/AST/Functions/LowerFunction.php | 62 + .../ORM/Query/AST/Functions/ModFunction.php | 68 + .../ORM/Query/AST/Functions/SizeFunction.php | 122 + .../ORM/Query/AST/Functions/SqrtFunction.php | 61 + .../Query/AST/Functions/SubstringFunction.php | 82 + .../ORM/Query/AST/Functions/TrimFunction.php | 100 + .../ORM/Query/AST/Functions/UpperFunction.php | 62 + .../ORM/Query/AST/GeneralCaseExpression.php | 48 + .../Doctrine/ORM/Query/AST/GroupByClause.php | 48 + .../Doctrine/ORM/Query/AST/HavingClause.php | 48 + .../AST/IdentificationVariableDeclaration.php | 52 + .../Doctrine/ORM/Query/AST/InExpression.php | 52 + .../lib/Doctrine/ORM/Query/AST/IndexBy.php | 48 + .../Doctrine/ORM/Query/AST/InputParameter.php | 58 + .../ORM/Query/AST/InstanceOfExpression.php | 50 + .../orm/lib/Doctrine/ORM/Query/AST/Join.php | 58 + .../AST/JoinAssociationPathExpression.php | 50 + .../ORM/Query/AST/JoinVariableDeclaration.php | 50 + .../Doctrine/ORM/Query/AST/LikeExpression.php | 53 + .../lib/Doctrine/ORM/Query/AST/Literal.php | 24 + .../orm/lib/Doctrine/ORM/Query/AST/Node.php | 98 + .../Query/AST/NullComparisonExpression.php | 50 + .../ORM/Query/AST/NullIfExpression.php | 49 + .../Doctrine/ORM/Query/AST/OrderByClause.php | 48 + .../Doctrine/ORM/Query/AST/OrderByItem.php | 59 + .../ORM/Query/AST/PartialObjectExpression.php | 15 + .../Doctrine/ORM/Query/AST/PathExpression.php | 58 + .../ORM/Query/AST/QuantifiedExpression.php | 68 + .../Query/AST/RangeVariableDeclaration.php | 50 + .../Doctrine/ORM/Query/AST/SelectClause.php | 50 + .../ORM/Query/AST/SelectExpression.php | 53 + .../ORM/Query/AST/SelectStatement.php | 53 + .../Query/AST/SimpleArithmeticExpression.php | 48 + .../ORM/Query/AST/SimpleCaseExpression.php | 50 + .../ORM/Query/AST/SimpleSelectClause.php | 50 + .../ORM/Query/AST/SimpleSelectExpression.php | 50 + .../ORM/Query/AST/SimpleWhenClause.php | 48 + .../lib/Doctrine/ORM/Query/AST/Subselect.php | 54 + .../ORM/Query/AST/SubselectFromClause.php | 48 + .../Doctrine/ORM/Query/AST/UpdateClause.php | 52 + .../lib/Doctrine/ORM/Query/AST/UpdateItem.php | 53 + .../ORM/Query/AST/UpdateStatement.php | 49 + .../lib/Doctrine/ORM/Query/AST/WhenClause.php | 48 + .../Doctrine/ORM/Query/AST/WhereClause.php | 48 + .../ORM/Query/Exec/AbstractSqlExecutor.php | 70 + .../Query/Exec/MultiTableDeleteExecutor.php | 124 + .../Query/Exec/MultiTableUpdateExecutor.php | 178 + .../ORM/Query/Exec/SingleSelectExecutor.php | 48 + .../Exec/SingleTableDeleteUpdateExecutor.php | 53 + .../orm/lib/Doctrine/ORM/Query/Expr.php | 595 ++++ .../orm/lib/Doctrine/ORM/Query/Expr/Andx.php | 44 + .../orm/lib/Doctrine/ORM/Query/Expr/Base.php | 89 + .../Doctrine/ORM/Query/Expr/Comparison.php | 59 + .../lib/Doctrine/ORM/Query/Expr/Composite.php | 68 + .../orm/lib/Doctrine/ORM/Query/Expr/From.php | 88 + .../orm/lib/Doctrine/ORM/Query/Expr/Func.php | 50 + .../lib/Doctrine/ORM/Query/Expr/GroupBy.php | 39 + .../orm/lib/Doctrine/ORM/Query/Expr/Join.php | 67 + .../lib/Doctrine/ORM/Query/Expr/Literal.php | 9 + .../orm/lib/Doctrine/ORM/Query/Expr/Math.php | 66 + .../lib/Doctrine/ORM/Query/Expr/OrderBy.php | 66 + .../orm/lib/Doctrine/ORM/Query/Expr/Orx.php | 44 + .../lib/Doctrine/ORM/Query/Expr/Select.php | 42 + .../Doctrine/ORM/Query/Filter/SQLFilter.php | 122 + .../Doctrine/ORM/Query/FilterCollection.php | 198 ++ .../orm/lib/Doctrine/ORM/Query/Lexer.php | 208 ++ .../ORM/Query/ParameterTypeInferer.php | 72 + .../orm/lib/Doctrine/ORM/Query/Parser.php | 3093 +++++++++++++++++ .../lib/Doctrine/ORM/Query/ParserResult.php | 141 + .../orm/lib/Doctrine/ORM/Query/Printer.php | 95 + .../lib/Doctrine/ORM/Query/QueryException.php | 154 + .../Doctrine/ORM/Query/ResultSetMapping.php | 485 +++ .../ORM/Query/ResultSetMappingBuilder.php | 109 + .../orm/lib/Doctrine/ORM/Query/SqlWalker.php | 2159 ++++++++++++ .../orm/lib/Doctrine/ORM/Query/TreeWalker.php | 411 +++ .../Doctrine/ORM/Query/TreeWalkerAdapter.php | 445 +++ .../Doctrine/ORM/Query/TreeWalkerChain.php | 664 ++++ .../orm/lib/Doctrine/ORM/QueryBuilder.php | 1115 ++++++ .../orm/lib/Doctrine/ORM/README.markdown | 0 .../Command/ClearCache/MetadataCommand.php | 104 + .../Command/ClearCache/QueryCommand.php | 104 + .../Command/ClearCache/ResultCommand.php | 104 + .../Command/ConvertDoctrine1SchemaCommand.php | 223 ++ .../Console/Command/ConvertMappingCommand.php | 186 + .../EnsureProductionSettingsCommand.php | 85 + .../Command/GenerateEntitiesCommand.php | 163 + .../Command/GenerateProxiesCommand.php | 115 + .../Command/GenerateRepositoriesCommand.php | 116 + .../ORM/Tools/Console/Command/InfoCommand.php | 80 + .../Tools/Console/Command/RunDqlCommand.php | 124 + .../Command/SchemaTool/AbstractCommand.php | 64 + .../Command/SchemaTool/CreateCommand.php | 79 + .../Command/SchemaTool/DropCommand.php | 111 + .../Command/SchemaTool/UpdateCommand.php | 135 + .../Console/Command/ValidateSchemaCommand.php | 89 + .../ORM/Tools/Console/ConsoleRunner.php | 70 + .../Console/Helper/EntityManagerHelper.php | 74 + .../ORM/Tools/Console/MetadataFilter.php | 80 + .../ORM/Tools/ConvertDoctrine1Schema.php | 274 ++ .../ORM/Tools/DebugUnitOfWorkListener.php | 151 + .../DisconnectedClassMetadataFactory.php | 45 + .../Doctrine/ORM/Tools/EntityGenerator.php | 1129 ++++++ .../ORM/Tools/EntityRepositoryGenerator.php | 83 + .../Tools/Event/GenerateSchemaEventArgs.php | 65 + .../Event/GenerateSchemaTableEventArgs.php | 75 + .../Tools/Export/ClassMetadataExporter.php | 76 + .../Tools/Export/Driver/AbstractExporter.php | 217 ++ .../Export/Driver/AnnotationExporter.php | 72 + .../ORM/Tools/Export/Driver/PhpExporter.php | 169 + .../ORM/Tools/Export/Driver/XmlExporter.php | 320 ++ .../ORM/Tools/Export/Driver/YamlExporter.php | 210 ++ .../ORM/Tools/Export/ExportException.php | 23 + .../ORM/Tools/Pagination/CountWalker.php | 80 + .../Tools/Pagination/LimitSubqueryWalker.php | 115 + .../ORM/Tools/Pagination/Paginator.php | 180 + .../ORM/Tools/Pagination/WhereInWalker.php | 142 + .../ORM/Tools/ResolveTargetEntityListener.php | 94 + .../orm/lib/Doctrine/ORM/Tools/SchemaTool.php | 701 ++++ .../Doctrine/ORM/Tools/SchemaValidator.php | 267 ++ .../orm/lib/Doctrine/ORM/Tools/Setup.php | 194 ++ .../orm/lib/Doctrine/ORM/Tools/ToolEvents.php | 44 + .../lib/Doctrine/ORM/Tools/ToolsException.php | 40 + .../ORM/TransactionRequiredException.php | 40 + .../orm/lib/Doctrine/ORM/UnitOfWork.php | 2949 ++++++++++++++++ .../doctrine/orm/lib/Doctrine/ORM/Version.php | 55 + vendor/doctrine/orm/phpunit.xml.dist | 59 + vendor/doctrine/orm/run-all.sh | 21 + .../JMS/AopBundle/Aop/InterceptorLoader.php | 58 + .../JMS/AopBundle/Aop/PointcutContainer.php | 34 + .../JMS/AopBundle/Aop/PointcutInterface.php | 54 + .../JMS/AopBundle/Aop/RegexPointcut.php | 46 + .../Compiler/PointcutMatchingPass.php | 195 ++ .../DependencyInjection/Configuration.php | 45 + .../DependencyInjection/JMSAopExtension.php | 53 + .../JMS/AopBundle/Exception/Exception.php | 28 + .../AopBundle/Exception/RuntimeException.php | 28 + .../aop-bundle/JMS/AopBundle/JMSAopBundle.php | 34 + vendor/jms/aop-bundle/JMS/AopBundle/README | 8 + .../AopBundle/Resources/config/services.xml | 18 + .../JMS/AopBundle/Resources/doc/index.rst | 252 ++ .../JMS/AopBundle/Resources/meta/LICENSE | 201 ++ .../aop-bundle/JMS/AopBundle/composer.json | 21 + vendor/jms/cg/LICENSE | 201 ++ vendor/jms/cg/composer.json | 19 + .../cg/src/CG/Core/AbstractClassGenerator.php | 60 + .../src/CG/Core/ClassGeneratorInterface.php | 36 + vendor/jms/cg/src/CG/Core/ClassUtils.php | 35 + .../src/CG/Core/DefaultGeneratorStrategy.php | 67 + .../cg/src/CG/Core/DefaultNamingStrategy.php | 41 + .../CG/Core/GeneratorStrategyInterface.php | 34 + .../src/CG/Core/NamingStrategyInterface.php | 50 + vendor/jms/cg/src/CG/Core/ReflectionUtils.php | 57 + .../cg/src/CG/Generator/AbstractPhpMember.php | 95 + .../cg/src/CG/Generator/DefaultNavigator.php | 172 + .../cg/src/CG/Generator/DefaultVisitor.php | 237 ++ .../CG/Generator/DefaultVisitorInterface.php | 47 + .../cg/src/CG/Generator/GeneratorUtils.php | 38 + vendor/jms/cg/src/CG/Generator/PhpClass.php | 360 ++ .../jms/cg/src/CG/Generator/PhpFunction.php | 146 + vendor/jms/cg/src/CG/Generator/PhpMethod.php | 158 + .../jms/cg/src/CG/Generator/PhpParameter.php | 126 + .../jms/cg/src/CG/Generator/PhpProperty.php | 84 + vendor/jms/cg/src/CG/Generator/Writer.php | 103 + vendor/jms/cg/src/CG/Proxy/Enhancer.php | 158 + .../cg/src/CG/Proxy/GeneratorInterface.php | 38 + .../cg/src/CG/Proxy/InterceptionGenerator.php | 117 + .../CG/Proxy/InterceptorLoaderInterface.php | 38 + .../src/CG/Proxy/LazyInitializerGenerator.php | 153 + .../src/CG/Proxy/LazyInitializerInterface.php | 38 + .../CG/Proxy/MethodInterceptorInterface.php | 42 + .../jms/cg/src/CG/Proxy/MethodInvocation.php | 77 + .../src/CG/Proxy/RegexInterceptionLoader.php | 48 + vendor/jms/cg/src/CG/Version.php | 8 + .../DiExtraBundle/Annotation/AfterSetup.php | 13 + .../Annotation/DoctrineListener.php | 74 + .../JMS/DiExtraBundle/Annotation/FormType.php | 37 + .../JMS/DiExtraBundle/Annotation/Inject.php | 27 + .../DiExtraBundle/Annotation/InjectParams.php | 57 + .../DiExtraBundle/Annotation/LookupMethod.php | 27 + .../JMS/DiExtraBundle/Annotation/Observe.php | 62 + .../DiExtraBundle/Annotation/Reference.php | 54 + .../JMS/DiExtraBundle/Annotation/Service.php | 87 + .../JMS/DiExtraBundle/Annotation/Tag.php | 60 + .../DiExtraBundle/Annotation/Validator.php | 51 + .../Config/FastDirectoriesResource.php | 78 + .../Config/ServiceFilesResource.php | 52 + .../Compiler/AnnotationConfigurationPass.php | 120 + .../Compiler/IntegrationPass.php | 55 + .../Compiler/ResourceOptimizationPass.php | 81 + .../DependencyInjection/Configuration.php | 69 + .../JMSDiExtraExtension.php | 84 + .../LookupMethodClassInterface.php | 24 + .../EventListener/ControllerListener.php | 58 + .../EventListener/TemplateListener.php | 50 + .../JMS/DiExtraBundle/Exception/Exception.php | 28 + .../Exception/InvalidArgumentException.php | 28 + .../Exception/InvalidTypeException.php | 29 + .../Exception/RuntimeException.php | 28 + .../DiExtraBundle/Finder/PatternFinder.php | 201 ++ .../Generator/DefinitionInjectorGenerator.php | 192 + .../Generator/LookupMethodClassGenerator.php | 119 + .../DiExtraBundle/Generator/NameGenerator.php | 79 + .../HttpKernel/ControllerResolver.php | 179 + .../JMS/DiExtraBundle/JMSDiExtraBundle.php | 50 + .../DiExtraBundle/Metadata/ClassMetadata.php | 74 + .../Metadata/Driver/AnnotationDriver.php | 220 ++ .../Metadata/MetadataConverter.php | 85 + .../di-extra-bundle/JMS/DiExtraBundle/README | 8 + .../Resources/config/services.xml | 50 + .../JMS/DiExtraBundle/Resources/doc/index.rst | 290 ++ .../JMS/DiExtraBundle/Resources/meta/LICENSE | 201 ++ .../JMS/DiExtraBundle/composer.json | 21 + vendor/jms/metadata/CHANGELOG.md | 18 + vendor/jms/metadata/LICENSE | 201 ++ vendor/jms/metadata/composer.json | 19 + .../src/Metadata/Cache/CacheInterface.php | 35 + .../metadata/src/Metadata/Cache/FileCache.php | 46 + .../src/Metadata/ClassHierarchyMetadata.php | 55 + .../metadata/src/Metadata/ClassMetadata.php | 98 + .../Metadata/Driver/AbstractFileDriver.php | 42 + .../src/Metadata/Driver/DriverChain.php | 40 + .../src/Metadata/Driver/DriverInterface.php | 24 + .../src/Metadata/Driver/FileLocator.php | 29 + .../Metadata/Driver/FileLocatorInterface.php | 8 + .../src/Metadata/Driver/LazyLoadingDriver.php | 22 + .../src/Metadata/MergeableClassMetadata.php | 23 + .../src/Metadata/MergeableInterface.php | 8 + .../metadata/src/Metadata/MetadataFactory.php | 142 + .../src/Metadata/MetadataFactoryInterface.php | 24 + .../metadata/src/Metadata/MethodMetadata.php | 61 + .../src/Metadata/PropertyMetadata.php | 69 + vendor/jms/metadata/src/Metadata/Version.php | 24 + .../Annotation/PreAuthorize.php | 59 + .../SecurityExtraBundle/Annotation/RunAs.php | 42 + .../SatisfiesParentSecurityPolicy.php | 81 + .../SecurityExtraBundle/Annotation/Secure.php | 45 + .../Annotation/SecureParam.php | 48 + .../Annotation/SecureReturn.php | 45 + .../JMS/SecurityExtraBundle/CHANGELOG-1.1.md | 38 + .../AccessControlConfiguration.php | 90 + .../AddAfterInvocationProvidersPass.php | 52 + .../Compiler/AddExpressionCompilersPass.php | 66 + .../Compiler/CollectSecuredServicesPass.php | 43 + .../Compiler/DisableVotersPass.php | 46 + .../Compiler/IntegrationPass.php | 22 + .../DependencyInjection/Configuration.php | 64 + .../JMSSecurityExtraExtension.php | 100 + .../DependencyInjection/SecurityExtension.php | 130 + .../Exception/Exception.php | 28 + .../Exception/InvalidArgumentException.php | 28 + .../Exception/RuntimeException.php | 28 + .../JMSSecurityExtraBundle.php | 59 + .../Metadata/ClassMetadata.php | 93 + .../Metadata/Driver/AnnotationDriver.php | 107 + .../Metadata/Driver/ConfigDriver.php | 100 + .../Metadata/MethodMetadata.php | 84 + .../JMS/SecurityExtraBundle/README | 8 + .../Resources/config/security_expressions.xml | 84 + .../Resources/config/services.xml | 99 + .../Resources/doc/index.rst | 352 ++ .../Resources/meta/LICENSE | 201 ++ .../HasPermissionFunctionCompiler.php | 63 + .../Acl/Expression/PermissionEvaluator.php | 122 + .../Security/Acl/Voter/AclVoter.php | 136 + .../Provider/RunAsAuthenticationProvider.php | 57 + .../Authentication/Token/RunAsUserToken.php | 85 + .../AclAfterInvocationProvider.php | 111 + .../AfterInvocationManager.php | 77 + .../AfterInvocationManagerInterface.php | 56 + .../AfterInvocationProviderInterface.php | 33 + .../Expression/Ast/AndExpression.php | 31 + .../Expression/Ast/ArrayExpression.php | 29 + .../Expression/Ast/ConstantExpression.php | 29 + .../Expression/Ast/ExpressionInterface.php | 23 + .../Expression/Ast/FunctionExpression.php | 32 + .../Expression/Ast/GetItemExpression.php | 31 + .../Expression/Ast/GetPropertyExpression.php | 31 + .../Expression/Ast/IsEqualExpression.php | 31 + .../Expression/Ast/MethodCallExpression.php | 33 + .../Expression/Ast/NotExpression.php | 29 + .../Expression/Ast/OrExpression.php | 31 + .../Expression/Ast/ParameterExpression.php | 29 + .../Expression/Ast/VariableExpression.php | 31 + .../Compiler/AndExpressionCompiler.php | 32 + .../Compiler/BinaryExprCompiler.php | 51 + .../ContainerAwareVariableCompiler.php | 60 + .../AuthenticationTrustFunctionCompiler.php | 35 + .../Func/FunctionCompilerInterface.php | 29 + .../Func/HasAnyRoleFunctionCompiler.php | 63 + .../Compiler/Func/HasRoleFunctionCompiler.php | 51 + .../Func/IsAnonymousFunctionCompiler.php | 39 + .../Func/IsAuthenticatedFunctionCompiler.php | 41 + .../IsFullyAuthenticatedFunctionCompiler.php | 39 + .../Func/IsRememberMeFunctionCompiler.php | 39 + .../Compiler/IsEqualExpressionCompiler.php | 32 + .../Compiler/NotExpressionCompiler.php | 44 + .../Compiler/OrExpressionCompiler.php | 32 + .../Compiler/ParameterExpressionCompiler.php | 80 + .../Compiler/TypeCompilerInterface.php | 29 + .../Compiler/VariableExpressionCompiler.php | 74 + .../ContainerAwareExpressionHandler.php | 47 + .../Expression/DefaultExpressionHandler.php | 51 + .../Authorization/Expression/Expression.php | 40 + .../Expression/ExpressionCompiler.php | 395 +++ .../Expression/ExpressionHandlerInterface.php | 26 + .../Expression/ExpressionLexer.php | 134 + .../Expression/ExpressionParser.php | 290 ++ .../Expression/ExpressionVoter.php | 114 + .../Expression/LazyLoadingExpressionVoter.php | 39 + .../MethodSecurityInterceptor.php | 150 + .../Interception/SecurityPointcut.php | 92 + .../Security/Authorization/RunAsManager.php | 79 + .../Authorization/RunAsManagerInterface.php | 57 + .../Authorization/Voter/IddqdVoter.php | 61 + .../Twig/SecurityExtension.php | 35 + .../JMS/SecurityExtraBundle/composer.json | 25 + vendor/kriswallsmith/assetic/.travis.yml | 16 + vendor/kriswallsmith/assetic/CHANGELOG-1.0.md | 29 + vendor/kriswallsmith/assetic/CHANGELOG-1.1.md | 9 + vendor/kriswallsmith/assetic/LICENSE | 19 + vendor/kriswallsmith/assetic/README.md | 284 ++ vendor/kriswallsmith/assetic/composer.json | 35 + vendor/kriswallsmith/assetic/docs/en/build.md | 32 + .../kriswallsmith/assetic/docs/en/concepts.md | 129 + .../kriswallsmith/assetic/docs/en/define.md | 145 + vendor/kriswallsmith/assetic/docs/en/index.md | 7 + .../assetic/docs/en/introduction.md | 21 + vendor/kriswallsmith/assetic/docs/ja/build.md | 30 + .../kriswallsmith/assetic/docs/ja/concepts.md | 121 + .../kriswallsmith/assetic/docs/ja/define.md | 140 + vendor/kriswallsmith/assetic/docs/ja/index.md | 7 + .../assetic/docs/ja/introduction.md | 18 + .../kriswallsmith/assetic/phpunit.travis.xml | 39 + vendor/kriswallsmith/assetic/phpunit.xml.dist | 42 + .../assetic/src/Assetic/Asset/AssetCache.php | 168 + .../src/Assetic/Asset/AssetCollection.php | 217 ++ .../Asset/AssetCollectionInterface.php | 53 + .../src/Assetic/Asset/AssetInterface.php | 156 + .../src/Assetic/Asset/AssetReference.php | 134 + .../assetic/src/Assetic/Asset/BaseAsset.php | 169 + .../assetic/src/Assetic/Asset/FileAsset.php | 78 + .../assetic/src/Assetic/Asset/GlobAsset.php | 111 + .../assetic/src/Assetic/Asset/HttpAsset.php | 79 + .../AssetCollectionFilterIterator.php | 84 + .../Iterator/AssetCollectionIterator.php | 109 + .../assetic/src/Assetic/Asset/StringAsset.php | 55 + .../assetic/src/Assetic/AssetManager.php | 79 + .../assetic/src/Assetic/AssetWriter.php | 107 + .../assetic/src/Assetic/Cache/ApcCache.php | 66 + .../src/Assetic/Cache/CacheInterface.php | 53 + .../assetic/src/Assetic/Cache/ConfigCache.php | 123 + .../src/Assetic/Cache/ExpiringCache.php | 60 + .../src/Assetic/Cache/FilesystemCache.php | 65 + .../src/Assetic/Exception/Exception.php | 21 + .../src/Assetic/Exception/FilterException.php | 73 + .../Extension/Twig/AsseticExtension.php | 76 + .../Extension/Twig/AsseticFilterFunction.php | 29 + .../Extension/Twig/AsseticFilterInvoker.php | 61 + .../Assetic/Extension/Twig/AsseticNode.php | 166 + .../Extension/Twig/AsseticTokenParser.php | 150 + .../Extension/Twig/TwigFormulaLoader.php | 97 + .../Assetic/Extension/Twig/TwigResource.php | 54 + .../src/Assetic/Factory/AssetFactory.php | 386 ++ .../src/Assetic/Factory/LazyAssetManager.php | 204 ++ .../Factory/Loader/BasePhpFormulaLoader.php | 159 + .../Factory/Loader/CachedFormulaLoader.php | 68 + .../Factory/Loader/FormulaLoaderInterface.php | 34 + .../Loader/FunctionCallsFormulaLoader.php | 53 + .../Resource/CoalescingDirectoryResource.php | 112 + .../Factory/Resource/DirectoryResource.php | 133 + .../Assetic/Factory/Resource/FileResource.php | 47 + .../Resource/IteratorResourceInterface.php | 21 + .../Factory/Resource/ResourceInterface.php | 43 + .../Factory/Worker/EnsureFilterWorker.php | 60 + .../Factory/Worker/WorkerInterface.php | 31 + .../src/Assetic/Filter/BaseCssFilter.php | 71 + .../src/Assetic/Filter/CallablesFilter.php | 45 + .../src/Assetic/Filter/CoffeeScriptFilter.php | 73 + .../src/Assetic/Filter/CompassFilter.php | 346 ++ .../src/Assetic/Filter/CssEmbedFilter.php | 139 + .../src/Assetic/Filter/CssImportFilter.php | 107 + .../src/Assetic/Filter/CssMinFilter.php | 74 + .../src/Assetic/Filter/CssRewriteFilter.php | 94 + .../src/Assetic/Filter/FilterCollection.php | 82 + .../src/Assetic/Filter/FilterInterface.php | 36 + .../GoogleClosure/BaseCompilerFilter.php | 84 + .../GoogleClosure/CompilerApiFilter.php | 100 + .../GoogleClosure/CompilerJarFilter.php | 90 + .../assetic/src/Assetic/Filter/GssFilter.php | 142 + .../src/Assetic/Filter/HashableInterface.php | 29 + .../src/Assetic/Filter/JSMinFilter.php | 34 + .../src/Assetic/Filter/JSMinPlusFilter.php | 34 + .../src/Assetic/Filter/JpegoptimFilter.php | 81 + .../src/Assetic/Filter/JpegtranFilter.php | 103 + .../assetic/src/Assetic/Filter/LessFilter.php | 114 + .../src/Assetic/Filter/LessphpFilter.php | 51 + .../src/Assetic/Filter/OptiPngFilter.php | 75 + .../src/Assetic/Filter/PackagerFilter.php | 64 + .../src/Assetic/Filter/PackerFilter.php | 56 + .../src/Assetic/Filter/PngoutFilter.php | 128 + .../src/Assetic/Filter/Sass/SassFilter.php | 169 + .../src/Assetic/Filter/Sass/ScssFilter.php | 28 + .../src/Assetic/Filter/SprocketsFilter.php | 148 + .../src/Assetic/Filter/StylusFilter.php | 117 + .../src/Assetic/Filter/UglifyJsFilter.php | 136 + .../Filter/Yui/BaseCompressorFilter.php | 108 + .../Filter/Yui/CssCompressorFilter.php | 28 + .../Assetic/Filter/Yui/JsCompressorFilter.php | 61 + .../assetic/src/Assetic/FilterManager.php | 64 + .../assetic/src/Assetic/Util/PathUtils.php | 31 + .../src/Assetic/Util/TraversableString.php | 44 + .../src/Assetic/ValueSupplierInterface.php | 29 + .../kriswallsmith/assetic/src/functions.php | 121 + .../Assetic/Test/Asset/AssetCacheTest.php | 175 + .../Test/Asset/AssetCollectionTest.php | 318 ++ .../Assetic/Test/Asset/AssetReferenceTest.php | 126 + .../Assetic/Test/Asset/FileAssetTest.php | 72 + .../Assetic/Test/Asset/GlobAssetTest.php | 61 + .../Assetic/Test/Asset/HttpAssetTest.php | 58 + .../Assetic/Test/Asset/StringAssetTest.php | 79 + .../tests/Assetic/Test/AssetManagerTest.php | 53 + .../tests/Assetic/Test/AssetWriterTest.php | 206 ++ .../tests/Assetic/Test/Cache/ApcCacheTest.php | 42 + .../Assetic/Test/Cache/ConfigCacheTest.php | 65 + .../Assetic/Test/Cache/ExpiringCacheTest.php | 111 + .../Test/Cache/FilesystemCacheTest.php | 52 + .../Extension/Twig/AsseticExtensionTest.php | 204 ++ .../Extension/Twig/TwigFormulaLoaderTest.php | 97 + .../Test/Extension/Twig/TwigResourceTest.php | 48 + .../Twig/templates/absolute_path.twig | 3 + .../Extension/Twig/templates/combine.twig | 3 + .../Test/Extension/Twig/templates/debug.twig | 3 + .../Extension/Twig/templates/filters.twig | 3 + .../Extension/Twig/templates/function.twig | 3 + .../Test/Extension/Twig/templates/glob.twig | 3 + .../Test/Extension/Twig/templates/image.twig | 3 + .../Extension/Twig/templates/mixture.twig | 3 + .../Twig/templates/optional_filter.twig | 3 + .../Twig/templates/output_pattern.twig | 3 + .../Extension/Twig/templates/output_url.twig | 3 + .../Extension/Twig/templates/reference.twig | 3 + .../Extension/Twig/templates/variables.twig | 5 + .../Assetic/Test/Factory/AssetFactoryTest.php | 203 ++ .../Test/Factory/LazyAssetManagerTest.php | 96 + .../Loader/CachedFormulaLoaderTest.php | 138 + .../Loader/FunctionCallsFormulaLoaderTest.php | 69 + .../Test/Factory/Loader/templates/debug.php | 8 + .../CoalescingDirectoryResourceTest.php | 42 + .../Resource/DirectoryResourceTest.php | 108 + .../Factory/Resource/FileResourceTest.php | 42 + .../Factory/Resource/Fixtures/dir1/file1.txt | 0 .../Factory/Resource/Fixtures/dir1/file2.txt | 0 .../Factory/Resource/Fixtures/dir2/file1.txt | 0 .../Factory/Resource/Fixtures/dir2/file3.txt | 0 .../Factory/Worker/EnsureFilterWorkerTest.php | 47 + .../Test/Filter/BaseImageFilterTest.php | 24 + .../Test/Filter/CallablesFilterTest.php | 39 + .../Test/Filter/CoffeeScriptFilterTest.php | 73 + .../Assetic/Test/Filter/CompassFilterTest.php | 66 + .../Test/Filter/CssEmbedFilterTest.php | 54 + .../Test/Filter/CssImportFilterTest.php | 67 + .../Assetic/Test/Filter/CssMinFilterTest.php | 40 + .../Test/Filter/CssRewriteFilterTest.php | 124 + .../Test/Filter/FilterCollectionTest.php | 59 + .../GoogleClosure/CompilerApiFilterTest.php | 59 + .../GoogleClosure/CompilerJarFilterTest.php | 53 + .../Assetic/Test/Filter/GssFilterTest.php | 45 + .../Assetic/Test/Filter/JSMinFilterTest.php | 39 + .../Test/Filter/JSMinPlusFilterTest.php | 39 + .../Test/Filter/JpegoptimFilterTest.php | 45 + .../Test/Filter/JpegtranFilterTest.php | 45 + .../Assetic/Test/Filter/LessFilterTest.php | 63 + .../Assetic/Test/Filter/LessphpFilterTest.php | 67 + .../Assetic/Test/Filter/OptiPngFilterTest.php | 56 + .../Test/Filter/PackagerFilterTest.php | 69 + .../Assetic/Test/Filter/PackerFilterTest.php | 36 + .../Assetic/Test/Filter/PngoutFilterTest.php | 57 + .../Test/Filter/Sass/SassFilterTest.php | 70 + .../Test/Filter/Sass/ScssFilterTest.php | 44 + .../Test/Filter/SprocketsFilterTest.php | 69 + .../Assetic/Test/Filter/StylusFilterTest.php | 53 + .../Test/Filter/UglifyJsFilterTest.php | 100 + .../Filter/Yui/BaseCompressorFilterTest.php | 31 + .../Filter/Yui/CssCompressorFilterTest.php | 23 + .../Filter/Yui/JsCompressorFilterTest.php | 62 + .../Test/Filter/fixtures/compass/compass.sass | 4 + .../fixtures/compass/partials/_sass.sass | 4 + .../fixtures/compass/partials/_scss.scss | 6 + .../Filter/fixtures/compass/stylesheet.sass | 4 + .../Filter/fixtures/compass/stylesheet.scss | 6 + .../Test/Filter/fixtures/cssembed/test.css | 4 + .../Test/Filter/fixtures/cssimport/import.css | 2 + .../Test/Filter/fixtures/cssimport/main.css | 4 + .../Test/Filter/fixtures/cssimport/more.sass | 1 + .../fixtures/cssimport/more/evenmore/bg.gif | 0 .../cssimport/more/evenmore/deep1.css | 2 + .../cssimport/more/evenmore/deep2.css | 4 + .../fixtures/cssimport/noncssimport.css | 2 + .../Test/Filter/fixtures/cssmin/fonts.css | 3 + .../Test/Filter/fixtures/cssmin/main.css | 5 + .../Assetic/Test/Filter/fixtures/home.gif | Bin 0 -> 61 bytes .../Assetic/Test/Filter/fixtures/home.jpg | Bin 0 -> 431 bytes .../Assetic/Test/Filter/fixtures/home.png | Bin 0 -> 184 bytes .../Assetic/Test/Filter/fixtures/jsmin/js.js | 7 + .../Test/Filter/fixtures/less/_include.less | 1 + .../Test/Filter/fixtures/less/main.less | 3 + .../fixtures/packager/app/application.js | 11 + .../Filter/fixtures/packager/lib/package.yml | 4 + .../Test/Filter/fixtures/packager/lib/util.js | 11 + .../Test/Filter/fixtures/packer/example.js | 7 + .../Test/Filter/fixtures/sass/_include.scss | 1 + .../Test/Filter/fixtures/sass/main.scss | 3 + .../Test/Filter/fixtures/sprockets/include.js | 1 + .../sprockets/lib1/assets/images/image.gif | Bin 0 -> 49 bytes .../Filter/fixtures/sprockets/lib1/header.js | 3 + .../Filter/fixtures/sprockets/lib2/footer.js | 1 + .../Test/Filter/fixtures/sprockets/main.js | 5 + .../Test/Filter/fixtures/uglifyjs/script.js | 18 + .../tests/Assetic/Test/FilterManagerTest.php | 58 + .../tests/Assetic/Test/Fixture/messages.de.js | 1 + .../tests/Assetic/Test/Fixture/messages.en.js | 1 + .../tests/Assetic/Test/Fixture/messages.fr.js | 1 + .../Test/Util/TraversableStringTest.php | 35 + .../kriswallsmith/assetic/tests/bootstrap.php | 46 + vendor/monolog/monolog/.travis.yml | 11 + vendor/monolog/monolog/CHANGELOG.mdown | 38 + vendor/monolog/monolog/LICENSE | 19 + vendor/monolog/monolog/README.mdown | 172 + vendor/monolog/monolog/composer.json | 27 + vendor/monolog/monolog/doc/extending.md | 76 + vendor/monolog/monolog/doc/sockets.md | 37 + vendor/monolog/monolog/doc/usage.md | 124 + .../Monolog/Formatter/ChromePHPFormatter.php | 77 + .../Monolog/Formatter/FormatterInterface.php | 36 + .../Formatter/GelfMessageFormatter.php | 91 + .../src/Monolog/Formatter/JsonFormatter.php | 40 + .../src/Monolog/Formatter/LineFormatter.php | 92 + .../Monolog/Formatter/NormalizerFormatter.php | 90 + .../Monolog/Formatter/WildfireFormatter.php | 87 + .../src/Monolog/Handler/AbstractHandler.php | 173 + .../Handler/AbstractProcessingHandler.php | 70 + .../src/Monolog/Handler/BufferHandler.php | 67 + .../src/Monolog/Handler/ChromePHPHandler.php | 127 + .../ActivationStrategyInterface.php | 28 + .../ErrorLevelActivationStrategy.php | 32 + .../Monolog/Handler/FingersCrossedHandler.php | 104 + .../src/Monolog/Handler/FirePHPHandler.php | 161 + .../src/Monolog/Handler/GelfHandler.php | 66 + .../src/Monolog/Handler/GroupHandler.php | 74 + .../src/Monolog/Handler/HandlerInterface.php | 77 + .../src/Monolog/Handler/MailHandler.php | 55 + .../src/Monolog/Handler/MongoDBHandler.php | 51 + .../Monolog/Handler/NativeMailerHandler.php | 49 + .../src/Monolog/Handler/NullHandler.php | 45 + .../Monolog/Handler/RotatingFileHandler.php | 109 + .../src/Monolog/Handler/SocketHandler.php | 272 ++ .../src/Monolog/Handler/StreamHandler.php | 71 + .../Monolog/Handler/SwiftMailerHandler.php | 55 + .../src/Monolog/Handler/SyslogHandler.php | 108 + .../src/Monolog/Handler/TestHandler.php | 120 + vendor/monolog/monolog/src/Monolog/Logger.php | 421 +++ .../Processor/IntrospectionProcessor.php | 58 + .../Processor/MemoryPeakUsageProcessor.php | 40 + .../src/Monolog/Processor/MemoryProcessor.php | 50 + .../Processor/MemoryUsageProcessor.php | 40 + .../src/Monolog/Processor/WebProcessor.php | 66 + .../Composer/ScriptHandler.php | 144 + .../Configurator/Configurator.php | 186 + .../Configurator/Form/DoctrineStepType.php | 47 + .../Configurator/Form/SecretStepType.php | 33 + .../Configurator/Step/DoctrineStep.php | 143 + .../Configurator/Step/SecretStep.php | 87 + .../Configurator/Step/StepInterface.php | 65 + .../Controller/ConfiguratorController.php | 107 + .../SensioDistributionExtension.php | 33 + .../Sensio/Bundle/DistributionBundle/LICENSE | 19 + .../DistributionBundle/Resources/bin/build.sh | 102 + .../Resources/bin/build_bootstrap.php | 26 + .../config/routing/webconfigurator.xml | 18 + .../Resources/config/webconfigurator.xml | 17 + .../public/webconfigurator/css/configure.css | 153 + .../public/webconfigurator/css/install.css | 137 + .../images/background-textfield.gif | Bin 0 -> 63 bytes .../webconfigurator/images/blue-arrow.png | Bin 0 -> 181 bytes .../public/webconfigurator/images/favicon.ico | Bin 0 -> 1150 bytes .../webconfigurator/images/logo-big.gif | Bin 0 -> 4060 bytes .../webconfigurator/images/logo-small.gif | Bin 0 -> 1698 bytes .../webconfigurator/images/notification.gif | Bin 0 -> 206 bytes .../Configurator/Step/doctrine.html.twig | 31 + .../views/Configurator/Step/secret.html.twig | 44 + .../views/Configurator/check.html.twig | 43 + .../views/Configurator/final.html.twig | 28 + .../views/Configurator/form.html.twig | 31 + .../views/Configurator/layout.html.twig | 20 + .../views/Configurator/steps.html.twig | 14 + .../SensioDistributionBundle.php | 32 + .../Bundle/DistributionBundle/composer.json | 20 + .../Bundle/FrameworkExtraBundle/.travis.yml | 9 + .../Configuration/Cache.php | 171 + .../Configuration/ConfigurationAnnotation.php | 22 + .../Configuration/ConfigurationInterface.php | 27 + .../Configuration/Method.php | 69 + .../Configuration/ParamConverter.php | 152 + .../Configuration/Route.php | 33 + .../Configuration/Template.php | 148 + .../Compiler/AddParamConverterPass.php | 36 + .../DependencyInjection/Configuration.php | 55 + .../SensioFrameworkExtraExtension.php | 81 + .../EventListener/CacheListener.php | 65 + .../EventListener/ControllerListener.php | 64 + .../EventListener/ParamConverterListener.php | 85 + .../EventListener/TemplateListener.php | 126 + .../Bundle/FrameworkExtraBundle/LICENSE | 19 + .../Bundle/FrameworkExtraBundle/README.md | 6 + .../ParamConverter/DoctrineParamConverter.php | 108 + .../ParamConverterInterface.php | 27 + .../ParamConverter/ParamConverterManager.php | 92 + .../Resources/config/annotations.xml | 17 + .../Resources/config/cache.xml | 12 + .../Resources/config/converters.xml | 26 + .../Resources/config/routing.xml | 31 + .../Resources/config/services.xml | 17 + .../Resources/config/view.xml | 18 + .../Resources/doc/annotations/cache.rst | 60 + .../Resources/doc/annotations/converters.rst | 101 + .../Resources/doc/annotations/routing.rst | 166 + .../Resources/doc/annotations/view.rst | 74 + .../Resources/doc/index.rst | 145 + .../AnnotatedRouteControllerLoader.php | 75 + .../SensioFrameworkExtraBundle.php | 31 + .../Templating/TemplateGuesser.php | 98 + .../Bundle/FrameworkExtraBundle/composer.json | 26 + .../Sensio/Bundle/GeneratorBundle/.travis.yml | 9 + .../Command/GenerateBundleCommand.php | 316 ++ .../Command/GenerateDoctrineCommand.php | 41 + .../Command/GenerateDoctrineCrudCommand.php | 274 ++ .../Command/GenerateDoctrineEntityCommand.php | 312 ++ .../Command/GenerateDoctrineFormCommand.php | 71 + .../Command/Helper/DialogHelper.php | 65 + .../GeneratorBundle/Command/Validators.php | 160 + .../Generator/BundleGenerator.php | 76 + .../Generator/DoctrineCrudGenerator.php | 290 ++ .../Generator/DoctrineEntityGenerator.php | 119 + .../Generator/DoctrineFormGenerator.php | 109 + .../GeneratorBundle/Generator/Generator.php | 41 + .../Sensio/Bundle/GeneratorBundle/LICENSE | 19 + .../Manipulator/KernelManipulator.php | 105 + .../Manipulator/Manipulator.php | 85 + .../Manipulator/RoutingManipulator.php | 75 + .../Sensio/Bundle/GeneratorBundle/README.md | 10 + .../doc/commands/generate_bundle.rst | 68 + .../doc/commands/generate_doctrine_crud.rst | 65 + .../doc/commands/generate_doctrine_entity.rst | 55 + .../doc/commands/generate_doctrine_form.rst | 23 + .../GeneratorBundle/Resources/doc/index.rst | 42 + .../Resources/skeleton/bundle/Bundle.php | 9 + .../skeleton/bundle/Configuration.php | 29 + .../skeleton/bundle/DefaultController.php | 28 + .../skeleton/bundle/DefaultControllerTest.php | 17 + .../Resources/skeleton/bundle/Extension.php | 37 + .../Resources/skeleton/bundle/index.html.twig | 1 + .../Resources/skeleton/bundle/messages.fr.xlf | 11 + .../Resources/skeleton/bundle/routing.php | 11 + .../Resources/skeleton/bundle/routing.xml | 10 + .../Resources/skeleton/bundle/routing.yml | 3 + .../Resources/skeleton/bundle/services.php | 21 + .../Resources/skeleton/bundle/services.xml | 20 + .../Resources/skeleton/bundle/services.yml | 7 + .../skeleton/crud/actions/create.php | 42 + .../skeleton/crud/actions/delete.php | 38 + .../Resources/skeleton/crud/actions/edit.php | 36 + .../Resources/skeleton/crud/actions/index.php | 25 + .../Resources/skeleton/crud/actions/new.php | 26 + .../Resources/skeleton/crud/actions/show.php | 39 + .../skeleton/crud/actions/update.php | 48 + .../skeleton/crud/config/routing.php | 52 + .../skeleton/crud/config/routing.xml | 44 + .../skeleton/crud/config/routing.yml | 40 + .../Resources/skeleton/crud/controller.php | 49 + .../crud/tests/others/full_scenario.php | 44 + .../crud/tests/others/short_scenario.php | 14 + .../Resources/skeleton/crud/tests/test.php | 18 + .../skeleton/crud/views/edit.html.twig | 11 + .../skeleton/crud/views/index.html.twig | 56 + .../skeleton/crud/views/new.html.twig | 11 + .../crud/views/others/actions.html.twig | 12 + .../views/others/record_actions.html.twig | 22 + .../skeleton/crud/views/show.html.twig | 28 + .../Resources/skeleton/form/FormType.php | 34 + .../GeneratorBundle/SensioGeneratorBundle.php | 23 + .../Bundle/GeneratorBundle/composer.json | 30 + vendor/swiftmailer/swiftmailer/LICENSE | 165 + vendor/swiftmailer/swiftmailer/VERSION | 1 + vendor/swiftmailer/swiftmailer/composer.json | 29 + .../swiftmailer/swiftmailer/doc/headers.rst | 742 ++++ .../swiftmailer/doc/help-resources.rst | 44 + .../swiftmailer/doc/including-the-files.rst | 30 + vendor/swiftmailer/swiftmailer/doc/index.rst | 15 + .../swiftmailer/doc/installing.rst | 201 ++ .../swiftmailer/doc/introduction.rst | 135 + .../swiftmailer/swiftmailer/doc/messages.rst | 964 +++++ .../swiftmailer/swiftmailer/doc/overview.rst | 161 + .../swiftmailer/swiftmailer/doc/plugins.rst | 385 ++ .../swiftmailer/swiftmailer/doc/sending.rst | 592 ++++ .../swiftmailer/doc/uml/Encoders.graffle | Bin 0 -> 3503 bytes .../swiftmailer/doc/uml/Mime.graffle | Bin 0 -> 5575 bytes .../swiftmailer/doc/uml/Transports.graffle | Bin 0 -> 3061 bytes .../swiftmailer/lib/classes/Swift.php | 69 + .../lib/classes/Swift/Attachment.php | 72 + .../AbstractFilterableInputStream.php | 175 + .../Swift/ByteStream/ArrayByteStream.php | 188 + .../Swift/ByteStream/FileByteStream.php | 234 ++ .../lib/classes/Swift/CharacterReader.php | 60 + .../GenericFixedWidthReader.php | 91 + .../Swift/CharacterReader/UsAsciiReader.php | 82 + .../Swift/CharacterReader/Utf8Reader.php | 182 + .../classes/Swift/CharacterReaderFactory.php | 28 + .../SimpleCharacterReaderFactory.php | 133 + .../lib/classes/Swift/CharacterStream.php | 86 + .../CharacterStream/ArrayCharacterStream.php | 317 ++ .../CharacterStream/NgCharacterStream.php | 298 ++ .../lib/classes/Swift/ConfigurableSpool.php | 59 + .../lib/classes/Swift/DependencyContainer.php | 348 ++ .../lib/classes/Swift/DependencyException.php | 29 + .../lib/classes/Swift/EmbeddedFile.php | 70 + .../swiftmailer/lib/classes/Swift/Encoder.php | 31 + .../classes/Swift/Encoder/Base64Encoder.php | 62 + .../lib/classes/Swift/Encoder/QpEncoder.php | 296 ++ .../classes/Swift/Encoder/Rfc2231Encoder.php | 87 + .../lib/classes/Swift/Encoding.php | 69 + .../lib/classes/Swift/Events/CommandEvent.php | 65 + .../classes/Swift/Events/CommandListener.php | 27 + .../lib/classes/Swift/Events/Event.php | 39 + .../classes/Swift/Events/EventDispatcher.php | 79 + .../classes/Swift/Events/EventListener.php | 19 + .../lib/classes/Swift/Events/EventObject.php | 64 + .../classes/Swift/Events/ResponseEvent.php | 64 + .../classes/Swift/Events/ResponseListener.php | 27 + .../lib/classes/Swift/Events/SendEvent.php | 120 + .../lib/classes/Swift/Events/SendListener.php | 33 + .../Swift/Events/SimpleEventDispatcher.php | 167 + .../Swift/Events/TransportChangeEvent.php | 30 + .../Swift/Events/TransportChangeListener.php | 51 + .../Swift/Events/TransportExceptionEvent.php | 48 + .../Events/TransportExceptionListener.php | 28 + .../lib/classes/Swift/FailoverTransport.php | 46 + .../lib/classes/Swift/FileSpool.php | 210 ++ .../lib/classes/Swift/FileStream.php | 27 + .../lib/classes/Swift/Filterable.php | 33 + .../swiftmailer/lib/classes/Swift/Image.php | 60 + .../lib/classes/Swift/InputByteStream.php | 72 + .../lib/classes/Swift/IoException.php | 29 + .../lib/classes/Swift/KeyCache.php | 97 + .../classes/Swift/KeyCache/ArrayKeyCache.php | 204 ++ .../classes/Swift/KeyCache/DiskKeyCache.php | 333 ++ .../classes/Swift/KeyCache/DummyKeyCache.php | 112 + .../Swift/KeyCache/KeyCacheInputStream.php | 51 + .../classes/Swift/KeyCache/NullKeyCache.php | 106 + .../KeyCache/SimpleKeyCacheInputStream.php | 129 + .../classes/Swift/LoadBalancedTransport.php | 46 + .../lib/classes/Swift/MailTransport.php | 46 + .../swiftmailer/lib/classes/Swift/Mailer.php | 118 + .../Swift/Mailer/ArrayRecipientIterator.php | 58 + .../Swift/Mailer/RecipientIterator.php | 34 + .../lib/classes/Swift/MemorySpool.php | 84 + .../swiftmailer/lib/classes/Swift/Message.php | 84 + .../lib/classes/Swift/Mime/Attachment.php | 143 + .../classes/Swift/Mime/CharsetObserver.php | 26 + .../lib/classes/Swift/Mime/ContentEncoder.php | 38 + .../ContentEncoder/Base64ContentEncoder.php | 77 + .../ContentEncoder/PlainContentEncoder.php | 172 + .../Mime/ContentEncoder/QpContentEncoder.php | 135 + .../lib/classes/Swift/Mime/EmbeddedFile.php | 48 + .../classes/Swift/Mime/EncodingObserver.php | 27 + .../lib/classes/Swift/Mime/Grammar.php | 178 + .../lib/classes/Swift/Mime/Header.php | 85 + .../lib/classes/Swift/Mime/HeaderEncoder.php | 27 + .../HeaderEncoder/Base64HeaderEncoder.php | 61 + .../Mime/HeaderEncoder/QpHeaderEncoder.php | 70 + .../lib/classes/Swift/Mime/HeaderFactory.php | 71 + .../lib/classes/Swift/Mime/HeaderSet.php | 169 + .../Swift/Mime/Headers/AbstractHeader.php | 504 +++ .../classes/Swift/Mime/Headers/DateHeader.php | 119 + .../Mime/Headers/IdentificationHeader.php | 166 + .../Swift/Mime/Headers/MailboxHeader.php | 326 ++ .../Mime/Headers/ParameterizedHeader.php | 268 ++ .../classes/Swift/Mime/Headers/PathHeader.php | 140 + .../Swift/Mime/Headers/UnstructuredHeader.php | 107 + .../lib/classes/Swift/Mime/Message.php | 229 ++ .../lib/classes/Swift/Mime/MimeEntity.php | 105 + .../lib/classes/Swift/Mime/MimePart.php | 224 ++ .../Swift/Mime/ParameterizedHeader.php | 34 + .../Swift/Mime/SimpleHeaderFactory.php | 184 + .../classes/Swift/Mime/SimpleHeaderSet.php | 394 +++ .../lib/classes/Swift/Mime/SimpleMessage.php | 622 ++++ .../classes/Swift/Mime/SimpleMimeEntity.php | 852 +++++ .../lib/classes/Swift/MimePart.php | 63 + .../lib/classes/Swift/NullTransport.php | 38 + .../lib/classes/Swift/OutputByteStream.php | 41 + .../classes/Swift/Plugins/AntiFloodPlugin.php | 144 + .../Swift/Plugins/BandwidthMonitorPlugin.php | 166 + .../Swift/Plugins/Decorator/Replacements.php | 36 + .../classes/Swift/Plugins/DecoratorPlugin.php | 242 ++ .../Swift/Plugins/ImpersonatePlugin.php | 68 + .../lib/classes/Swift/Plugins/Logger.php | 37 + .../classes/Swift/Plugins/LoggerPlugin.php | 150 + .../Swift/Plugins/Loggers/ArrayLogger.php | 73 + .../Swift/Plugins/Loggers/EchoLogger.php | 64 + .../classes/Swift/Plugins/MessageLogger.php | 77 + .../Swift/Plugins/Pop/Pop3Connection.php | 36 + .../Swift/Plugins/Pop/Pop3Exception.php | 33 + .../Swift/Plugins/PopBeforeSmtpPlugin.php | 286 ++ .../Swift/Plugins/RedirectingPlugin.php | 109 + .../lib/classes/Swift/Plugins/Reporter.php | 35 + .../classes/Swift/Plugins/ReporterPlugin.php | 79 + .../Swift/Plugins/Reporters/HitReporter.php | 61 + .../Swift/Plugins/Reporters/HtmlReporter.php | 45 + .../lib/classes/Swift/Plugins/Sleeper.php | 26 + .../classes/Swift/Plugins/ThrottlerPlugin.php | 184 + .../lib/classes/Swift/Plugins/Timer.php | 26 + .../lib/classes/Swift/Preferences.php | 91 + .../Swift/ReplacementFilterFactory.php | 27 + .../classes/Swift/RfcComplianceException.php | 29 + .../lib/classes/Swift/SendmailTransport.php | 46 + .../lib/classes/Swift/SmtpTransport.php | 54 + .../swiftmailer/lib/classes/Swift/Spool.php | 52 + .../lib/classes/Swift/SpoolTransport.php | 44 + .../lib/classes/Swift/StreamFilter.php | 33 + .../ByteArrayReplacementFilter.php | 187 + .../StreamFilters/StringReplacementFilter.php | 65 + .../StringReplacementFilterFactory.php | 51 + .../lib/classes/Swift/SwiftException.php | 28 + .../lib/classes/Swift/Transport.php | 58 + .../Swift/Transport/AbstractSmtpTransport.php | 559 +++ .../Esmtp/Auth/CramMd5Authenticator.php | 85 + .../Esmtp/Auth/LoginAuthenticator.php | 55 + .../Esmtp/Auth/PlainAuthenticator.php | 54 + .../Swift/Transport/Esmtp/AuthHandler.php | 259 ++ .../Swift/Transport/Esmtp/Authenticator.php | 37 + .../classes/Swift/Transport/EsmtpHandler.php | 81 + .../Swift/Transport/EsmtpTransport.php | 395 +++ .../Swift/Transport/FailoverTransport.php | 95 + .../lib/classes/Swift/Transport/IoBuffer.php | 63 + .../Swift/Transport/LoadBalancedTransport.php | 185 + .../classes/Swift/Transport/MailInvoker.php | 36 + .../classes/Swift/Transport/MailTransport.php | 245 ++ .../classes/Swift/Transport/NullTransport.php | 90 + .../Swift/Transport/SendmailTransport.php | 170 + .../Swift/Transport/SimpleMailInvoker.php | 57 + .../lib/classes/Swift/Transport/SmtpAgent.php | 36 + .../Swift/Transport/SpoolTransport.php | 116 + .../classes/Swift/Transport/StreamBuffer.php | 329 ++ .../lib/classes/Swift/TransportException.php | 30 + .../lib/classes/Swift/Validate.php | 38 + .../lib/dependency_maps/cache_deps.php | 25 + .../lib/dependency_maps/message_deps.php | 9 + .../lib/dependency_maps/mime_deps.php | 105 + .../lib/dependency_maps/transport_deps.php | 70 + .../swiftmailer/lib/mime_types.php | 76 + .../swiftmailer/lib/preferences.php | 22 + .../swiftmailer/lib/swift_init.php | 27 + .../swiftmailer/lib/swift_required.php | 24 + .../swiftmailer/lib/swift_required_pear.php | 27 + .../Bundle/AsseticBundle/AsseticBundle.php | 49 + .../CacheWarmer/AssetManagerCacheWarmer.php | 41 + .../AsseticBundle/Command/DumpCommand.php | 232 ++ .../AsseticBundle/Config/AsseticResource.php | 75 + .../Controller/AsseticController.php | 121 + .../AsseticBundle/DefaultValueSupplier.php | 35 + .../DependencyInjection/AsseticExtension.php | 144 + .../Compiler/AssetFactoryPass.php | 36 + .../Compiler/AssetManagerPass.php | 62 + .../Compiler/CheckClosureFilterPass.php | 36 + .../Compiler/CheckCssEmbedFilterPass.php | 31 + .../Compiler/CheckYuiFilterPass.php | 36 + .../Compiler/FilterManagerPass.php | 44 + .../Compiler/RouterResourcePass.php | 44 + .../Compiler/SprocketsFilterPass.php | 35 + .../Compiler/TemplateResourcesPass.php | 67 + .../Compiler/TemplatingPass.php | 44 + .../DependencyInjection/Configuration.php | 199 ++ .../DirectoryResourceDefinition.php | 75 + .../EventListener/RequestListener.php | 31 + .../Exception/InvalidBundleException.php | 26 + .../AsseticBundle/Factory/AssetFactory.php | 97 + .../Loader/AsseticHelperFormulaLoader.php | 87 + .../Factory/Loader/ConfigurationLoader.php | 29 + .../Resource/CoalescingDirectoryResource.php | 30 + .../Resource/ConfigurationResource.php | 44 + .../Factory/Resource/DirectoryResource.php | 51 + .../Resource/DirectoryResourceIterator.php | 45 + .../Factory/Resource/FileResource.php | 88 + .../Factory/Worker/UseControllerWorker.php | 33 + .../Bundle/AsseticBundle/FilterManager.php | 55 + .../Resources/config/assetic.xml | 79 + .../Resources/config/controller.xml | 41 + .../Resources/config/filters/closure.xml | 31 + .../Resources/config/filters/coffee.xml | 22 + .../Resources/config/filters/compass.xml | 36 + .../Resources/config/filters/cssembed.xml | 34 + .../Resources/config/filters/cssimport.xml | 16 + .../Resources/config/filters/cssmin.xml | 20 + .../Resources/config/filters/cssrewrite.xml | 16 + .../Resources/config/filters/gss.xml | 20 + .../Resources/config/filters/jpegoptim.xml | 22 + .../Resources/config/filters/jpegtran.xml | 26 + .../Resources/config/filters/less.xml | 22 + .../Resources/config/filters/lessphp.xml | 18 + .../Resources/config/filters/optipng.xml | 20 + .../Resources/config/filters/packager.xml | 18 + .../Resources/config/filters/pngout.xml | 26 + .../Resources/config/filters/sass.xml | 22 + .../Resources/config/filters/scss.xml | 22 + .../Resources/config/filters/sprockets.xml | 23 + .../Resources/config/filters/stylus.xml | 22 + .../Resources/config/filters/uglifyjs.xml | 32 + .../Resources/config/filters/yui_css.xml | 22 + .../Resources/config/filters/yui_js.xml | 28 + .../Resources/config/schema/assetic-1.0.xsd | 58 + .../Resources/config/templating_php.xml | 39 + .../Resources/config/templating_twig.xml | 35 + .../AsseticBundle/Routing/AsseticLoader.php | 122 + .../Templating/AsseticHelper.php | 157 + .../Templating/DynamicAsseticHelper.php | 44 + .../Templating/StaticAsseticHelper.php | 44 + .../AssetManagerCacheWarmerTest.php | 51 + .../Tests/Command/DumpCommandTest.php | 202 ++ .../Controller/AsseticControllerTest.php | 167 + .../AsseticExtensionTest.php | 215 ++ .../Tests/Factory/AssetFactoryTest.php | 97 + .../CoalescingDirectoryResourceTest.php | 63 + .../Factory/Resource/FileResourceTest.php | 31 + .../AsseticBundle/Tests/FilterManagerTest.php | 59 + .../AsseticBundle/Tests/FunctionalTest.php | 75 + .../Resources/Resources/views/base.html.php | 11 + .../Resources/Resources/views/base.html.twig | 11 + .../Resources/Resources/views/layout.html.php | 17 + .../Resources/views/layout.html.twig | 19 + .../Tests/Resources/config/config.yml | 40 + .../Tests/Resources/config/routing.yml | 3 + .../Tests/Resources/web/javascript1.js | 1 + .../Tests/Resources/web/javascript2.js | 1 + .../Tests/Resources/web/stylesheet1.css | 1 + .../Tests/Resources/web/stylesheet2.css | 1 + .../Tests/Templating/AsseticHelperTest.php | 56 + .../Tests/TestBundle/Resources/css/bundle.css | 1 + .../Tests/TestBundle/TestBundle.php | 18 + .../Bundle/AsseticBundle/Tests/TestKernel.php | 38 + .../Bundle/AsseticBundle/Tests/bootstrap.php | 17 + .../AsseticBundle/Twig/AsseticExtension.php | 69 + .../Bundle/AsseticBundle/Twig/AsseticNode.php | 83 + .../AsseticBundle/Twig/AsseticNodeVisitor.php | 120 + .../AsseticBundle/Twig/AsseticTokenParser.php | 66 + .../Symfony/Bundle/AsseticBundle/UPGRADE.md | 10 + .../Bundle/AsseticBundle/composer.json | 33 + .../Bundle/AsseticBundle/phpunit.xml.dist | 35 + .../Symfony/Bundle/MonologBundle/.travis.yml | 9 + .../Compiler/AddProcessorsPass.php | 59 + .../Compiler/DebugHandlerPass.php | 49 + .../Compiler/LoggerChannelPass.php | 105 + .../DependencyInjection/Configuration.php | 215 ++ .../DependencyInjection/MonologExtension.php | 289 ++ .../Symfony/Bundle/MonologBundle/LICENSE | 19 + .../Bundle/MonologBundle/MonologBundle.php | 35 + .../Resources/config/monolog.xml | 39 + .../Resources/config/schema/monolog-1.0.xsd | 92 + .../Compiler/AddProcessorsPassTest.php | 67 + .../Compiler/LoggerChannelPassTest.php | 130 + .../DependencyInjection/ConfigurationTest.php | 228 ++ .../Fixtures/xml/handlers_with_channels.xml | 31 + .../Fixtures/xml/multiple_handlers.xml | 14 + .../Fixtures/xml/new_and_priority.xml | 18 + .../Fixtures/xml/new_and_priority_import.xml | 14 + .../Fixtures/xml/new_at_end.xml | 17 + .../Fixtures/xml/new_at_end_import.xml | 14 + .../Fixtures/xml/overwriting.xml | 16 + .../Fixtures/xml/overwriting_import.xml | 14 + .../Fixtures/yml/handlers_with_channels.yml | 30 + .../Fixtures/yml/multiple_handlers.yml | 13 + .../Fixtures/yml/new_and_priority.yml | 22 + .../Fixtures/yml/new_and_priority_import.yml | 13 + .../Fixtures/yml/new_at_end.yml | 15 + .../Fixtures/yml/new_at_end_import.yml | 13 + .../Fixtures/yml/overwriting.yml | 10 + .../Fixtures/yml/overwriting_import.yml | 13 + .../MonologExtensionTest.php | 285 ++ .../XmlMonologExtensionTest.php | 25 + .../YamlMonologExtensionTest.php | 25 + .../Bundle/MonologBundle/Tests/TestCase.php | 22 + .../Bundle/MonologBundle/Tests/bootstrap.php | 19 + .../Bundle/MonologBundle/composer.json | 37 + .../Bundle/MonologBundle/phpunit.xml.dist | 20 + .../Command/SendEmailCommand.php | 74 + .../Compiler/RegisterPluginsPass.php | 36 + .../DependencyInjection/Configuration.php | 91 + .../SwiftmailerExtension.php | 155 + .../EventListener/EmailSenderListener.php | 59 + .../Symfony/Bundle/SwiftmailerBundle/LICENSE | 19 + .../config/schema/swiftmailer-1.0.xsd | 63 + .../Resources/config/smtp.xml | 27 + .../Resources/config/spool.xml | 18 + .../Resources/config/spool_file.xml | 16 + .../Resources/config/spool_memory.xml | 20 + .../Resources/config/swiftmailer.xml | 86 + .../views/Collector/swiftmailer.html.twig | 53 + .../SwiftmailerBundle/SwiftmailerBundle.php | 31 + .../SwiftmailerExtensionTest.php | 57 + .../SwiftmailerBundle/Tests/TestCase.php | 22 + .../Bundle/SwiftmailerBundle/composer.json | 33 + vendor/symfony/symfony/.editorconfig | 10 + vendor/symfony/symfony/.travis.yml | 10 + vendor/symfony/symfony/CHANGELOG-2.0.md | 341 ++ vendor/symfony/symfony/CONTRIBUTORS.md | 457 +++ vendor/symfony/symfony/LICENSE | 19 + vendor/symfony/symfony/UPGRADE-2.1.md | 1094 ++++++ vendor/symfony/symfony/autoload.php.dist | 22 + vendor/symfony/symfony/composer.json | 75 + .../src/Symfony/Bridge/Doctrine/CHANGELOG.md | 9 + .../Doctrine/CacheWarmer/ProxyCacheWarmer.php | 71 + .../Doctrine/ContainerAwareEventManager.php | 137 + .../DataCollector/DoctrineDataCollector.php | 177 + .../DataFixtures/ContainerAwareLoader.php | 54 + .../AbstractDoctrineExtension.php | 383 ++ .../CompilerPass/DoctrineValidationPass.php | 71 + ...gisterEventListenersAndSubscribersPass.php | 130 + .../Security/UserProvider/EntityFactory.php | 62 + .../Form/ChoiceList/EntityChoiceList.php | 394 +++ .../Form/ChoiceList/EntityLoaderInterface.php | 39 + .../Form/ChoiceList/ORMQueryBuilderLoader.php | 82 + .../CollectionToArrayTransformer.php | 61 + .../Doctrine/Form/DoctrineOrmExtension.php | 37 + .../Doctrine/Form/DoctrineOrmTypeGuesser.php | 151 + .../MergeDoctrineCollectionListener.php | 47 + .../Doctrine/Form/Type/DoctrineType.php | 101 + .../Bridge/Doctrine/Form/Type/EntityType.php | 40 + .../HttpFoundation/DbalSessionHandler.php | 172 + .../DbalSessionHandlerSchema.php | 48 + .../src/Symfony/Bridge/Doctrine/LICENSE | 19 + .../Bridge/Doctrine/Logger/DbalLogger.php | 73 + .../Bridge/Doctrine/ManagerRegistry.php | 53 + .../src/Symfony/Bridge/Doctrine/README.md | 28 + .../Bridge/Doctrine/RegistryInterface.php | 94 + .../Security/User/EntityUserProvider.php | 110 + .../Tests/ContainerAwareEventManagerTest.php | 66 + .../DoctrineDataCollectorTest.php | 158 + .../DataFixtures/ContainerAwareLoaderTest.php | 40 + ...erEventListenersAndSubscribersPassTest.php | 126 + .../Doctrine/Tests/DoctrineOrmTestCase.php | 59 + .../Tests/Fixtures/AssociationEntity.php | 43 + .../Tests/Fixtures/CompositeIdentEntity.php | 62 + .../Fixtures/CompositeStringIdentEntity.php | 36 + .../Tests/Fixtures/ContainerAwareFixture.php | 31 + .../Tests/Fixtures/ItemGroupEntity.php | 36 + .../Fixtures/NoToStringSingleIdentEntity.php | 32 + .../Tests/Fixtures/SingleIdentEntity.php | 37 + .../Fixtures/SingleStringIdentEntity.php | 32 + .../Form/ChoiceList/EntityChoiceListTest.php | 311 ++ .../Tests/Form/Type/EntityTypeTest.php | 697 ++++ .../HttpFoundation/DbalSessionHandlerTest.php | 37 + .../Security/User/EntityUserProviderTest.php | 119 + .../Constraints/UniqueValidatorTest.php | 229 ++ .../Bridge/Doctrine/Tests/bootstrap.php | 70 + .../Validator/Constraints/UniqueEntity.php | 56 + .../Constraints/UniqueEntityValidator.php | 119 + .../Validator/DoctrineInitializer.php | 38 + .../src/Symfony/Bridge/Doctrine/composer.json | 38 + .../Symfony/Bridge/Doctrine/phpunit.xml.dist | 29 + .../src/Symfony/Bridge/Monolog/CHANGELOG.md | 7 + .../Monolog/Handler/ChromePhpHandler.php | 83 + .../Bridge/Monolog/Handler/DebugHandler.php | 58 + .../Bridge/Monolog/Handler/FirePHPHandler.php | 84 + .../src/Symfony/Bridge/Monolog/LICENSE | 19 + .../src/Symfony/Bridge/Monolog/Logger.php | 58 + .../Bridge/Monolog/Processor/WebProcessor.php | 38 + .../src/Symfony/Bridge/Monolog/README.md | 18 + .../Tests/Processor/WebProcessorTest.php | 77 + .../Bridge/Monolog/Tests/bootstrap.php | 34 + .../src/Symfony/Bridge/Monolog/composer.json | 32 + .../Symfony/Bridge/Monolog/phpunit.xml.dist | 29 + .../src/Symfony/Bridge/Propel1/CHANGELOG.md | 7 + .../DataCollector/PropelDataCollector.php | 145 + .../Security/UserProvider/PropelFactory.php | 58 + .../Form/ChoiceList/ModelChoiceList.php | 354 ++ .../CollectionToArrayTransformer.php | 55 + .../Bridge/Propel1/Form/PropelExtension.php | 34 + .../Bridge/Propel1/Form/PropelTypeGuesser.php | 172 + .../Bridge/Propel1/Form/Type/ModelType.php | 70 + .../src/Symfony/Bridge/Propel1/LICENSE | 19 + .../Bridge/Propel1/Logger/PropelLogger.php | 170 + .../src/Symfony/Bridge/Propel1/README.md | 20 + .../Security/User/PropelUserProvider.php | 100 + .../DataCollector/PropelDataCollectorTest.php | 110 + .../Bridge/Propel1/Tests/Fixtures/Column.php | 59 + .../Bridge/Propel1/Tests/Fixtures/Item.php | 108 + .../Propel1/Tests/Fixtures/ItemQuery.php | 64 + .../Propel1/Tests/Fixtures/ReadOnlyItem.php | 25 + .../Tests/Fixtures/ReadOnlyItemQuery.php | 27 + .../Form/ChoiceList/ModelChoiceListTest.php | 161 + .../CollectionToArrayTransformerTest.php | 111 + .../Tests/Form/PropelTypeGuesserTest.php | 119 + .../Bridge/Propel1/Tests/Propel1TestCase.php | 22 + .../Bridge/Propel1/Tests/bootstrap.php | 34 + .../src/Symfony/Bridge/Propel1/composer.json | 34 + .../Symfony/Bridge/Propel1/phpunit.xml.dist | 29 + .../Symfony/Bridge/Swiftmailer/CHANGELOG.md | 7 + .../DataCollector/MessageDataCollector.php | 85 + .../src/Symfony/Bridge/Swiftmailer/LICENSE | 19 + .../Symfony/Bridge/Swiftmailer/composer.json | 34 + .../src/Symfony/Bridge/Twig/CHANGELOG.md | 11 + .../Bridge/Twig/Extension/FormExtension.php | 366 ++ .../Twig/Extension/RoutingExtension.php | 62 + .../Twig/Extension/SecurityExtension.php | 63 + .../Twig/Extension/TranslationExtension.php | 114 + .../Bridge/Twig/Extension/YamlExtension.php | 67 + .../symfony/src/Symfony/Bridge/Twig/LICENSE | 19 + .../Bridge/Twig/Node/FormThemeNode.php | 40 + .../Twig/Node/TransDefaultDomainNode.php | 33 + .../Symfony/Bridge/Twig/Node/TransNode.php | 119 + .../TranslationDefaultDomainNodeVisitor.php | 81 + .../NodeVisitor/TranslationNodeVisitor.php | 98 + .../symfony/src/Symfony/Bridge/Twig/README.md | 15 + .../views/Form/form_div_layout.html.twig | 329 ++ .../views/Form/form_table_layout.html.twig | 52 + .../Fixtures/StubFilesystemLoader.php | 30 + .../Extension/Fixtures/StubTranslator.php | 35 + .../Extension/FormExtensionDivLayoutTest.php | 147 + .../FormExtensionTableLayoutTest.php | 103 + .../Extension/TranslationExtensionTest.php | 149 + .../Tests/Extension/child_label.html.twig | 3 + .../Tests/Extension/custom_widgets.html.twig | 5 + .../Tests/Extension/parent_label.html.twig | 3 + .../Twig/Tests/Extension/theme.html.twig | 6 + .../Tests/Extension/theme_extends.html.twig | 8 + .../Twig/Tests/Extension/theme_use.html.twig | 8 + .../Bridge/Twig/Tests/Node/FormThemeTest.php | 85 + .../Symfony/Bridge/Twig/Tests/TestCase.php | 22 + .../TokenParser/FormThemeTokenParserTest.php | 108 + .../Tests/Translation/TwigExtractorTest.php | 71 + .../Symfony/Bridge/Twig/Tests/bootstrap.php | 14 + .../Twig/TokenParser/FormThemeTokenParser.php | 61 + .../TokenParser/TransChoiceTokenParser.php | 87 + .../TransDefaultDomainTokenParser.php | 48 + .../Twig/TokenParser/TransTokenParser.php | 87 + .../Bridge/Twig/Translation/TwigExtractor.php | 85 + .../src/Symfony/Bridge/Twig/TwigEngine.php | 126 + .../src/Symfony/Bridge/Twig/composer.json | 47 + .../src/Symfony/Bridge/Twig/phpunit.xml.dist | 30 + .../Bundle/FrameworkBundle/CHANGELOG.md | 34 + .../CacheWarmer/RouterCacheWarmer.php | 58 + .../CacheWarmer/TemplateFinder.php | 109 + .../CacheWarmer/TemplateFinderInterface.php | 28 + .../CacheWarmer/TemplatePathsCacheWarmer.php | 64 + .../Symfony/Bundle/FrameworkBundle/Client.php | 109 + .../Command/AssetsInstallCommand.php | 112 + .../Command/CacheClearCommand.php | 177 + .../Command/CacheWarmupCommand.php | 61 + .../Command/ConfigDumpReferenceCommand.php | 259 ++ .../Command/ContainerAwareCommand.php | 49 + .../Command/ContainerDebugCommand.php | 226 ++ .../Command/RouterApacheDumperCommand.php | 86 + .../Command/RouterDebugCommand.php | 176 + .../Command/RouterMatchCommand.php | 89 + .../Command/ServerRunCommand.php | 98 + .../Command/TranslationUpdateCommand.php | 134 + .../FrameworkBundle/Console/Application.php | 87 + .../Bundle/FrameworkBundle/Console/Shell.php | 45 + .../FrameworkBundle/Controller/Controller.php | 247 ++ .../Controller/ControllerNameParser.php | 86 + .../Controller/ControllerResolver.php | 85 + .../Controller/InternalController.php | 46 + .../Controller/RedirectController.php | 101 + .../Controller/TemplateController.php | 35 + .../TraceableControllerResolver.php | 71 + .../DataCollector/RequestDataCollector.php | 95 + .../DataCollector/RouterDataCollector.php | 104 + .../Compiler/AddCacheClearerPass.php | 41 + .../Compiler/AddCacheWarmerPass.php | 50 + .../Compiler/AddConstraintValidatorsPass.php | 34 + .../Compiler/AddValidatorInitializersPass.php | 33 + .../Compiler/CompilerDebugDumpPass.php | 33 + .../ContainerBuilderDebugDumpPass.php | 34 + .../DependencyInjection/Compiler/FormPass.php | 62 + .../Compiler/ProfilerPass.php | 57 + .../Compiler/RegisterKernelListenersPass.php | 59 + .../Compiler/RoutingResolverPass.php | 37 + .../Compiler/TemplatingPass.php | 39 + .../Compiler/TranslationDumperPass.php | 35 + .../Compiler/TranslationExtractorPass.php | 39 + .../Compiler/TranslatorPass.php | 45 + .../DependencyInjection/Configuration.php | 389 +++ .../FrameworkExtension.php | 682 ++++ .../EventListener/SessionListener.php | 75 + .../EventListener/TestSessionListener.php | 88 + .../FrameworkBundle/FrameworkBundle.php | 72 + .../FrameworkBundle/HttpCache/HttpCache.php | 82 + .../Bundle/FrameworkBundle/HttpKernel.php | 239 ++ .../Symfony/Bundle/FrameworkBundle/LICENSE | 19 + .../Resources/config/annotations.xml | 30 + .../Resources/config/collectors.xml | 60 + .../Resources/config/debug.xml | 32 + .../FrameworkBundle/Resources/config/esi.xml | 20 + .../FrameworkBundle/Resources/config/form.xml | 144 + .../Resources/config/form_csrf.xml | 24 + .../Resources/config/profiling.xml | 34 + .../Resources/config/router.php | 30 + .../Resources/config/routing.xml | 95 + .../Resources/config/routing/internal.xml | 18 + .../Resources/config/schema/symfony-1.0.xsd | 142 + .../Resources/config/services.xml | 55 + .../Resources/config/session.xml | 50 + .../Resources/config/templating.xml | 61 + .../Resources/config/templating_debug.xml | 17 + .../Resources/config/templating_php.xml | 108 + .../FrameworkBundle/Resources/config/test.xml | 32 + .../Resources/config/translation.xml | 139 + .../Resources/config/validator.xml | 65 + .../FrameworkBundle/Resources/config/web.xml | 43 + .../Resources/public/css/exception.css | 228 ++ .../Resources/public/css/exception_layout.css | 136 + .../public/images/blue_picto_less.gif | Bin 0 -> 197 bytes .../public/images/blue_picto_more.gif | Bin 0 -> 213 bytes .../Resources/public/images/border_l.png | Bin 0 -> 249 bytes .../Resources/public/images/border_r.png | Bin 0 -> 253 bytes .../Resources/public/images/btn_bg.png | Bin 0 -> 87 bytes .../Resources/public/images/close_quote.gif | Bin 0 -> 284 bytes .../public/images/exception_detected.gif | Bin 0 -> 3996 bytes .../public/images/exception_detected.png | Bin 0 -> 3637 bytes .../public/images/grey_magnifier.png | Bin 0 -> 393 bytes .../Resources/public/images/icon_log.png | Bin 0 -> 283 bytes .../Resources/public/images/input_bg.gif | Bin 0 -> 63 bytes .../Resources/public/images/logo_symfony.gif | Bin 0 -> 1698 bytes .../Resources/public/images/logo_symfony.png | Bin 0 -> 1459 bytes .../Resources/public/images/open_quote.gif | Bin 0 -> 281 bytes .../Resources/views/Form/attributes.html.php | 1 + .../views/Form/checkbox_widget.html.php | 5 + .../views/Form/choice_options.html.php | 1 + .../views/Form/choice_widget.html.php | 5 + .../Form/choice_widget_collapsed.html.php | 13 + .../Form/choice_widget_expanded.html.php | 6 + .../views/Form/choice_widget_options.html.php | 11 + .../views/Form/collection_widget.html.php | 4 + .../views/Form/container_attributes.html.php | 1 + .../Resources/views/Form/date_widget.html.php | 11 + .../views/Form/datetime_widget.html.php | 7 + .../views/Form/email_widget.html.php | 1 + .../views/Form/field_enctype.html.php | 1 + .../views/Form/field_errors.html.php | 1 + .../Resources/views/Form/field_label.html.php | 1 + .../Resources/views/Form/field_rest.html.php | 1 + .../Resources/views/Form/field_row.html.php | 1 + .../Resources/views/Form/field_rows.html.php | 1 + .../views/Form/field_widget.html.php | 1 + .../views/Form/form_enctype.html.php | 1 + .../Resources/views/Form/form_errors.html.php | 21 + .../Resources/views/Form/form_label.html.php | 3 + .../Resources/views/Form/form_rest.html.php | 5 + .../Resources/views/Form/form_row.html.php | 7 + .../Resources/views/Form/form_rows.html.php | 4 + .../Resources/views/Form/form_widget.html.php | 5 + .../views/Form/form_widget_compound.html.php | 4 + .../views/Form/form_widget_simple.html.php | 5 + .../Resources/views/Form/hidden_row.html.php | 1 + .../views/Form/hidden_widget.html.php | 1 + .../views/Form/integer_widget.html.php | 1 + .../views/Form/money_widget.html.php | 1 + .../views/Form/number_widget.html.php | 1 + .../views/Form/password_widget.html.php | 1 + .../views/Form/percent_widget.html.php | 1 + .../views/Form/radio_widget.html.php | 5 + .../views/Form/repeated_row.html.php | 1 + .../views/Form/search_widget.html.php | 1 + .../views/Form/textarea_widget.html.php | 1 + .../Resources/views/Form/time_widget.html.php | 18 + .../Resources/views/Form/url_widget.html.php | 1 + .../views/Form/widget_attributes.html.php | 10 + .../Form/widget_container_attributes.html.php | 2 + .../views/FormTable/form_errors.html.php | 51 + .../views/FormTable/form_row.html.php | 11 + .../FormTable/form_widget_compound.html.php | 4 + .../views/FormTable/hidden_row.html.php | 6 + .../Routing/DelegatingLoader.php | 73 + .../Routing/RedirectableUrlMatcher.php | 42 + .../Bundle/FrameworkBundle/Routing/Router.php | 109 + .../Templating/Asset/PackageFactory.php | 44 + .../Templating/Asset/PathPackage.php | 35 + .../FrameworkBundle/Templating/Debugger.php | 47 + .../Templating/DelegatingEngine.php | 95 + .../Templating/EngineInterface.php | 34 + .../Templating/GlobalVariables.php | 110 + .../Templating/Helper/ActionsHelper.php | 61 + .../Templating/Helper/CodeHelper.php | 222 ++ .../Templating/Helper/FormHelper.php | 360 ++ .../Templating/Helper/RequestHelper.php | 68 + .../Templating/Helper/RouterHelper.php | 59 + .../Templating/Helper/SessionHelper.php | 73 + .../Templating/Helper/TranslatorHelper.php | 61 + .../Templating/Loader/FilesystemLoader.php | 74 + .../Templating/Loader/TemplateLocator.php | 84 + .../FrameworkBundle/Templating/PhpEngine.php | 92 + .../Templating/TemplateNameParser.php | 105 + .../Templating/TemplateReference.php | 57 + .../FrameworkBundle/Test/WebTestCase.php | 169 + .../Tests/CacheWarmer/TemplateFinderTest.php | 58 + .../Tests/Command/TestCaseMethod.tpl | 47 + .../Controller/ControllerNameParserTest.php | 110 + .../Controller/RedirectControllerTest.php | 123 + .../Compiler/AddCacheWarmerPassTest.php | 92 + .../Compiler/ProfilerPassTest.php | 76 + .../RegisterKernelListenersPassTest.php | 89 + .../Compiler/TranslatorPassTest.php | 48 + .../Resources/config/validation.xml | 0 .../Resources/config/validation.yml | 0 .../Fixtures/TestBundle/TestBundle.php | 17 + .../Fixtures/php/deprecated_merge_full.php | 22 + .../Fixtures/php/deprecated_merge_partial.php | 19 + .../DependencyInjection/Fixtures/php/full.php | 72 + .../Fixtures/php/templating_url_package.php | 14 + .../Fixtures/php/validation_annotations.php | 9 + .../Fixtures/xml/deprecated_merge_full.xml | 12 + .../Fixtures/xml/deprecated_merge_partial.xml | 12 + .../DependencyInjection/Fixtures/xml/full.xml | 40 + .../Fixtures/xml/templating_url_package.xml | 19 + .../Fixtures/xml/validation_annotations.xml | 12 + .../Fixtures/yml/deprecated_merge_full.yml | 17 + .../Fixtures/yml/deprecated_merge_partial.yml | 15 + .../DependencyInjection/Fixtures/yml/full.yml | 55 + .../Fixtures/yml/templating_url_package.yml | 8 + .../Fixtures/yml/validation_annotations.yml | 5 + .../FrameworkExtensionTest.php | 305 ++ .../PhpFrameworkExtensionTest.php | 25 + .../XmlFrameworkExtensionTest.php | 25 + .../YamlFrameworkExtensionTest.php | 25 + .../EventListener/TestSessionListenerTest.php | 106 + .../Tests/Fixtures/BaseBundle/BaseBundle.php | 18 + .../Resources/views/base.format.engine | 0 .../views/controller/base.format.engine | 0 .../views/this.is.a.template.format.engine | 0 .../Resources/views/resource.format.engine | 0 .../views/this.is.a.template.format.engine | 0 .../Resources/views/translation.html.php | 2 + .../Controller/DefaultController.php | 21 + .../Fabpot/FooBundle/FabpotFooBundle.php | 30 + .../Controller/DefaultController.php | 21 + .../Controller/Sub/DefaultController.php | 21 + .../Controller/Test/DefaultController.php | 21 + .../TestBundle/FooBundle/FooBundle.php | 23 + .../Controller/DefaultController.php | 21 + .../Cms/FooBundle/SensioCmsFooBundle.php | 23 + .../Controller/DefaultController.php | 21 + .../Sensio/FooBundle/SensioFooBundle.php | 23 + .../Controller/SessionController.php | 72 + .../TestBundle/Resources/config/routing.yml | 20 + .../Bundle/TestBundle/TestBundle.php | 18 + .../Tests/Functional/SessionTest.php | 154 + .../Tests/Functional/WebTestCase.php | 67 + .../Tests/Functional/app/AppKernel.php | 113 + .../Tests/Functional/app/Session/bundles.php | 9 + .../Tests/Functional/app/Session/config.yml | 3 + .../Tests/Functional/app/Session/routing.yml | 2 + .../Tests/Functional/app/config/default.yml | 2 + .../Tests/Functional/app/config/framework.yml | 16 + .../FrameworkBundle/Tests/HttpKernelTest.php | 216 ++ .../Routing/RedirectableUrlMatcherTest.php | 60 + .../Tests/Routing/RouterTest.php | 88 + .../Templating/Helper/CodeHelperTest.php | 69 + .../Fixtures/StubTemplateNameParser.php | 43 + .../Helper/Fixtures/StubTranslator.php | 35 + .../Helper/FormHelperDivLayoutTest.php | 98 + .../Helper/FormHelperTableLayoutTest.php | 87 + .../Templating/Helper/RequestHelperTest.php | 55 + .../Resources/Child/form_label.html.php | 1 + .../Resources/Custom/_text_id_widget.html.php | 3 + .../Resources/Parent/form_label.html.php | 1 + .../Parent/form_widget_simple.html.php | 2 + .../Templating/Helper/SessionHelperTest.php | 70 + .../Templating/Loader/TemplateLocatorTest.php | 84 + .../Tests/Templating/PhpEngineTest.php | 74 + .../Templating/TemplateNameParserTest.php | 113 + .../Templating/TemplateReferenceTest.php | 28 + .../Tests/Templating/TemplateTest.php | 48 + .../Bundle/FrameworkBundle/Tests/TestCase.php | 16 + .../Tests/Translation/PhpExtractorTest.php | 35 + .../Tests/Translation/TranslatorTest.php | 150 + .../ConstraintValidatorFactoryTest.php | 65 + .../Translation/PhpExtractor.php | 123 + .../Translation/TranslationLoader.php | 61 + .../Translation/Translator.php | 148 + .../Validator/ConstraintValidatorFactory.php | 74 + .../Bundle/FrameworkBundle/composer.json | 45 + .../Bundle/SecurityBundle/CHANGELOG.md | 77 + .../SecurityBundle/Command/InitAclCommand.php | 74 + .../DataCollector/SecurityDataCollector.php | 109 + .../Compiler/AddSecurityVotersPass.php | 45 + .../DependencyInjection/MainConfiguration.php | 389 +++ .../Security/Factory/AbstractFactory.php | 169 + .../Security/Factory/FormLoginFactory.php | 100 + .../Security/Factory/HttpBasicFactory.php | 82 + .../Security/Factory/HttpDigestFactory.php | 85 + .../Security/Factory/RememberMeFactory.php | 143 + .../Factory/SecurityFactoryInterface.php | 31 + .../Security/Factory/X509Factory.php | 67 + .../Security/UserProvider/InMemoryFactory.php | 69 + .../UserProviderFactoryInterface.php | 30 + .../DependencyInjection/SecurityExtension.php | 635 ++++ .../EventListener/AclSchemaListener.php | 36 + .../EventListener/ResponseListener.php | 34 + .../src/Symfony/Bundle/SecurityBundle/LICENSE | 19 + .../Resources/config/collectors.xml | 17 + .../Resources/config/security.xml | 140 + .../Resources/config/security_acl.xml | 47 + .../Resources/config/security_acl_dbal.xml | 54 + .../Resources/config/security_listeners.xml | 189 + .../Resources/config/security_rememberme.xml | 61 + .../Resources/config/templating_php.xml | 24 + .../Resources/config/templating_twig.xml | 23 + .../views/Collector/security.html.twig | 74 + .../Security/FirewallContext.php | 37 + .../SecurityBundle/Security/FirewallMap.php | 46 + .../Bundle/SecurityBundle/SecurityBundle.php | 45 + .../Templating/Helper/LogoutUrlHelper.php | 121 + .../Templating/Helper/SecurityHelper.php | 59 + .../DependencyInjection/ConfigurationTest.php | 70 + .../Fixtures/php/container1.php | 75 + .../Fixtures/php/custom_acl_provider.php | 9 + .../Fixtures/php/merge.php | 20 + .../Fixtures/php/merge_import.php | 15 + .../Fixtures/xml/container1.xml | 63 + .../Fixtures/xml/custom_acl_provider.xml | 16 + .../Fixtures/xml/merge.xml | 22 + .../Fixtures/xml/merge_import.xml | 17 + .../Fixtures/yml/container1.yml | 57 + .../Fixtures/yml/custom_acl_provider.yml | 6 + .../Fixtures/yml/merge.yml | 14 + .../Fixtures/yml/merge_import.yml | 9 + .../PhpSecurityExtensionTest.php | 25 + .../Security/Factory/AbstractFactoryTest.php | 66 + .../SecurityExtensionTest.php | 183 + .../XmlSecurityExtensionTest.php | 25 + .../YamlSecurityExtensionTest.php | 25 + .../AuthenticationCommencingTest.php | 24 + .../Controller/LoginController.php | 43 + .../CsrfFormLoginBundle.php | 18 + .../Form/UserLoginFormType.php | 98 + .../Resources/config/routing.yml | 30 + .../views/Login/after_login.html.twig | 8 + .../Resources/views/Login/login.html.twig | 12 + .../Controller/LocalizedController.php | 60 + .../Controller/LoginController.php | 51 + .../FormLoginExtension.php | 28 + .../FormLoginBundle/FormLoginBundle.php | 18 + .../Resources/config/localized_routing.yml | 29 + .../Resources/config/routing.yml | 33 + .../Resources/views/Localized/login.html.twig | 21 + .../views/Login/after_login.html.twig | 6 + .../Resources/views/Login/login.html.twig | 21 + .../Security/LocalizedFormFailureHandler.php | 33 + .../Tests/Functional/CsrfFormLoginTest.php | 132 + .../Tests/Functional/FormLoginTest.php | 103 + .../Functional/LocalizedRoutesAsPathTest.php | 97 + .../SecurityRoutingIntegrationTest.php | 84 + .../Tests/Functional/SwitchUserTest.php | 91 + .../Tests/Functional/WebTestCase.php | 67 + .../Tests/Functional/app/AppKernel.php | 113 + .../Functional/app/CsrfFormLogin/bundles.php | 8 + .../Functional/app/CsrfFormLogin/config.yml | 47 + .../app/CsrfFormLogin/routes_as_path.yml | 13 + .../Functional/app/CsrfFormLogin/routing.yml | 2 + .../app/Resources/views/base.html.twig | 13 + .../app/StandardFormLogin/bundles.php | 13 + .../app/StandardFormLogin/config.yml | 32 + .../localized_form_failure_handler.yml | 20 + .../StandardFormLogin/localized_routes.yml | 26 + .../localized_routes_with_forward.yml | 9 + .../app/StandardFormLogin/routes_as_path.yml | 13 + .../app/StandardFormLogin/routing.yml | 5 + .../app/StandardFormLogin/switchuser.yml | 14 + .../Tests/Functional/app/config/default.yml | 3 + .../Tests/Functional/app/config/framework.yml | 17 + .../Tests/Functional/app/config/twig.yml | 7 + .../Twig/Extension/LogoutUrlExtension.php | 75 + .../Bundle/SecurityBundle/composer.json | 31 + .../Symfony/Bundle/TwigBundle/CHANGELOG.md | 10 + .../CacheWarmer/TemplateCacheCacheWarmer.php | 78 + .../Bundle/TwigBundle/Command/LintCommand.php | 139 + .../Controller/ExceptionController.php | 119 + .../TwigBundle/Debug/TimedTwigEngine.php | 58 + .../Compiler/ExceptionListenerPass.php | 36 + .../Compiler/TwigEnvironmentPass.php | 44 + .../DependencyInjection/Configuration.php | 130 + .../DependencyInjection/TwigExtension.php | 121 + .../TwigBundle/Extension/ActionsExtension.php | 67 + .../TwigBundle/Extension/AssetsExtension.php | 79 + .../TwigBundle/Extension/CodeExtension.php | 97 + .../src/Symfony/Bundle/TwigBundle/LICENSE | 19 + .../TwigBundle/Loader/FilesystemLoader.php | 87 + .../Bundle/TwigBundle/Node/RenderNode.php | 44 + .../TwigBundle/Resources/config/debug.xml | 24 + .../Resources/config/schema/twig-1.0.xsd | 43 + .../TwigBundle/Resources/config/twig.xml | 94 + .../Resources/views/Exception/error.atom.twig | 1 + .../Resources/views/Exception/error.css.twig | 4 + .../Resources/views/Exception/error.html.twig | 17 + .../Resources/views/Exception/error.js.twig | 4 + .../Resources/views/Exception/error.json.twig | 1 + .../Resources/views/Exception/error.rdf.twig | 1 + .../Resources/views/Exception/error.txt.twig | 8 + .../Resources/views/Exception/error.xml.twig | 3 + .../views/Exception/exception.atom.twig | 1 + .../views/Exception/exception.css.twig | 3 + .../views/Exception/exception.html.twig | 129 + .../views/Exception/exception.js.twig | 3 + .../views/Exception/exception.json.twig | 1 + .../views/Exception/exception.rdf.twig | 1 + .../views/Exception/exception.txt.twig | 7 + .../views/Exception/exception.xml.twig | 9 + .../views/Exception/exception_full.html.twig | 9 + .../Resources/views/Exception/logs.html.twig | 7 + .../Resources/views/Exception/trace.html.twig | 22 + .../Resources/views/Exception/trace.txt.twig | 8 + .../views/Exception/traces.html.twig | 25 + .../Resources/views/Exception/traces.txt.twig | 6 + .../Resources/views/Exception/traces.xml.twig | 8 + .../Resources/views/layout.html.twig | 42 + .../Controller/ExceptionControllerTest.php | 87 + .../DependencyInjection/Fixtures/php/full.php | 21 + .../DependencyInjection/Fixtures/xml/full.xml | 16 + .../DependencyInjection/Fixtures/yml/full.yml | 15 + .../DependencyInjection/TwigExtensionTest.php | 158 + .../Tests/Loader/FilesystemLoaderTest.php | 74 + .../Bundle/TwigBundle/Tests/TestCase.php | 22 + .../TwigBundle/Tests/TwigEngineTest.php | 94 + .../TokenParser/RenderTokenParser.php | 68 + .../Symfony/Bundle/TwigBundle/TwigBundle.php | 33 + .../Symfony/Bundle/TwigBundle/TwigEngine.php | 117 + .../Symfony/Bundle/TwigBundle/composer.json | 31 + .../Bundle/WebProfilerBundle/CHANGELOG.md | 14 + .../Controller/ExceptionController.php | 45 + .../Controller/ProfilerController.php | 358 ++ .../Controller/RouterController.php | 56 + .../DependencyInjection/Configuration.php | 54 + .../WebProfilerExtension.php | 74 + .../EventListener/WebDebugToolbarListener.php | 127 + .../Symfony/Bundle/WebProfilerBundle/LICENSE | 19 + .../Resources/ICONS_LICENSE.txt | 5 + .../Resources/config/routing/profiler.xml | 49 + .../Resources/config/routing/wdt.xml | 10 + .../config/schema/webprofiler-1.0.xsd | 23 + .../Resources/config/toolbar.xml | 20 + .../Resources/public/css/profiler.css | 485 +++ .../Resources/public/favicon.ico | Bin 0 -> 1150 bytes .../Resources/public/images/close.png | Bin 0 -> 402 bytes .../Resources/public/images/config.png | Bin 0 -> 379 bytes .../Resources/public/images/db.png | Bin 0 -> 246 bytes .../Resources/public/images/events.png | Bin 0 -> 730 bytes .../Resources/public/images/exception.png | Bin 0 -> 921 bytes .../Resources/public/images/import.png | Bin 0 -> 988 bytes .../Resources/public/images/logger.png | Bin 0 -> 283 bytes .../Resources/public/images/mail.png | Bin 0 -> 568 bytes .../Resources/public/images/memory.png | Bin 0 -> 199 bytes .../public/images/profiler/bg_submenu.gif | Bin 0 -> 176 bytes .../public/images/profiler/bg_submenu.png | Bin 0 -> 114 bytes .../public/images/profiler/border_l.png | Bin 0 -> 249 bytes .../public/images/profiler/border_r.png | Bin 0 -> 253 bytes .../public/images/profiler/btn_bg.png | Bin 0 -> 87 bytes .../public/images/profiler/config.png | Bin 0 -> 379 bytes .../Resources/public/images/profiler/db.png | Bin 0 -> 358 bytes .../public/images/profiler/events.png | Bin 0 -> 1060 bytes .../public/images/profiler/exception.png | Bin 0 -> 1148 bytes .../public/images/profiler/grey_magnifier.png | Bin 0 -> 393 bytes .../public/images/profiler/input_bg.gif | Bin 0 -> 63 bytes .../public/images/profiler/logger.png | Bin 0 -> 453 bytes .../images/profiler/logo_symfony_profiler.gif | Bin 0 -> 2589 bytes .../images/profiler/logo_symfony_profiler.png | Bin 0 -> 2222 bytes .../Resources/public/images/profiler/mail.png | Bin 0 -> 1093 bytes .../public/images/profiler/request.png | Bin 0 -> 1042 bytes .../public/images/profiler/routing.png | Bin 0 -> 696 bytes .../public/images/profiler/security.png | Bin 0 -> 994 bytes .../public/images/profiler/spinner.gif | Bin 0 -> 1505 bytes .../Resources/public/images/profiler/time.png | Bin 0 -> 776 bytes .../Resources/public/images/request.png | Bin 0 -> 757 bytes .../Resources/public/images/routing.png | Bin 0 -> 337 bytes .../Resources/public/images/search.png | Bin 0 -> 785 bytes .../Resources/public/images/security.png | Bin 0 -> 808 bytes .../Resources/public/images/spacer.gif | Bin 0 -> 45 bytes .../Resources/public/images/symfony.png | Bin 0 -> 1332 bytes .../Resources/public/images/time.png | Bin 0 -> 482 bytes .../views/Collector/config.html.twig | 164 + .../views/Collector/events.html.twig | 61 + .../views/Collector/exception.html.twig | 30 + .../views/Collector/logger.html.twig | 75 + .../views/Collector/memory.html.twig | 17 + .../views/Collector/request.html.twig | 161 + .../views/Collector/router.html.twig | 15 + .../Resources/views/Collector/time.html.twig | 459 +++ .../Resources/views/Profiler/admin.html.twig | 27 + .../views/Profiler/ajax_layout.html.twig | 1 + .../Resources/views/Profiler/bag.html.twig | 16 + .../Resources/views/Profiler/base.html.twig | 16 + .../views/Profiler/base_js.html.twig | 72 + .../Resources/views/Profiler/header.html.twig | 25 + .../Resources/views/Profiler/info.html.twig | 43 + .../Resources/views/Profiler/layout.html.twig | 54 + .../views/Profiler/results.html.twig | 35 + .../Resources/views/Profiler/search.html.twig | 39 + .../Resources/views/Profiler/table.html.twig | 16 + .../views/Profiler/toolbar.html.twig | 26 + .../views/Profiler/toolbar_item.html.twig | 9 + .../views/Profiler/toolbar_js.html.twig | 18 + .../views/Profiler/toolbar_redirect.html.twig | 18 + .../views/Profiler/toolbar_style.html.twig | 270 ++ .../Resources/views/Router/panel.html.twig | 44 + .../Controller/ExceptionControllerTest.php | 89 + .../DependencyInjection/ConfigurationTest.php | 41 + .../WebProfilerExtensionTest.php | 130 + .../WebDebugToolbarListenerTest.php | 226 ++ .../WebProfilerBundle/Tests/TestCase.php | 22 + .../WebProfilerBundle/WebProfilerBundle.php | 23 + .../Bundle/WebProfilerBundle/composer.json | 31 + .../Symfony/Component/BrowserKit/CHANGELOG.md | 8 + .../Symfony/Component/BrowserKit/Client.php | 492 +++ .../Symfony/Component/BrowserKit/Cookie.php | 315 ++ .../Component/BrowserKit/CookieJar.php | 215 ++ .../Symfony/Component/BrowserKit/History.php | 110 + .../src/Symfony/Component/BrowserKit/LICENSE | 19 + .../Symfony/Component/BrowserKit/README.md | 26 + .../Symfony/Component/BrowserKit/Request.php | 138 + .../Symfony/Component/BrowserKit/Response.php | 138 + .../Component/BrowserKit/Tests/ClientTest.php | 400 +++ .../BrowserKit/Tests/CookieJarTest.php | 168 + .../Component/BrowserKit/Tests/CookieTest.php | 173 + .../BrowserKit/Tests/HistoryTest.php | 101 + .../BrowserKit/Tests/RequestTest.php | 53 + .../BrowserKit/Tests/ResponseTest.php | 76 + .../Component/BrowserKit/Tests/bootstrap.php | 22 + .../Component/BrowserKit/composer.json | 38 + .../Component/BrowserKit/phpunit.xml.dist | 30 + .../Component/ClassLoader/ApcClassLoader.php | 118 + .../ClassLoader/ApcUniversalClassLoader.php | 98 + .../Component/ClassLoader/CHANGELOG.md | 15 + .../ClassLoader/ClassCollectionLoader.php | 223 ++ .../Component/ClassLoader/ClassLoader.php | 203 ++ .../ClassLoader/ClassMapGenerator.php | 133 + .../ClassLoader/DebugClassLoader.php | 91 + .../ClassLoader/DebugUniversalClassLoader.php | 63 + .../src/Symfony/Component/ClassLoader/LICENSE | 19 + .../Component/ClassLoader/MapClassLoader.php | 76 + .../Symfony/Component/ClassLoader/README.md | 72 + .../Tests/ApcUniversalClassLoaderTest.php | 192 + .../Tests/ClassCollectionLoaderTest.php | 74 + .../ClassLoader/Tests/ClassLoaderTest.php | 163 + .../Tests/ClassMapGeneratorTest.php | 102 + .../Tests/Fixtures/Apc/Namespaced/Bar.php | 17 + .../Tests/Fixtures/Apc/Namespaced/Baz.php | 17 + .../Tests/Fixtures/Apc/Namespaced/Foo.php | 17 + .../Tests/Fixtures/Apc/Namespaced/FooBar.php | 17 + .../Tests/Fixtures/Apc/Pearlike/Bar.php | 6 + .../Tests/Fixtures/Apc/Pearlike/Baz.php | 6 + .../Tests/Fixtures/Apc/Pearlike/Foo.php | 6 + .../alpha/Apc/ApcPrefixCollision/A/Bar.php | 6 + .../alpha/Apc/ApcPrefixCollision/A/Foo.php | 6 + .../alpha/Apc/NamespaceCollision/A/Bar.php | 17 + .../alpha/Apc/NamespaceCollision/A/Foo.php | 17 + .../beta/Apc/ApcPrefixCollision/A/B/Bar.php | 6 + .../beta/Apc/ApcPrefixCollision/A/B/Foo.php | 6 + .../beta/Apc/NamespaceCollision/A/B/Bar.php | 17 + .../beta/Apc/NamespaceCollision/A/B/Foo.php | 17 + .../Apc/fallback/Apc/Pearlike/FooBar.php | 6 + .../Apc/fallback/Namespaced/FooBar.php | 17 + .../Tests/Fixtures/Namespaced/Bar.php | 17 + .../Tests/Fixtures/Namespaced/Baz.php | 17 + .../Tests/Fixtures/Namespaced/Foo.php | 17 + .../Tests/Fixtures/Namespaced2/Bar.php | 8 + .../Tests/Fixtures/Namespaced2/Baz.php | 8 + .../Tests/Fixtures/Namespaced2/Foo.php | 8 + .../Tests/Fixtures/Pearlike/Bar.php | 6 + .../Tests/Fixtures/Pearlike/Baz.php | 6 + .../Tests/Fixtures/Pearlike/Foo.php | 6 + .../Tests/Fixtures/Pearlike2/Bar.php | 6 + .../Tests/Fixtures/Pearlike2/Baz.php | 6 + .../Tests/Fixtures/Pearlike2/Foo.php | 6 + .../alpha/NamespaceCollision/A/Bar.php | 17 + .../alpha/NamespaceCollision/A/Foo.php | 17 + .../alpha/NamespaceCollision/C/Bar.php | 8 + .../alpha/NamespaceCollision/C/Foo.php | 8 + .../Fixtures/alpha/PrefixCollision/A/Bar.php | 6 + .../Fixtures/alpha/PrefixCollision/A/Foo.php | 6 + .../Fixtures/alpha/PrefixCollision/C/Bar.php | 6 + .../Fixtures/alpha/PrefixCollision/C/Foo.php | 6 + .../beta/NamespaceCollision/A/B/Bar.php | 17 + .../beta/NamespaceCollision/A/B/Foo.php | 17 + .../beta/NamespaceCollision/C/B/Bar.php | 8 + .../beta/NamespaceCollision/C/B/Foo.php | 8 + .../Fixtures/beta/PrefixCollision/A/B/Bar.php | 6 + .../Fixtures/beta/PrefixCollision/A/B/Foo.php | 6 + .../Fixtures/beta/PrefixCollision/C/B/Bar.php | 6 + .../Fixtures/beta/PrefixCollision/C/B/Foo.php | 6 + .../Tests/Fixtures/classmap/SomeClass.php | 17 + .../Tests/Fixtures/classmap/SomeInterface.php | 17 + .../Tests/Fixtures/classmap/SomeParent.php | 17 + .../Tests/Fixtures/classmap/multipleNs.php | 14 + .../Tests/Fixtures/classmap/notAClass.php | 3 + .../Tests/Fixtures/classmap/notPhpFile.md | 1 + .../classmap/sameNsMultipleClasses.php | 15 + .../Fixtures/fallback/Namespaced/FooBar.php | 17 + .../Fixtures/fallback/Namespaced2/FooBar.php | 8 + .../Fixtures/fallback/Pearlike/FooBar.php | 6 + .../Fixtures/fallback/Pearlike2/FooBar.php | 6 + .../Tests/Fixtures/includepath/Foo.php | 5 + .../Tests/Fixtures/php5.4/traits.php | 30 + .../Tests/UniversalClassLoaderTest.php | 196 ++ .../Component/ClassLoader/Tests/bootstrap.php | 22 + .../ClassLoader/UniversalClassLoader.php | 319 ++ .../ClassLoader/XcacheClassLoader.php | 121 + .../Component/ClassLoader/composer.json | 33 + .../Component/ClassLoader/phpunit.xml.dist | 30 + .../src/Symfony/Component/Config/CHANGELOG.md | 10 + .../Symfony/Component/Config/ConfigCache.php | 117 + .../Component/Config/Definition/ArrayNode.php | 363 ++ .../Component/Config/Definition/BaseNode.php | 337 ++ .../Config/Definition/BooleanNode.php | 39 + .../Builder/ArrayNodeDefinition.php | 419 +++ .../Builder/BooleanNodeDefinition.php | 43 + .../Definition/Builder/EnumNodeDefinition.php | 41 + .../Config/Definition/Builder/ExprBuilder.php | 229 ++ .../Definition/Builder/MergeBuilder.php | 74 + .../Config/Definition/Builder/NodeBuilder.php | 219 ++ .../Definition/Builder/NodeDefinition.php | 343 ++ .../Builder/NodeParentInterface.php | 21 + .../Builder/NormalizationBuilder.php | 70 + .../Builder/ParentNodeDefinitionInterface.php | 26 + .../Builder/ScalarNodeDefinition.php | 32 + .../Config/Definition/Builder/TreeBuilder.php | 59 + .../Definition/Builder/ValidationBuilder.php | 53 + .../Builder/VariableNodeDefinition.php | 68 + .../Definition/ConfigurationInterface.php | 27 + .../Component/Config/Definition/EnumNode.php | 50 + .../Exception/DuplicateKeyException.php | 22 + .../Config/Definition/Exception/Exception.php | 21 + .../Exception/ForbiddenOverwriteException.php | 22 + .../InvalidConfigurationException.php | 33 + .../Exception/InvalidDefinitionException.php | 21 + .../Exception/InvalidTypeException.php | 21 + .../Exception/UnsetKeyException.php | 22 + .../Config/Definition/NodeInterface.php | 87 + .../Component/Config/Definition/Processor.php | 127 + .../Definition/PrototypeNodeInterface.php | 27 + .../Config/Definition/PrototypedArrayNode.php | 342 ++ .../Config/Definition/ScalarNode.php | 47 + .../Config/Definition/VariableNode.php | 114 + ...LoaderImportCircularReferenceException.php | 27 + .../Exception/FileLoaderLoadException.php | 78 + .../Symfony/Component/Config/FileLocator.php | 99 + .../Component/Config/FileLocatorInterface.php | 31 + .../src/Symfony/Component/Config/LICENSE | 19 + .../Config/Loader/DelegatingLoader.php | 62 + .../Component/Config/Loader/FileLoader.php | 93 + .../Component/Config/Loader/Loader.php | 80 + .../Config/Loader/LoaderInterface.php | 53 + .../Config/Loader/LoaderResolver.php | 81 + .../Config/Loader/LoaderResolverInterface.php | 30 + .../src/Symfony/Component/Config/README.md | 14 + .../Config/Resource/DirectoryResource.php | 102 + .../Config/Resource/FileResource.php | 80 + .../Config/Resource/ResourceInterface.php | 43 + .../Config/Tests/Definition/ArrayNodeTest.php | 57 + .../Tests/Definition/BooleanNodeTest.php | 61 + .../Builder/ArrayNodeDefinitionTest.php | 159 + .../Builder/EnumNodeDefinitionTest.php | 37 + .../Definition/Builder/NodeBuilderTest.php | 83 + .../Definition/Builder/TreeBuilderTest.php | 127 + .../Config/Tests/Definition/EnumNodeTest.php | 41 + .../Tests/Definition/FinalizationTest.php | 73 + .../Config/Tests/Definition/MergeTest.php | 195 ++ .../Tests/Definition/NormalizationTest.php | 210 ++ .../Config/Tests/Definition/ProcessorTest.php | 51 + .../Definition/PrototypedArrayNodeTest.php | 181 + .../Tests/Definition/ScalarNodeTest.php | 60 + .../Config/Tests/FileLocatorTest.php | 107 + .../Config/Tests/Fixtures/Again/foo.xml | 0 .../Fixtures/Builder/BarNodeDefinition.php | 21 + .../Tests/Fixtures/Builder/NodeBuilder.php | 34 + .../Builder/VariableNodeDefinition.php | 18 + .../Component/Config/Tests/Fixtures/foo.xml | 0 .../Tests/Loader/DelegatingLoaderTest.php | 83 + .../Tests/Loader/LoaderResolverTest.php | 56 + .../Config/Tests/Loader/LoaderTest.php | 74 + .../Tests/Resource/DirectoryResourceTest.php | 171 + .../Tests/Resource/FileResourceTest.php | 52 + .../Component/Config/Tests/bootstrap.php | 18 + .../Symfony/Component/Config/composer.json | 30 + .../Symfony/Component/Config/phpunit.xml.dist | 30 + .../Symfony/Component/Console/Application.php | 1080 ++++++ .../Symfony/Component/Console/CHANGELOG.md | 19 + .../Component/Console/Command/Command.php | 614 ++++ .../Component/Console/Command/HelpCommand.php | 84 + .../Component/Console/Command/ListCommand.php | 87 + .../Console/Formatter/OutputFormatter.php | 230 ++ .../Formatter/OutputFormatterInterface.php | 83 + .../Formatter/OutputFormatterStyle.php | 218 ++ .../OutputFormatterStyleInterface.php | 72 + .../Formatter/OutputFormatterStyleStack.php | 121 + .../Component/Console/Helper/DialogHelper.php | 141 + .../Console/Helper/FormatterHelper.php | 99 + .../Component/Console/Helper/Helper.php | 42 + .../Console/Helper/HelperInterface.php | 49 + .../Component/Console/Helper/HelperSet.php | 104 + .../Component/Console/Input/ArgvInput.php | 313 ++ .../Component/Console/Input/ArrayInput.php | 190 + .../Symfony/Component/Console/Input/Input.php | 211 ++ .../Component/Console/Input/InputArgument.php | 132 + .../Console/Input/InputDefinition.php | 535 +++ .../Console/Input/InputInterface.php | 152 + .../Component/Console/Input/InputOption.php | 209 ++ .../Component/Console/Input/StringInput.php | 81 + .../src/Symfony/Component/Console/LICENSE | 19 + .../Console/Output/ConsoleOutput.php | 104 + .../Console/Output/ConsoleOutputInterface.php | 30 + .../Component/Console/Output/NullOutput.php | 34 + .../Component/Console/Output/Output.php | 180 + .../Console/Output/OutputInterface.php | 109 + .../Component/Console/Output/StreamOutput.php | 113 + .../src/Symfony/Component/Console/README.md | 55 + .../src/Symfony/Component/Console/Shell.php | 207 ++ .../Console/Tester/ApplicationTester.php | 104 + .../Console/Tester/CommandTester.php | 102 + .../Console/Tests/ApplicationTest.php | 470 +++ .../Console/Tests/Command/CommandTest.php | 253 ++ .../Console/Tests/Command/HelpCommandTest.php | 42 + .../Console/Tests/Command/ListCommandTest.php | 38 + .../Console/Tests/Fixtures/Foo1Command.php | 26 + .../Console/Tests/Fixtures/Foo2Command.php | 21 + .../Console/Tests/Fixtures/Foo3Command.php | 25 + .../Console/Tests/Fixtures/FooCommand.php | 33 + .../Console/Tests/Fixtures/TestCommand.php | 28 + .../Tests/Fixtures/application_astext1.txt | 20 + .../Tests/Fixtures/application_astext2.txt | 16 + .../Tests/Fixtures/application_asxml1.txt | 83 + .../Tests/Fixtures/application_asxml2.txt | 15 + .../Tests/Fixtures/application_gethelp.txt | 13 + .../Fixtures/application_renderexception1.txt | 8 + .../Fixtures/application_renderexception2.txt | 11 + .../Fixtures/application_renderexception3.txt | 19 + .../Fixtures/application_renderexception4.txt | 9 + .../Tests/Fixtures/application_run1.txt | 17 + .../Tests/Fixtures/application_run2.txt | 26 + .../Tests/Fixtures/application_run3.txt | 27 + .../Tests/Fixtures/application_run4.txt | 1 + .../Console/Tests/Fixtures/command_astext.txt | 18 + .../Console/Tests/Fixtures/command_asxml.txt | 38 + .../Tests/Fixtures/definition_astext.txt | 11 + .../Tests/Fixtures/definition_asxml.txt | 39 + .../OutputFormatterStyleStackTest.php | 70 + .../Formatter/OutputFormatterStyleTest.php | 77 + .../Tests/Formatter/OutputFormatterTest.php | 191 + .../Console/Tests/Helper/DialogHelperTest.php | 93 + .../Tests/Helper/FormatterHelperTest.php | 71 + .../Console/Tests/Input/ArgvInputTest.php | 217 ++ .../Console/Tests/Input/ArrayInputTest.php | 90 + .../Console/Tests/Input/InputArgumentTest.php | 104 + .../Tests/Input/InputDefinitionTest.php | 364 ++ .../Console/Tests/Input/InputOptionTest.php | 192 + .../Console/Tests/Input/InputTest.php | 117 + .../Console/Tests/Input/StringInputTest.php | 58 + .../Tests/Output/ConsoleOutputTest.php | 24 + .../Console/Tests/Output/NullOutputTest.php | 24 + .../Console/Tests/Output/OutputTest.php | 101 + .../Console/Tests/Output/StreamOutputTest.php | 59 + .../Tests/Tester/ApplicationTesterTest.php | 64 + .../Tests/Tester/CommandTesterTest.php | 62 + .../Component/Console/Tests/bootstrap.php | 18 + .../Symfony/Component/Console/composer.json | 30 + .../Component/Console/phpunit.xml.dist | 30 + .../Component/CssSelector/CHANGELOG.md | 7 + .../Component/CssSelector/CssSelector.php | 322 ++ .../CssSelector/Exception/ParseException.php | 24 + .../src/Symfony/Component/CssSelector/LICENSE | 19 + .../Component/CssSelector/Node/AttribNode.php | 131 + .../Component/CssSelector/Node/ClassNode.php | 59 + .../CssSelector/Node/CombinedSelectorNode.php | 142 + .../CssSelector/Node/ElementNode.php | 77 + .../CssSelector/Node/FunctionNode.php | 290 ++ .../Component/CssSelector/Node/HashNode.php | 59 + .../CssSelector/Node/NodeInterface.php | 37 + .../Component/CssSelector/Node/OrNode.php | 58 + .../Component/CssSelector/Node/PseudoNode.php | 228 ++ .../Symfony/Component/CssSelector/README.md | 23 + .../CssSelector/Tests/CssSelectorTest.php | 71 + .../CssSelector/Tests/Node/AttribNodeTest.php | 43 + .../CssSelector/Tests/Node/ClassNodeTest.php | 27 + .../Tests/Node/CombinedSelectorNodeTest.php | 36 + .../Tests/Node/ElementNodeTest.php | 30 + .../Tests/Node/FunctionNodeTest.php | 96 + .../CssSelector/Tests/Node/HashNodeTest.php | 27 + .../CssSelector/Tests/Node/OrNodeTest.php | 43 + .../CssSelector/Tests/Node/PseudoNodeTest.php | 55 + .../CssSelector/Tests/TokenizerTest.php | 71 + .../CssSelector/Tests/XPathExprTest.php | 35 + .../Component/CssSelector/Tests/bootstrap.php | 18 + .../Symfony/Component/CssSelector/Token.php | 73 + .../Component/CssSelector/TokenStream.php | 105 + .../Component/CssSelector/Tokenizer.php | 201 ++ .../Component/CssSelector/XPathExpr.php | 254 ++ .../Component/CssSelector/XPathExprOr.php | 54 + .../Component/CssSelector/composer.json | 30 + .../Component/CssSelector/phpunit.xml.dist | 30 + .../Component/DependencyInjection/Alias.php | 71 + .../DependencyInjection/CHANGELOG.md | 12 + .../Compiler/AnalyzeServiceReferencesPass.php | 140 + .../Compiler/CheckCircularReferencesPass.php | 70 + .../Compiler/CheckDefinitionValidityPass.php | 79 + ...xceptionOnInvalidReferenceBehaviorPass.php | 64 + .../Compiler/CheckReferenceValidityPass.php | 167 + .../DependencyInjection/Compiler/Compiler.php | 122 + .../Compiler/CompilerPassInterface.php | 33 + .../Compiler/InlineServiceDefinitionsPass.php | 137 + .../Compiler/LoggingFormatter.php | 46 + .../MergeExtensionConfigurationPass.php | 51 + .../Compiler/PassConfig.php | 259 ++ .../RemoveAbstractDefinitionsPass.php | 39 + .../Compiler/RemovePrivateAliasesPass.php | 44 + .../Compiler/RemoveUnusedDefinitionsPass.php | 84 + .../Compiler/RepeatablePassInterface.php | 28 + .../Compiler/RepeatedPass.php | 80 + .../ReplaceAliasByActualDefinitionPass.php | 116 + .../ResolveDefinitionTemplatesPass.php | 148 + .../Compiler/ResolveInvalidReferencesPass.php | 103 + .../ResolveParameterPlaceHoldersPass.php | 61 + .../ResolveReferencesToAliasesPass.php | 93 + .../Compiler/ServiceReferenceGraph.php | 117 + .../Compiler/ServiceReferenceGraphEdge.php | 70 + .../Compiler/ServiceReferenceGraphNode.php | 124 + .../DependencyInjection/Container.php | 467 +++ .../DependencyInjection/ContainerAware.php | 41 + .../ContainerAwareInterface.php | 31 + .../DependencyInjection/ContainerBuilder.php | 867 +++++ .../ContainerInterface.php | 154 + .../DependencyInjection/Definition.php | 655 ++++ .../DefinitionDecorator.php | 205 ++ .../DependencyInjection/Dumper/Dumper.php | 38 + .../Dumper/DumperInterface.php | 33 + .../Dumper/GraphvizDumper.php | 273 ++ .../DependencyInjection/Dumper/PhpDumper.php | 1136 ++++++ .../DependencyInjection/Dumper/XmlDumper.php | 301 ++ .../DependencyInjection/Dumper/YamlDumper.php | 295 ++ .../Exception/BadMethodCallException.php | 19 + .../Exception/ExceptionInterface.php | 22 + .../Exception/InactiveScopeException.php | 41 + .../Exception/InvalidArgumentException.php | 21 + .../Exception/LogicException.php | 19 + .../Exception/OutOfBoundsException.php | 19 + .../ParameterCircularReferenceException.php | 34 + .../Exception/ParameterNotFoundException.php | 80 + .../Exception/RuntimeException.php | 21 + .../ScopeCrossingInjectionException.php | 65 + .../ScopeWideningInjectionException.php | 64 + .../ServiceCircularReferenceException.php | 41 + .../Exception/ServiceNotFoundException.php | 47 + .../ConfigurationExtensionInterface.php | 32 + .../Extension/ExtensionInterface.php | 65 + .../IntrospectableContainerInterface.php | 33 + .../Component/DependencyInjection/LICENSE | 19 + .../Loader/ClosureLoader.php | 61 + .../DependencyInjection/Loader/FileLoader.php | 39 + .../Loader/IniFileLoader.php | 62 + .../Loader/PhpFileLoader.php | 57 + .../Loader/XmlFileLoader.php | 499 +++ .../Loader/YamlFileLoader.php | 331 ++ .../schema/dic/services/services-1.0.xsd | 183 + .../DependencyInjection/Parameter.php | 44 + .../ParameterBag/FrozenParameterBag.php | 72 + .../ParameterBag/ParameterBag.php | 273 ++ .../ParameterBag/ParameterBagInterface.php | 97 + .../Component/DependencyInjection/README.md | 76 + .../DependencyInjection/Reference.php | 72 + .../Component/DependencyInjection/Scope.php | 50 + .../DependencyInjection/ScopeInterface.php | 32 + .../DependencyInjection/SimpleXMLElement.php | 127 + .../TaggedContainerInterface.php | 33 + .../AnalyzeServiceReferencesPassTest.php | 107 + .../CheckCircularReferencesPassTest.php | 85 + .../CheckDefinitionValidityPassTest.php | 69 + ...tionOnInvalidReferenceBehaviorPassTest.php | 71 + .../CheckReferenceValidityPassTest.php | 98 + .../InlineServiceDefinitionsPassTest.php | 134 + .../Tests/Compiler/IntegrationTest.php | 118 + .../RemoveUnusedDefinitionsPassTest.php | 89 + ...ReplaceAliasByActualDefinitionPassTest.php | 49 + .../ResolveDefinitionTemplatesPassTest.php | 151 + .../ResolveInvalidReferencesPassTest.php | 69 + .../ResolveReferencesToAliasesPassTest.php | 56 + .../Tests/ContainerBuilderTest.php | 554 +++ .../Tests/ContainerTest.php | 450 +++ .../Tests/CrossCheckTest.php | 97 + .../Tests/DefinitionDecoratorTest.php | 110 + .../Tests/DefinitionTest.php | 292 ++ .../Tests/Dumper/GraphvizDumperTest.php | 58 + .../Tests/Dumper/PhpDumperTest.php | 130 + .../Tests/Dumper/XmlDumperTest.php | 110 + .../Tests/Dumper/YamlDumperTest.php | 66 + .../Tests/Fixtures/containers/container10.php | 14 + .../Tests/Fixtures/containers/container11.php | 12 + .../Tests/Fixtures/containers/container12.php | 13 + .../Tests/Fixtures/containers/container8.php | 13 + .../Tests/Fixtures/containers/container9.php | 58 + .../Tests/Fixtures/containers/interfaces1.php | 25 + .../Tests/Fixtures/containers/interfaces2.php | 34 + .../Tests/Fixtures/graphviz/services1.dot | 7 + .../Tests/Fixtures/graphviz/services10-1.dot | 10 + .../Tests/Fixtures/graphviz/services10.dot | 10 + .../Tests/Fixtures/graphviz/services9.dot | 25 + .../Fixtures/includes/ProjectExtension.php | 41 + .../includes/ProjectWithXsdExtension.php | 19 + .../ProjectWithXsdExtensionInPhar.phar | Bin 0 -> 1138 bytes .../Tests/Fixtures/includes/classes.php | 42 + .../Tests/Fixtures/includes/createphar.php | 47 + .../Tests/Fixtures/includes/foo.php | 36 + .../Fixtures/includes/schema/project-1.0.xsd | 13 + .../Tests/Fixtures/ini/nonvalid.ini | 2 + .../Tests/Fixtures/ini/parameters.ini | 3 + .../Tests/Fixtures/ini/parameters1.ini | 3 + .../Tests/Fixtures/ini/parameters2.ini | 2 + .../Tests/Fixtures/php/services1-1.php | 28 + .../Tests/Fixtures/php/services1.php | 28 + .../Tests/Fixtures/php/services10.php | 104 + .../Tests/Fixtures/php/services8.php | 52 + .../Tests/Fixtures/php/services9.php | 160 + .../Tests/Fixtures/php/simple.php | 3 + .../Fixtures/xml/extension1/services.xml | 14 + .../Fixtures/xml/extension2/services.xml | 14 + .../Fixtures/xml/extensions/services1.xml | 19 + .../Fixtures/xml/extensions/services2.xml | 19 + .../Fixtures/xml/extensions/services3.xml | 19 + .../Fixtures/xml/extensions/services4.xml | 6 + .../Fixtures/xml/extensions/services5.xml | 11 + .../Fixtures/xml/extensions/services6.xml | 11 + .../Fixtures/xml/extensions/services7.xml | 11 + .../Tests/Fixtures/xml/nonvalid.xml | 3 + .../Tests/Fixtures/xml/services1.xml | 2 + .../Tests/Fixtures/xml/services13.xml | 9 + .../Tests/Fixtures/xml/services2.xml | 31 + .../Tests/Fixtures/xml/services3.xml | 13 + .../Tests/Fixtures/xml/services4.xml | 13 + .../Fixtures/xml/services4_bad_import.xml | 9 + .../Tests/Fixtures/xml/services5.xml | 21 + .../Tests/Fixtures/xml/services6.xml | 50 + .../Tests/Fixtures/xml/services7.xml | 9 + .../Tests/Fixtures/xml/services8.xml | 21 + .../Tests/Fixtures/xml/services9.xml | 56 + .../Tests/Fixtures/yaml/badtag1.yml | 5 + .../Tests/Fixtures/yaml/badtag2.yml | 6 + .../Tests/Fixtures/yaml/badtag3.yml | 6 + .../Tests/Fixtures/yaml/nonvalid1.yml | 2 + .../Tests/Fixtures/yaml/nonvalid2.yml | 1 + .../Tests/Fixtures/yaml/services1.yml | 1 + .../Tests/Fixtures/yaml/services10.yml | 9 + .../Tests/Fixtures/yaml/services11.yml | 1 + .../Tests/Fixtures/yaml/services13.yml | 3 + .../Tests/Fixtures/yaml/services2.yml | 11 + .../Tests/Fixtures/yaml/services3.yml | 5 + .../Tests/Fixtures/yaml/services4.yml | 6 + .../Fixtures/yaml/services4_bad_import.yml | 2 + .../Tests/Fixtures/yaml/services6.yml | 26 + .../Tests/Fixtures/yaml/services7.yml | 2 + .../Tests/Fixtures/yaml/services8.yml | 6 + .../Tests/Fixtures/yaml/services9.yml | 43 + .../Tests/Loader/ClosureLoaderTest.php | 50 + .../Tests/Loader/IniFileLoaderTest.php | 90 + .../Tests/Loader/PhpFileLoaderTest.php | 50 + .../Tests/Loader/XmlFileLoaderTest.php | 331 ++ .../Tests/Loader/YamlFileLoaderTest.php | 211 ++ .../ParameterBag/FrozenParameterBagTest.php | 60 + .../Tests/ParameterBag/ParameterBagTest.php | 228 ++ .../Tests/ParameterTest.php | 26 + .../Tests/ReferenceTest.php | 32 + .../DependencyInjection/Tests/bootstrap.php | 22 + .../DependencyInjection/Variable.php | 50 + .../DependencyInjection/composer.json | 38 + .../DependencyInjection/phpunit.xml.dist | 30 + .../Symfony/Component/DomCrawler/CHANGELOG.md | 12 + .../Symfony/Component/DomCrawler/Crawler.php | 721 ++++ .../DomCrawler/Field/ChoiceFormField.php | 307 ++ .../DomCrawler/Field/FileFormField.php | 96 + .../Component/DomCrawler/Field/FormField.php | 122 + .../DomCrawler/Field/InputFormField.php | 47 + .../DomCrawler/Field/TextareaFormField.php | 39 + .../src/Symfony/Component/DomCrawler/Form.php | 586 ++++ .../src/Symfony/Component/DomCrawler/LICENSE | 19 + .../src/Symfony/Component/DomCrawler/Link.php | 157 + .../Symfony/Component/DomCrawler/README.md | 35 + .../DomCrawler/Tests/CrawlerTest.php | 595 ++++ .../Tests/Field/ChoiceFormFieldTest.php | 329 ++ .../Tests/Field/FileFormFieldTest.php | 87 + .../DomCrawler/Tests/Field/FormFieldTest.php | 38 + .../Tests/Field/FormFieldTestCase.php | 27 + .../Tests/Field/InputFormFieldTest.php | 49 + .../Tests/Field/TextareaFormFieldTest.php | 33 + .../Component/DomCrawler/Tests/FormTest.php | 671 ++++ .../Component/DomCrawler/Tests/LinkTest.php | 104 + .../Component/DomCrawler/Tests/bootstrap.php | 22 + .../Component/DomCrawler/composer.json | 36 + .../Component/DomCrawler/phpunit.xml.dist | 30 + .../Component/EventDispatcher/CHANGELOG.md | 16 + .../ContainerAwareEventDispatcher.php | 200 ++ .../TraceableEventDispatcherInterface.php | 32 + .../Component/EventDispatcher/Event.php | 121 + .../EventDispatcher/EventDispatcher.php | 185 + .../EventDispatcherInterface.php | 96 + .../EventSubscriberInterface.php | 50 + .../EventDispatcher/GenericEvent.php | 180 + .../Symfony/Component/EventDispatcher/LICENSE | 19 + .../Component/EventDispatcher/README.md | 28 + .../ContainerAwareEventDispatcherTest.php | 257 ++ .../Tests/EventDispatcherTest.php | 297 ++ .../EventDispatcher/Tests/EventTest.php | 85 + .../Tests/GenericEventTest.php | 131 + .../Tests/UnmodifiableEventDispatcherTest.php | 106 + .../EventDispatcher/Tests/bootstrap.php | 22 + .../UnmodifiableEventDispatcher.php | 92 + .../Component/EventDispatcher/composer.json | 37 + .../EventDispatcher/phpunit.xml.dist | 30 + .../Symfony/Component/Filesystem/CHANGELOG.md | 8 + .../Exception/ExceptionInterface.php | 24 + .../Filesystem/Exception/IOException.php | 24 + .../Component/Filesystem/Filesystem.php | 400 +++ .../src/Symfony/Component/Filesystem/LICENSE | 19 + .../Symfony/Component/Filesystem/README.md | 43 + .../Filesystem/Tests/FilesystemTest.php | 858 +++++ .../Component/Filesystem/Tests/bootstrap.php | 18 + .../Component/Filesystem/composer.json | 30 + .../Component/Filesystem/phpunit.xml.dist | 28 + .../src/Symfony/Component/Finder/CHANGELOG.md | 14 + .../Finder/Comparator/Comparator.php | 94 + .../Finder/Comparator/DateComparator.php | 54 + .../Finder/Comparator/NumberComparator.php | 82 + .../src/Symfony/Component/Finder/Finder.php | 632 ++++ .../src/Symfony/Component/Finder/Glob.php | 103 + .../Finder/Iterator/CustomFilterIterator.php | 61 + .../Iterator/DateRangeFilterIterator.php | 58 + .../Iterator/DepthRangeFilterIterator.php | 67 + .../ExcludeDirectoryFilterIterator.php | 56 + .../Iterator/FileTypeFilterIterator.php | 55 + .../Iterator/FilecontentFilterIterator.php | 76 + .../Iterator/FilenameFilterIterator.php | 68 + .../Iterator/MultiplePcreFilterIterator.php | 80 + .../Iterator/RecursiveDirectoryIterator.php | 41 + .../Iterator/SizeRangeFilterIterator.php | 57 + .../Finder/Iterator/SortableIterator.php | 80 + .../src/Symfony/Component/Finder/LICENSE | 19 + .../src/Symfony/Component/Finder/README.md | 38 + .../Symfony/Component/Finder/SplFileInfo.php | 75 + .../Tests/Comparator/ComparatorTest.php | 64 + .../Tests/Comparator/DateComparatorTest.php | 64 + .../Tests/Comparator/NumberComparatorTest.php | 109 + .../Component/Finder/Tests/FinderTest.php | 444 +++ .../Component/Finder/Tests/Fixtures/dolor.txt | 2 + .../Component/Finder/Tests/Fixtures/ipsum.txt | 2 + .../Component/Finder/Tests/Fixtures/lorem.txt | 2 + .../Component/Finder/Tests/GlobTest.php | 47 + .../Iterator/CustomFilterIteratorTest.php | 46 + .../Iterator/DateRangeFilterIteratorTest.php | 39 + .../Tests/Iterator/DepthRangeIteratorTest.php | 49 + .../ExcludeDirectoryFileIteratorTest.php | 58 + .../Iterator/FileTypeFilterIteratorTest.php | 55 + .../FilecontentFilterIteratorTest.php | 193 + .../Iterator/FilenameFilterIteratorTest.php | 55 + .../Finder/Tests/Iterator/Iterator.php | 56 + .../Tests/Iterator/IteratorTestCase.php | 32 + .../MultiplePcreFilterIteratorTest.php | 65 + .../Tests/Iterator/RealIteratorTestCase.php | 64 + .../Iterator/SizeRangeFilterIteratorTest.php | 60 + .../Tests/Iterator/SortableIteratorTest.php | 48 + .../Component/Finder/Tests/bootstrap.php | 18 + .../Symfony/Component/Finder/composer.json | 30 + .../Symfony/Component/Finder/phpunit.xml.dist | 29 + .../Component/Form/AbstractExtension.php | 195 ++ .../Symfony/Component/Form/AbstractType.php | 121 + .../Component/Form/AbstractTypeExtension.php | 76 + .../src/Symfony/Component/Form/CHANGELOG.md | 141 + .../Component/Form/CallbackTransformer.php | 70 + .../Component/Form/CallbackValidator.php | 40 + .../Component/Form/DataMapperInterface.php | 38 + .../Form/DataTransformerInterface.php | 77 + .../Component/Form/Event/DataEvent.php | 69 + .../Component/Form/Event/FilterDataEvent.php | 22 + .../Form/Exception/AlreadyBoundException.php | 16 + .../Exception/CircularReferenceException.php | 22 + .../Form/Exception/CreationException.php | 21 + .../Form/Exception/ErrorMappingException.php | 16 + .../Form/Exception/FormException.php | 16 + .../InvalidConfigurationException.php | 16 + .../Exception/InvalidPropertyException.php | 16 + .../InvalidPropertyPathException.php | 16 + .../Exception/NotInitializedException.php | 16 + .../Form/Exception/NotValidException.php | 16 + .../PropertyAccessDeniedException.php | 16 + .../Form/Exception/StringCastException.php | 16 + .../TransformationFailedException.php | 21 + .../Exception/TypeDefinitionException.php | 21 + .../Form/Exception/TypeLoaderException.php | 16 + .../Exception/UnexpectedTypeException.php | 20 + .../Extension/Core/ChoiceList/ChoiceList.php | 498 +++ .../Core/ChoiceList/ChoiceListInterface.php | 135 + .../Core/ChoiceList/LazyChoiceList.php | 149 + .../Core/ChoiceList/ObjectChoiceList.php | 175 + .../Core/ChoiceList/SimpleChoiceList.php | 166 + .../Form/Extension/Core/CoreExtension.php | 56 + .../Core/DataMapper/PropertyPathMapper.php | 72 + .../ArrayToPartsTransformer.php | 87 + .../BaseDateTimeTransformer.php | 52 + .../BooleanToStringTransformer.php | 85 + .../ChoiceToBooleanArrayTransformer.php | 106 + .../ChoiceToValueTransformer.php | 63 + .../ChoicesToBooleanArrayTransformer.php | 115 + .../ChoicesToValuesTransformer.php | 82 + .../DataTransformer/DataTransformerChain.php | 87 + .../DateTimeToArrayTransformer.php | 182 + .../DateTimeToLocalizedStringTransformer.php | 164 + .../DateTimeToStringTransformer.php | 118 + .../DateTimeToTimestampTransformer.php | 89 + .../IntegerToLocalizedStringTransformer.php | 54 + .../MoneyToLocalizedStringTransformer.php | 90 + .../NumberToLocalizedStringTransformer.php | 142 + .../PercentToLocalizedStringTransformer.php | 147 + .../ValueToDuplicatesTransformer.php | 92 + .../ValueToStringTransformer.php | 67 + .../FixCheckboxInputListener.php | 51 + .../EventListener/FixRadioInputListener.php | 51 + .../EventListener/FixUrlProtocolListener.php | 45 + .../EventListener/MergeCollectionListener.php | 126 + .../Core/EventListener/ResizeFormListener.php | 158 + .../Core/EventListener/TrimListener.php | 38 + .../Form/Extension/Core/Type/BirthdayType.php | 44 + .../Form/Extension/Core/Type/CheckboxType.php | 75 + .../Form/Extension/Core/Type/ChoiceType.php | 227 ++ .../Extension/Core/Type/CollectionType.php | 93 + .../Form/Extension/Core/Type/CountryType.php | 45 + .../Form/Extension/Core/Type/DateTimeType.php | 212 ++ .../Form/Extension/Core/Type/DateType.php | 249 ++ .../Form/Extension/Core/Type/EmailType.php | 33 + .../Form/Extension/Core/Type/FieldType.php | 32 + .../Form/Extension/Core/Type/FileType.php | 67 + .../Form/Extension/Core/Type/FormType.php | 234 ++ .../Form/Extension/Core/Type/HiddenType.php | 48 + .../Form/Extension/Core/Type/IntegerType.php | 76 + .../Form/Extension/Core/Type/LanguageType.php | 45 + .../Form/Extension/Core/Type/LocaleType.php | 45 + .../Form/Extension/Core/Type/MoneyType.php | 117 + .../Form/Extension/Core/Type/NumberType.php | 74 + .../Form/Extension/Core/Type/PasswordType.php | 57 + .../Form/Extension/Core/Type/PercentType.php | 63 + .../Form/Extension/Core/Type/RadioType.php | 33 + .../Form/Extension/Core/Type/RepeatedType.php | 64 + .../Form/Extension/Core/Type/SearchType.php | 33 + .../Form/Extension/Core/Type/TextType.php | 56 + .../Form/Extension/Core/Type/TextareaType.php | 43 + .../Form/Extension/Core/Type/TimeType.php | 208 ++ .../Form/Extension/Core/Type/TimezoneType.php | 86 + .../Form/Extension/Core/Type/UrlType.php | 54 + .../Form/Extension/Core/View/ChoiceView.php | 66 + .../Form/Extension/Csrf/CsrfExtension.php | 44 + .../CsrfProvider/CsrfProviderInterface.php | 49 + .../Csrf/CsrfProvider/DefaultCsrfProvider.php | 74 + .../Csrf/CsrfProvider/SessionCsrfProvider.php | 55 + .../EventListener/CsrfValidationListener.php | 76 + .../Csrf/Type/FormTypeCsrfExtension.php | 96 + .../DependencyInjectionExtension.php | 89 + .../Extension/Validator/Constraints/Form.php | 33 + .../Validator/Constraints/FormValidator.php | 174 + .../EventListener/ValidationListener.php | 68 + .../Type/FormTypeValidatorExtension.php | 104 + .../Type/RepeatedTypeValidatorExtension.php | 45 + .../Extension/Validator/Util/ServerParams.php | 68 + .../Validator/ValidatorExtension.php | 45 + .../Validator/ValidatorTypeGuesser.php | 318 ++ .../Validator/ViolationMapper/MappingRule.php | 107 + .../ViolationMapper/RelativePath.php | 45 + .../ViolationMapper/ViolationMapper.php | 311 ++ .../ViolationMapperInterface.php | 33 + .../ViolationMapper/ViolationPath.php | 267 ++ .../ViolationMapper/ViolationPathIterator.php | 31 + .../src/Symfony/Component/Form/Form.php | 1074 ++++++ .../Symfony/Component/Form/FormBuilder.php | 280 ++ .../Component/Form/FormBuilderInterface.php | 116 + .../src/Symfony/Component/Form/FormConfig.php | 695 ++++ .../Form/FormConfigEditorInterface.php | 219 ++ .../Component/Form/FormConfigInterface.php | 198 ++ .../src/Symfony/Component/Form/FormError.php | 97 + .../src/Symfony/Component/Form/FormEvent.php | 21 + .../src/Symfony/Component/Form/FormEvents.php | 50 + .../Component/Form/FormExtensionInterface.php | 63 + .../Symfony/Component/Form/FormFactory.php | 354 ++ .../Component/Form/FormFactoryInterface.php | 144 + .../Symfony/Component/Form/FormInterface.php | 246 ++ .../Form/FormTypeExtensionInterface.php | 75 + .../Component/Form/FormTypeGuesserChain.php | 114 + .../Form/FormTypeGuesserInterface.php | 76 + .../Component/Form/FormTypeInterface.php | 121 + .../Component/Form/FormValidatorInterface.php | 28 + .../src/Symfony/Component/Form/FormView.php | 301 ++ .../Component/Form/FormViewInterface.php | 150 + .../Symfony/Component/Form/Guess/Guess.php | 113 + .../Component/Form/Guess/TypeGuess.php | 70 + .../Component/Form/Guess/ValueGuess.php | 50 + .../src/Symfony/Component/Form/LICENSE | 19 + .../src/Symfony/Component/Form/README.md | 29 + .../Form/Resources/config/validation.xml | 13 + .../Resources/translations/validators.ca.xlf | 19 + .../Resources/translations/validators.cs.xlf | 19 + .../Resources/translations/validators.da.xlf | 19 + .../Resources/translations/validators.de.xlf | 19 + .../Resources/translations/validators.en.xlf | 19 + .../Resources/translations/validators.es.xlf | 19 + .../Resources/translations/validators.et.xlf | 19 + .../Resources/translations/validators.eu.xlf | 19 + .../Resources/translations/validators.fa.xlf | 19 + .../Resources/translations/validators.fi.xlf | 19 + .../Resources/translations/validators.fr.xlf | 19 + .../Resources/translations/validators.he.xlf | 19 + .../Resources/translations/validators.hr.xlf | 19 + .../Resources/translations/validators.hu.xlf | 19 + .../Resources/translations/validators.hy.xlf | 19 + .../Resources/translations/validators.id.xlf | 19 + .../Resources/translations/validators.it.xlf | 19 + .../Resources/translations/validators.ja.xlf | 19 + .../Resources/translations/validators.lb.xlf | 19 + .../Resources/translations/validators.lt.xlf | 19 + .../Resources/translations/validators.mn.xlf | 19 + .../Resources/translations/validators.nb.xlf | 19 + .../Resources/translations/validators.nl.xlf | 19 + .../Resources/translations/validators.pl.xlf | 19 + .../Resources/translations/validators.pt.xlf | 19 + .../translations/validators.pt_BR.xlf | 19 + .../Resources/translations/validators.ro.xlf | 19 + .../Resources/translations/validators.ru.xlf | 19 + .../Resources/translations/validators.sk.xlf | 19 + .../Resources/translations/validators.sl.xlf | 19 + .../translations/validators.sr_Cyrl.xlf | 19 + .../translations/validators.sr_Latn.xlf | 19 + .../Resources/translations/validators.sv.xlf | 19 + .../Resources/translations/validators.ua.xlf | 19 + .../translations/validators.zh_CN.xlf | 19 + .../Component/Form/ReversedTransformer.php | 55 + .../Form/Tests/AbstractDivLayoutTest.php | 560 +++ .../Form/Tests/AbstractExtensionTest.php | 43 + .../Form/Tests/AbstractLayoutTest.php | 1734 +++++++++ .../Form/Tests/AbstractTableLayoutTest.php | 344 ++ .../Core/ChoiceList/ChoiceListTest.php | 144 + .../Core/ChoiceList/LazyChoiceListTest.php | 116 + .../Core/ChoiceList/ObjectChoiceListTest.php | 209 ++ .../Core/ChoiceList/SimpleChoiceListTest.php | 188 + .../DataMapper/PropertyPathMapperTest.php | 365 ++ .../ArrayToPartsTransformerTest.php | 149 + .../BooleanToStringTransformerTest.php | 60 + .../ChoiceToValueTransformerTest.php | 76 + .../ChoicesToValuesTransformerTest.php | 76 + .../DataTransformerChainTest.php | 53 + .../Core/DataTransformer/DateTimeTestCase.php | 20 + .../DateTimeToArrayTransformerTest.php | 512 +++ ...teTimeToLocalizedStringTransformerTest.php | 297 ++ .../DateTimeToStringTransformerTest.php | 150 + .../DateTimeToTimestampTransformerTest.php | 104 + ...ntegerToLocalizedStringTransformerTest.php | 111 + .../DataTransformer/LocalizedTestCase.php | 70 + .../MoneyToLocalizedStringTransformerTest.php | 71 + ...NumberToLocalizedStringTransformerTest.php | 175 + ...ercentToLocalizedStringTransformerTest.php | 110 + .../ValueToDuplicatesTransformerTest.php | 120 + .../ValueToStringTransformerTest.php | 90 + .../FixRadioInputListenerTest.php | 73 + .../FixUrlProtocolListenerTest.php | 61 + .../Core/EventListener/Fixtures/randomhash | Bin 0 -> 35 bytes ...MergeCollectionListenerArrayObjectTest.php | 27 + .../MergeCollectionListenerArrayTest.php | 27 + ...ollectionListenerCustomArrayObjectTest.php | 28 + .../MergeCollectionListenerTest.php | 260 ++ .../EventListener/ResizeFormListenerTest.php | 244 ++ .../Core/EventListener/TrimListenerTest.php | 49 + .../Extension/Core/Type/CheckboxTypeTest.php | 140 + .../Extension/Core/Type/ChoiceTypeTest.php | 713 ++++ .../Core/Type/CollectionTypeTest.php | 200 ++ .../Extension/Core/Type/CountryTypeTest.php | 46 + .../Extension/Core/Type/DateTimeTypeTest.php | 246 ++ .../Extension/Core/Type/DateTypeTest.php | 550 +++ .../Extension/Core/Type/FileTypeTest.php | 54 + .../Extension/Core/Type/FormTypeTest.php | 644 ++++ .../Extension/Core/Type/IntegerTypeTest.php | 25 + .../Extension/Core/Type/LanguageTypeTest.php | 41 + .../Extension/Core/Type/LocaleTypeTest.php | 30 + .../Extension/Core/Type/LocalizedTestCase.php | 28 + .../Extension/Core/Type/MoneyTypeTest.php | 34 + .../Extension/Core/Type/NumberTypeTest.php | 58 + .../Extension/Core/Type/PasswordTypeTest.php | 43 + .../Extension/Core/Type/RepeatedTypeTest.php | 115 + .../Extension/Core/Type/TimeTypeTest.php | 419 +++ .../Extension/Core/Type/TimezoneTypeTest.php | 30 + .../Extension/Core/Type/TypeTestCase.php | 65 + .../Tests/Extension/Core/Type/UrlTypeTest.php | 61 + .../CsrfProvider/DefaultCsrfProviderTest.php | 58 + .../CsrfProvider/SessionCsrfProviderTest.php | 75 + .../Csrf/Type/FormTypeCsrfExtensionTest.php | 254 ++ .../Constraints/FormValidatorTest.php | 520 +++ .../EventListener/ValidationListenerTest.php | 152 + .../Type/FormTypeValidatorExtensionTest.php | 76 + .../Extension/Validator/Type/TypeTestCase.php | 49 + .../ViolationMapper/ViolationMapperTest.php | 1455 ++++++++ .../ViolationMapper/ViolationPathTest.php | 246 ++ .../Component/Form/Tests/Fixtures/Author.php | 71 + .../Form/Tests/Fixtures/AuthorType.php | 30 + .../Form/Tests/Fixtures/CustomArrayObject.php | 70 + .../Tests/Fixtures/FixedDataTransformer.php | 44 + .../Tests/Fixtures/FixedFilterListener.php | 66 + .../Component/Form/Tests/Fixtures/FooType.php | 59 + .../Tests/Fixtures/FooTypeBarExtension.php | 35 + .../Tests/Fixtures/FooTypeBazExtension.php | 28 + .../Form/Tests/Fixtures/Magician.php | 27 + .../Form/Tests/Fixtures/TestExtension.php | 72 + .../Symfony/Component/Form/Tests/Fixtures/foo | 0 .../Component/Form/Tests/FormBuilderTest.php | 218 ++ .../Component/Form/Tests/FormConfigTest.php | 78 + .../Component/Form/Tests/FormFactoryTest.php | 595 ++++ .../Component/Form/Tests/FormInterface.php | 16 + .../Symfony/Component/Form/Tests/FormTest.php | 1353 +++++++ .../Component/Form/Tests/Guess/GuessTest.php | 36 + .../Form/Tests/Util/FormUtilTest.php | 193 + .../Util/PropertyPathArrayObjectTest.php | 20 + .../Form/Tests/Util/PropertyPathArrayTest.php | 20 + .../Tests/Util/PropertyPathBuilderTest.php | 238 ++ .../Tests/Util/PropertyPathCollectionTest.php | 198 ++ .../PropertyPathCustomArrayObjectTest.php | 22 + .../Form/Tests/Util/PropertyPathTest.php | 583 ++++ .../Component/Form/Tests/bootstrap.php | 22 + .../Component/Form/UnmodifiableFormConfig.php | 338 ++ .../Symfony/Component/Form/Util/FormUtil.php | 222 ++ .../Component/Form/Util/PropertyPath.php | 612 ++++ .../Form/Util/PropertyPathBuilder.php | 280 ++ .../Form/Util/PropertyPathInterface.php | 92 + .../Form/Util/PropertyPathIterator.php | 55 + .../Util/PropertyPathIteratorInterface.php | 34 + .../Form/Util/VirtualFormAwareIterator.php | 33 + .../src/Symfony/Component/Form/composer.json | 41 + .../Symfony/Component/Form/phpunit.xml.dist | 29 + .../HttpFoundation/ApacheRequest.php | 51 + .../Component/HttpFoundation/CHANGELOG.md | 73 + .../Component/HttpFoundation/Cookie.php | 203 ++ .../File/Exception/AccessDeniedException.php | 30 + .../File/Exception/FileException.php | 21 + .../File/Exception/FileNotFoundException.php | 30 + .../Exception/UnexpectedTypeException.php | 20 + .../File/Exception/UploadException.php | 21 + .../Component/HttpFoundation/File/File.php | 129 + .../File/MimeType/ExtensionGuesser.php | 100 + .../MimeType/ExtensionGuesserInterface.php | 26 + .../MimeType/FileBinaryMimeTypeGuesser.php | 89 + .../File/MimeType/FileinfoMimeTypeGuesser.php | 59 + .../MimeType/MimeTypeExtensionGuesser.php | 743 ++++ .../File/MimeType/MimeTypeGuesser.php | 121 + .../MimeType/MimeTypeGuesserInterface.php | 32 + .../HttpFoundation/File/UploadedFile.php | 223 ++ .../Component/HttpFoundation/FileBag.php | 158 + .../Component/HttpFoundation/HeaderBag.php | 323 ++ .../Component/HttpFoundation/JsonResponse.php | 109 + .../Symfony/Component/HttpFoundation/LICENSE | 19 + .../Component/HttpFoundation/ParameterBag.php | 301 ++ .../Component/HttpFoundation/README.md | 46 + .../HttpFoundation/RedirectResponse.php | 83 + .../Component/HttpFoundation/Request.php | 1467 ++++++++ .../HttpFoundation/RequestMatcher.php | 221 ++ .../RequestMatcherInterface.php | 33 + .../stubs/SessionHandlerInterface.php | 98 + .../Component/HttpFoundation/Response.php | 1117 ++++++ .../HttpFoundation/ResponseHeaderBag.php | 293 ++ .../Component/HttpFoundation/ServerBag.php | 82 + .../Session/Attribute/AttributeBag.php | 157 + .../Attribute/AttributeBagInterface.php | 72 + .../Attribute/NamespacedAttributeBag.php | 154 + .../Session/Flash/AutoExpireFlashBag.php | 176 + .../HttpFoundation/Session/Flash/FlashBag.php | 186 + .../Session/Flash/FlashBagInterface.php | 93 + .../HttpFoundation/Session/Session.php | 339 ++ .../Session/SessionBagInterface.php | 48 + .../Session/SessionInterface.php | 199 ++ .../Storage/Handler/FileSessionHandler.php | 115 + .../Handler/MemcacheSessionHandler.php | 109 + .../Handler/MemcachedSessionHandler.php | 116 + .../Storage/Handler/MongoDbSessionHandler.php | 145 + .../Storage/Handler/NullSessionHandler.php | 72 + .../Storage/Handler/PdoSessionHandler.php | 231 ++ .../Session/Storage/MetadataBag.php | 160 + .../Storage/MockArraySessionStorage.php | 252 ++ .../Storage/MockFileSessionStorage.php | 122 + .../Session/Storage/NativeSessionStorage.php | 392 +++ .../Session/Storage/Proxy/AbstractProxy.php | 135 + .../Session/Storage/Proxy/NativeProxy.php | 41 + .../Storage/Proxy/SessionHandlerProxy.php | 95 + .../Storage/SessionStorageInterface.php | 136 + .../HttpFoundation/StreamedResponse.php | 129 + .../Tests/ApacheRequestTest.php | 92 + .../HttpFoundation/Tests/CookieTest.php | 127 + .../HttpFoundation/Tests/File/FileTest.php | 134 + .../Tests/File/Fixtures/.unknownextension | 1 + .../Tests/File/Fixtures/directory/.empty | 0 .../HttpFoundation/Tests/File/Fixtures/test | Bin 0 -> 35 bytes .../Tests/File/Fixtures/test.gif | Bin 0 -> 35 bytes .../Tests/File/MimeType/MimeTypeTest.php | 105 + .../Tests/File/UploadedFileTest.php | 221 ++ .../HttpFoundation/Tests/FileBagTest.php | 148 + .../HttpFoundation/Tests/HeaderBagTest.php | 158 + .../HttpFoundation/Tests/JsonResponseTest.php | 114 + .../HttpFoundation/Tests/ParameterBagTest.php | 233 ++ .../Tests/RedirectResponseTest.php | 50 + .../Tests/RequestMatcherTest.php | 180 + .../HttpFoundation/Tests/RequestTest.php | 1072 ++++++ .../Tests/ResponseHeaderBagTest.php | 176 + .../HttpFoundation/Tests/ResponseTest.php | 556 +++ .../HttpFoundation/Tests/ServerBagTest.php | 101 + .../Session/Attribute/AttributeBagTest.php | 193 + .../Attribute/NamespacedAttributeBagTest.php | 171 + .../Session/Flash/AutoExpireFlashBagTest.php | 155 + .../Tests/Session/Flash/FlashBagTest.php | 168 + .../Tests/Session/SessionTest.php | 277 ++ .../Handler/FileSessionHandlerTest.php | 106 + .../Handler/MemcacheSessionHandlerTest.php | 124 + .../Handler/MemcachedSessionHandlerTest.php | 119 + .../Handler/MongoDbSessionHandlerTest.php | 99 + .../Handler/NullSessionHandlerTest.php | 58 + .../Storage/Handler/PdoSessionHandlerTest.php | 64 + .../Tests/Session/Storage/MetadataBagTest.php | 99 + .../Storage/MockArraySessionStorageTest.php | 98 + .../Storage/MockFileSessionStorageTest.php | 119 + .../Storage/NativeSessionStorageTest.php | 154 + .../Storage/Proxy/AbstractProxyTest.php | 141 + .../Session/Storage/Proxy/NativeProxyTest.php | 35 + .../Storage/Proxy/SessionHandlerProxyTest.php | 122 + .../Tests/StreamedResponseTest.php | 105 + .../HttpFoundation/Tests/bootstrap.php | 22 + .../Component/HttpFoundation/composer.json | 33 + .../Component/HttpFoundation/phpunit.xml.dist | 30 + .../Component/HttpKernel/Bundle/Bundle.php | 194 ++ .../HttpKernel/Bundle/BundleInterface.php | 98 + .../Symfony/Component/HttpKernel/CHANGELOG.md | 19 + .../CacheClearer/CacheClearerInterface.php | 27 + .../CacheClearer/ChainCacheClearer.php | 55 + .../HttpKernel/CacheWarmer/CacheWarmer.php | 32 + .../CacheWarmer/CacheWarmerAggregate.php | 73 + .../CacheWarmer/CacheWarmerInterface.php | 32 + .../CacheWarmer/WarmableInterface.php | 27 + .../Symfony/Component/HttpKernel/Client.php | 184 + .../HttpKernel/Config/FileLocator.php | 54 + .../Controller/ControllerResolver.php | 160 + .../ControllerResolverInterface.php | 63 + .../DataCollector/ConfigDataCollector.php | 185 + .../DataCollector/DataCollector.php | 35 + .../DataCollector/DataCollectorInterface.php | 45 + .../DataCollector/EventDataCollector.php | 77 + .../DataCollector/ExceptionDataCollector.php | 110 + .../DataCollector/LoggerDataCollector.php | 106 + .../DataCollector/MemoryDataCollector.php | 51 + .../DataCollector/RequestDataCollector.php | 207 ++ .../DataCollector/TimeDataCollector.php | 109 + ...ContainerAwareTraceableEventDispatcher.php | 318 ++ .../HttpKernel/Debug/ErrorHandler.php | 72 + .../HttpKernel/Debug/ExceptionHandler.php | 263 ++ .../Component/HttpKernel/Debug/Stopwatch.php | 251 ++ .../HttpKernel/Debug/StopwatchEvent.php | 182 + .../AddClassesToCachePass.php | 47 + .../ConfigurableExtension.php | 45 + .../DependencyInjection/Extension.php | 125 + .../MergeExtensionConfigurationPass.php | 41 + .../Event/FilterControllerEvent.php | 107 + .../HttpKernel/Event/FilterResponseEvent.php | 67 + .../HttpKernel/Event/GetResponseEvent.php | 72 + .../GetResponseForControllerResultEvent.php | 54 + .../Event/GetResponseForExceptionEvent.php | 72 + .../HttpKernel/Event/KernelEvent.php | 89 + .../HttpKernel/Event/PostResponseEvent.php | 72 + .../HttpKernel/EventListener/EsiListener.php | 60 + .../EventListener/ExceptionListener.php | 113 + .../EventListener/LocaleListener.php | 65 + .../EventListener/ProfilerListener.php | 160 + .../EventListener/ResponseListener.php | 59 + .../EventListener/RouterListener.php | 103 + .../StreamedResponseListener.php | 52 + .../Exception/AccessDeniedHttpException.php | 33 + .../HttpKernel/Exception/FlattenException.php | 226 ++ .../HttpKernel/Exception/HttpException.php | 41 + .../Exception/HttpExceptionInterface.php | 34 + .../MethodNotAllowedHttpException.php | 35 + .../Exception/NotFoundHttpException.php | 32 + .../Component/HttpKernel/HttpCache/Esi.php | 234 ++ .../HttpCache/EsiResponseCacheStrategy.php | 74 + .../EsiResponseCacheStrategyInterface.php | 41 + .../HttpKernel/HttpCache/HttpCache.php | 660 ++++ .../Component/HttpKernel/HttpCache/Store.php | 403 +++ .../HttpKernel/HttpCache/StoreInterface.php | 85 + .../Component/HttpKernel/HttpKernel.php | 231 ++ .../HttpKernel/HttpKernelInterface.php | 47 + .../Symfony/Component/HttpKernel/Kernel.php | 771 ++++ .../Component/HttpKernel/KernelEvents.php | 105 + .../Component/HttpKernel/KernelInterface.php | 199 ++ .../src/Symfony/Component/HttpKernel/LICENSE | 19 + .../HttpKernel/Log/DebugLoggerInterface.php | 38 + .../HttpKernel/Log/LoggerInterface.php | 62 + .../Component/HttpKernel/Log/NullLogger.php | 80 + .../Profiler/BaseMemcacheProfilerStorage.php | 291 ++ .../Profiler/FileProfilerStorage.php | 264 ++ .../Profiler/MemcacheProfilerStorage.php | 110 + .../Profiler/MemcachedProfilerStorage.php | 105 + .../Profiler/MongoDbProfilerStorage.php | 227 ++ .../Profiler/MysqlProfilerStorage.php | 69 + .../Profiler/PdoProfilerStorage.php | 254 ++ .../Component/HttpKernel/Profiler/Profile.php | 219 ++ .../HttpKernel/Profiler/Profiler.php | 248 ++ .../Profiler/ProfilerStorageInterface.php | 57 + .../Profiler/RedisProfilerStorage.php | 374 ++ .../Profiler/SqliteProfilerStorage.php | 130 + .../Symfony/Component/HttpKernel/README.md | 92 + .../HttpKernel/TerminableInterface.php | 39 + .../HttpKernel/Tests/Bundle/BundleTest.php | 48 + .../CacheClearer/ChainCacheClearerTest.php | 58 + .../CacheWarmer/CacheWarmerAggregateTest.php | 102 + .../Tests/CacheWarmer/CacheWarmerTest.php | 67 + .../Component/HttpKernel/Tests/ClientTest.php | 159 + .../Controller/ControllerResolverTest.php | 176 + .../DataCollector/ConfigDataCollectorTest.php | 86 + .../DataCollector/EventDataCollectorTest.php | 45 + .../ExceptionDataCollectorTest.php | 47 + .../DataCollector/LoggerDataCollectorTest.php | 64 + .../DataCollector/MemoryDataCollectorTest.php | 37 + .../RequestDataCollectorTest.php | 73 + ...ainerAwareTraceableEventDispatcherTest.php | 80 + .../Tests/Debug/ErrorHandlerTest.php | 58 + .../Tests/Debug/ExceptionHandlerTest.php | 59 + .../Tests/Debug/StopwatchEventTest.php | 152 + .../HttpKernel/Tests/Debug/StopwatchTest.php | 121 + .../MergeExtensionConfigurationPassTest.php | 65 + .../Tests/EventListener/EsiListenerTest.php | 73 + .../EventListener/ExceptionListenerTest.php | 139 + .../EventListener/LocaleListenerTest.php | 98 + .../EventListener/ResponseListenerTest.php | 99 + .../EventListener/RouterListenerTest.php | 109 + .../Tests/Exception/FlattenExceptionTest.php | 121 + .../Fixtures/BaseBundle/Resources/foo.txt | 0 .../Fixtures/BaseBundle/Resources/hide.txt | 0 .../Fixtures/Bundle1Bundle/Resources/foo.txt | 0 .../Tests/Fixtures/Bundle1Bundle/bar.txt | 0 .../Tests/Fixtures/Bundle1Bundle/foo.txt | 0 .../Tests/Fixtures/Bundle2Bundle/foo.txt | 0 .../Fixtures/ChildBundle/Resources/foo.txt | 0 .../Fixtures/ChildBundle/Resources/hide.txt | 0 .../ExtensionAbsentBundle.php | 18 + .../ExtensionLoadedExtension.php | 22 + .../ExtensionLoadedBundle.php | 18 + .../Command/FooCommand.php | 23 + .../ExtensionPresentExtension.php | 22 + .../ExtensionPresentBundle.php | 18 + .../Tests/Fixtures/FooBarBundle.php | 19 + .../Tests/Fixtures/KernelForTest.php | 54 + .../Fixtures/Resources/BaseBundle/hide.txt | 0 .../Fixtures/Resources/Bundle1Bundle/foo.txt | 0 .../Fixtures/Resources/ChildBundle/foo.txt | 0 .../Fixtures/Resources/FooBundle/foo.txt | 0 .../HttpKernel/Tests/Fixtures/TestClient.php | 26 + .../Tests/Fixtures/TestEventDispatcher.php | 28 + .../HttpKernel/Tests/HttpCache/EsiTest.php | 227 ++ .../Tests/HttpCache/HttpCacheTest.php | 1037 ++++++ .../Tests/HttpCache/HttpCacheTestCase.php | 179 + .../HttpKernel/Tests/HttpCache/StoreTest.php | 232 ++ .../Tests/HttpCache/TestHttpKernel.php | 86 + .../HttpCache/TestMultipleHttpKernel.php | 78 + .../HttpKernel/Tests/HttpKernelTest.php | 237 ++ .../Component/HttpKernel/Tests/KernelTest.php | 776 +++++ .../Component/HttpKernel/Tests/Logger.php | 88 + .../Profiler/AbstractProfilerStorageTest.php | 216 ++ .../Profiler/FileProfilerStorageTest.php | 60 + .../Profiler/MemcacheProfilerStorageTest.php | 49 + .../Profiler/MemcachedProfilerStorageTest.php | 49 + .../Tests/Profiler/Mock/MemcacheMock.php | 260 ++ .../Tests/Profiler/Mock/MemcachedMock.php | 225 ++ .../Tests/Profiler/Mock/RedisMock.php | 241 ++ .../Profiler/MongoDbProfilerStorageTest.php | 81 + .../Tests/Profiler/ProfilerTest.php | 56 + .../Profiler/RedisProfilerStorageTest.php | 49 + .../Profiler/SqliteProfilerStorageTest.php | 50 + .../HttpKernel/Tests/TestHttpKernel.php | 41 + .../Component/HttpKernel/Tests/bootstrap.php | 22 + .../Component/HttpKernel/composer.json | 50 + .../Component/HttpKernel/phpunit.xml.dist | 29 + .../src/Symfony/Component/Locale/CHANGELOG.md | 7 + .../MethodArgumentNotImplementedException.php | 32 + ...odArgumentValueNotImplementedException.php | 41 + .../MethodNotImplementedException.php | 28 + .../Exception/NotImplementedException.php | 32 + .../src/Symfony/Component/Locale/LICENSE | 19 + .../src/Symfony/Component/Locale/Locale.php | 258 ++ .../src/Symfony/Component/Locale/README.md | 22 + .../Locale/Resources/data/UPDATE.txt | 30 + .../Locale/Resources/data/lang/af.res | Bin 0 -> 2944 bytes .../Locale/Resources/data/lang/ak.res | Bin 0 -> 1688 bytes .../Locale/Resources/data/lang/am.res | Bin 0 -> 3756 bytes .../Locale/Resources/data/lang/ar.res | Bin 0 -> 25924 bytes .../Locale/Resources/data/lang/as.res | Bin 0 -> 1500 bytes .../Locale/Resources/data/lang/asa.res | Bin 0 -> 1600 bytes .../Locale/Resources/data/lang/az.res | Bin 0 -> 24356 bytes .../Locale/Resources/data/lang/az_AZ.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/az_Cyrl.res | Bin 0 -> 432 bytes .../Locale/Resources/data/lang/az_Latn.res | Bin 0 -> 100 bytes .../Locale/Resources/data/lang/az_Latn_AZ.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/be.res | Bin 0 -> 6984 bytes .../Locale/Resources/data/lang/bem.res | Bin 0 -> 1888 bytes .../Locale/Resources/data/lang/bez.res | Bin 0 -> 1576 bytes .../Locale/Resources/data/lang/bg.res | Bin 0 -> 25128 bytes .../Locale/Resources/data/lang/bm.res | Bin 0 -> 1660 bytes .../Locale/Resources/data/lang/bn.res | Bin 0 -> 23632 bytes .../Locale/Resources/data/lang/bn_IN.res | Bin 0 -> 1032 bytes .../Locale/Resources/data/lang/bo.res | Bin 0 -> 400 bytes .../Locale/Resources/data/lang/bs.res | Bin 0 -> 23688 bytes .../Locale/Resources/data/lang/ca.res | Bin 0 -> 25304 bytes .../Locale/Resources/data/lang/cgg.res | Bin 0 -> 1700 bytes .../Locale/Resources/data/lang/chr.res | Bin 0 -> 892 bytes .../Locale/Resources/data/lang/cs.res | Bin 0 -> 11008 bytes .../Locale/Resources/data/lang/cy.res | Bin 0 -> 2928 bytes .../Locale/Resources/data/lang/da.res | Bin 0 -> 24976 bytes .../Locale/Resources/data/lang/dav.res | Bin 0 -> 1580 bytes .../Locale/Resources/data/lang/de.res | Bin 0 -> 28096 bytes .../Locale/Resources/data/lang/de_CH.res | Bin 0 -> 164 bytes .../Locale/Resources/data/lang/ebu.res | Bin 0 -> 1580 bytes .../Locale/Resources/data/lang/ee.res | Bin 0 -> 1696 bytes .../Locale/Resources/data/lang/el.res | Bin 0 -> 27120 bytes .../Locale/Resources/data/lang/en.res | Bin 0 -> 30020 bytes .../Locale/Resources/data/lang/en_RH.res | Bin 0 -> 92 bytes .../Locale/Resources/data/lang/en_ZW.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/eo.res | Bin 0 -> 4292 bytes .../Locale/Resources/data/lang/es.res | Bin 0 -> 24196 bytes .../Locale/Resources/data/lang/es_AR.res | Bin 0 -> 180 bytes .../Locale/Resources/data/lang/es_CL.res | Bin 0 -> 264 bytes .../Locale/Resources/data/lang/et.res | Bin 0 -> 23360 bytes .../Locale/Resources/data/lang/eu.res | Bin 0 -> 6368 bytes .../Locale/Resources/data/lang/fa.res | Bin 0 -> 21604 bytes .../Locale/Resources/data/lang/fa_AF.res | Bin 0 -> 704 bytes .../Locale/Resources/data/lang/ff.res | Bin 0 -> 1584 bytes .../Locale/Resources/data/lang/fi.res | Bin 0 -> 28012 bytes .../Locale/Resources/data/lang/fil.res | Bin 0 -> 3264 bytes .../Locale/Resources/data/lang/fil_PH.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/fo.res | Bin 0 -> 156 bytes .../Locale/Resources/data/lang/fr.res | Bin 0 -> 26084 bytes .../Locale/Resources/data/lang/ga.res | Bin 0 -> 5120 bytes .../Locale/Resources/data/lang/gl.res | Bin 0 -> 7104 bytes .../Locale/Resources/data/lang/gsw.res | Bin 0 -> 28388 bytes .../Locale/Resources/data/lang/gu.res | Bin 0 -> 21712 bytes .../Locale/Resources/data/lang/guz.res | Bin 0 -> 1584 bytes .../Locale/Resources/data/lang/gv.res | Bin 0 -> 148 bytes .../Locale/Resources/data/lang/ha.res | Bin 0 -> 1720 bytes .../Locale/Resources/data/lang/ha_GH.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/ha_Latn.res | Bin 0 -> 100 bytes .../Locale/Resources/data/lang/ha_Latn_GH.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/ha_Latn_NE.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/ha_Latn_NG.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/ha_NE.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/ha_NG.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/haw.res | Bin 0 -> 1484 bytes .../Locale/Resources/data/lang/he.res | Bin 0 -> 11588 bytes .../Locale/Resources/data/lang/he_IL.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/hi.res | Bin 0 -> 23084 bytes .../Locale/Resources/data/lang/hr.res | Bin 0 -> 26960 bytes .../Locale/Resources/data/lang/hu.res | Bin 0 -> 24372 bytes .../Locale/Resources/data/lang/hy.res | Bin 0 -> 152 bytes .../Locale/Resources/data/lang/id.res | Bin 0 -> 8268 bytes .../Locale/Resources/data/lang/id_ID.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/ig.res | Bin 0 -> 1412 bytes .../Locale/Resources/data/lang/ii.res | Bin 0 -> 932 bytes .../Locale/Resources/data/lang/in.res | Bin 0 -> 128 bytes .../Locale/Resources/data/lang/in_ID.res | Bin 0 -> 92 bytes .../Locale/Resources/data/lang/is.res | Bin 0 -> 19368 bytes .../Locale/Resources/data/lang/it.res | Bin 0 -> 23716 bytes .../Locale/Resources/data/lang/iw.res | Bin 0 -> 128 bytes .../Locale/Resources/data/lang/iw_IL.res | Bin 0 -> 92 bytes .../Locale/Resources/data/lang/ja.res | Bin 0 -> 19196 bytes .../Locale/Resources/data/lang/ja_JP.res | Bin 0 -> 80 bytes .../Resources/data/lang/ja_JP_TRADITIONAL.res | Bin 0 -> 120 bytes .../Locale/Resources/data/lang/jmc.res | Bin 0 -> 1684 bytes .../Locale/Resources/data/lang/ka.res | Bin 0 -> 8716 bytes .../Locale/Resources/data/lang/kab.res | Bin 0 -> 1652 bytes .../Locale/Resources/data/lang/kam.res | Bin 0 -> 1580 bytes .../Locale/Resources/data/lang/kde.res | Bin 0 -> 1688 bytes .../Locale/Resources/data/lang/kea.res | Bin 0 -> 1420 bytes .../Locale/Resources/data/lang/khq.res | Bin 0 -> 1992 bytes .../Locale/Resources/data/lang/ki.res | Bin 0 -> 1576 bytes .../Locale/Resources/data/lang/kk.res | Bin 0 -> 148 bytes .../Locale/Resources/data/lang/kk_Cyrl.res | Bin 0 -> 100 bytes .../Locale/Resources/data/lang/kk_Cyrl_KZ.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/kk_KZ.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/kl.res | Bin 0 -> 160 bytes .../Locale/Resources/data/lang/kln.res | Bin 0 -> 2156 bytes .../Locale/Resources/data/lang/km.res | Bin 0 -> 4040 bytes .../Locale/Resources/data/lang/kn.res | Bin 0 -> 22544 bytes .../Locale/Resources/data/lang/ko.res | Bin 0 -> 18288 bytes .../Locale/Resources/data/lang/kok.res | Bin 0 -> 4448 bytes .../Locale/Resources/data/lang/kw.res | Bin 0 -> 156 bytes .../Locale/Resources/data/lang/lag.res | Bin 0 -> 1640 bytes .../Locale/Resources/data/lang/lg.res | Bin 0 -> 1644 bytes .../Locale/Resources/data/lang/lt.res | Bin 0 -> 25800 bytes .../Locale/Resources/data/lang/luo.res | Bin 0 -> 1580 bytes .../Locale/Resources/data/lang/luy.res | Bin 0 -> 1576 bytes .../Locale/Resources/data/lang/lv.res | Bin 0 -> 22628 bytes .../Locale/Resources/data/lang/mas.res | Bin 0 -> 2612 bytes .../Locale/Resources/data/lang/mer.res | Bin 0 -> 1568 bytes .../Locale/Resources/data/lang/mfe.res | Bin 0 -> 1452 bytes .../Locale/Resources/data/lang/mg.res | Bin 0 -> 1504 bytes .../Locale/Resources/data/lang/mk.res | Bin 0 -> 20876 bytes .../Locale/Resources/data/lang/ml.res | Bin 0 -> 25248 bytes .../Locale/Resources/data/lang/mo.res | Bin 0 -> 132 bytes .../Locale/Resources/data/lang/mr.res | Bin 0 -> 21792 bytes .../Locale/Resources/data/lang/ms.res | Bin 0 -> 1692 bytes .../Locale/Resources/data/lang/mt.res | Bin 0 -> 17844 bytes .../Locale/Resources/data/lang/my.res | Bin 0 -> 8636 bytes .../Locale/Resources/data/lang/naq.res | Bin 0 -> 1924 bytes .../Locale/Resources/data/lang/nb.res | Bin 0 -> 25732 bytes .../Locale/Resources/data/lang/nb_NO.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/nd.res | Bin 0 -> 1832 bytes .../Locale/Resources/data/lang/ne.res | Bin 0 -> 6304 bytes .../Locale/Resources/data/lang/nl.res | Bin 0 -> 25808 bytes .../Locale/Resources/data/lang/nl_BE.res | Bin 0 -> 352 bytes .../Locale/Resources/data/lang/nn.res | Bin 0 -> 25972 bytes .../Locale/Resources/data/lang/nn_NO.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/no.res | Bin 0 -> 128 bytes .../Locale/Resources/data/lang/no_NO.res | Bin 0 -> 92 bytes .../Locale/Resources/data/lang/no_NO_NY.res | Bin 0 -> 92 bytes .../Locale/Resources/data/lang/nyn.res | Bin 0 -> 1708 bytes .../Locale/Resources/data/lang/om.res | Bin 0 -> 3892 bytes .../Locale/Resources/data/lang/or.res | Bin 0 -> 22584 bytes .../Locale/Resources/data/lang/pa.res | Bin 0 -> 1164 bytes .../Locale/Resources/data/lang/pa_Arab.res | Bin 0 -> 228 bytes .../Locale/Resources/data/lang/pa_Arab_PK.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/pa_Guru.res | Bin 0 -> 100 bytes .../Locale/Resources/data/lang/pa_Guru_IN.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/pa_IN.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/pa_PK.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/pl.res | Bin 0 -> 26556 bytes .../Locale/Resources/data/lang/ps.res | Bin 0 -> 1048 bytes .../Locale/Resources/data/lang/pt.res | Bin 0 -> 25568 bytes .../Locale/Resources/data/lang/pt_PT.res | Bin 0 -> 4312 bytes .../Locale/Resources/data/lang/rm.res | Bin 0 -> 25684 bytes .../Locale/Resources/data/lang/ro.res | Bin 0 -> 12660 bytes .../Locale/Resources/data/lang/ro_MD.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/rof.res | Bin 0 -> 1592 bytes .../Locale/Resources/data/lang/root.res | Bin 0 -> 344 bytes .../Locale/Resources/data/lang/ru.res | Bin 0 -> 26560 bytes .../Locale/Resources/data/lang/ru_UA.res | Bin 0 -> 256 bytes .../Locale/Resources/data/lang/rw.res | Bin 0 -> 4352 bytes .../Locale/Resources/data/lang/rwk.res | Bin 0 -> 1680 bytes .../Locale/Resources/data/lang/saq.res | Bin 0 -> 1584 bytes .../Locale/Resources/data/lang/seh.res | Bin 0 -> 1420 bytes .../Locale/Resources/data/lang/ses.res | Bin 0 -> 1976 bytes .../Locale/Resources/data/lang/sg.res | Bin 0 -> 1436 bytes .../Locale/Resources/data/lang/sh.res | Bin 0 -> 136 bytes .../Locale/Resources/data/lang/sh_BA.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/sh_CS.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/sh_YU.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/shi.res | Bin 0 -> 1616 bytes .../Locale/Resources/data/lang/shi_Latn.res | Bin 0 -> 100 bytes .../Resources/data/lang/shi_Latn_MA.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/shi_MA.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/shi_Tfng.res | Bin 0 -> 1616 bytes .../Locale/Resources/data/lang/si.res | Bin 0 -> 916 bytes .../Locale/Resources/data/lang/sk.res | Bin 0 -> 12500 bytes .../Locale/Resources/data/lang/sl.res | Bin 0 -> 28996 bytes .../Locale/Resources/data/lang/sn.res | Bin 0 -> 1672 bytes .../Locale/Resources/data/lang/so.res | Bin 0 -> 1704 bytes .../Locale/Resources/data/lang/sq.res | Bin 0 -> 760 bytes .../Locale/Resources/data/lang/sr.res | Bin 0 -> 27032 bytes .../Locale/Resources/data/lang/sr_BA.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/sr_CS.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/sr_Cyrl.res | Bin 0 -> 100 bytes .../Locale/Resources/data/lang/sr_Cyrl_BA.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/sr_Cyrl_CS.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/sr_Cyrl_RS.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/sr_Cyrl_YU.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/sr_Latn.res | Bin 0 -> 27168 bytes .../Locale/Resources/data/lang/sr_Latn_BA.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/sr_Latn_CS.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/sr_Latn_ME.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/sr_Latn_RS.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/sr_Latn_YU.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/sr_ME.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/sr_RS.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/sr_YU.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/sv.res | Bin 0 -> 25900 bytes .../Locale/Resources/data/lang/sv_FI.res | Bin 0 -> 172 bytes .../Locale/Resources/data/lang/sw.res | Bin 0 -> 1584 bytes .../Locale/Resources/data/lang/ta.res | Bin 0 -> 23396 bytes .../Locale/Resources/data/lang/te.res | Bin 0 -> 22504 bytes .../Locale/Resources/data/lang/teo.res | Bin 0 -> 1580 bytes .../Locale/Resources/data/lang/th.res | Bin 0 -> 23176 bytes .../Locale/Resources/data/lang/th_TH.res | Bin 0 -> 80 bytes .../Resources/data/lang/th_TH_TRADITIONAL.res | Bin 0 -> 120 bytes .../Locale/Resources/data/lang/ti.res | Bin 0 -> 2668 bytes .../Locale/Resources/data/lang/tl.res | Bin 0 -> 128 bytes .../Locale/Resources/data/lang/tl_PH.res | Bin 0 -> 136 bytes .../Locale/Resources/data/lang/to.res | Bin 0 -> 11564 bytes .../Locale/Resources/data/lang/tr.res | Bin 0 -> 26180 bytes .../Locale/Resources/data/lang/tzm.res | Bin 0 -> 1672 bytes .../Locale/Resources/data/lang/tzm_Latn.res | Bin 0 -> 100 bytes .../Resources/data/lang/tzm_Latn_MA.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/tzm_MA.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/uk.res | Bin 0 -> 27100 bytes .../Locale/Resources/data/lang/ur.res | Bin 0 -> 2544 bytes .../Locale/Resources/data/lang/uz.res | Bin 0 -> 148 bytes .../Locale/Resources/data/lang/uz_AF.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/uz_Arab.res | Bin 0 -> 196 bytes .../Locale/Resources/data/lang/uz_Arab_AF.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/uz_Cyrl.res | Bin 0 -> 100 bytes .../Locale/Resources/data/lang/uz_Cyrl_UZ.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/uz_Latn.res | Bin 0 -> 588 bytes .../Locale/Resources/data/lang/uz_UZ.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/vi.res | Bin 0 -> 5428 bytes .../Locale/Resources/data/lang/vun.res | Bin 0 -> 1684 bytes .../Locale/Resources/data/lang/xog.res | Bin 0 -> 1696 bytes .../Locale/Resources/data/lang/yo.res | Bin 0 -> 3908 bytes .../Locale/Resources/data/lang/zh.res | Bin 0 -> 17736 bytes .../Locale/Resources/data/lang/zh_CN.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/zh_HK.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/zh_Hans.res | Bin 0 -> 100 bytes .../Locale/Resources/data/lang/zh_Hans_CN.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/zh_Hans_SG.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/zh_Hant.res | Bin 0 -> 17544 bytes .../Locale/Resources/data/lang/zh_Hant_HK.res | Bin 0 -> 556 bytes .../Locale/Resources/data/lang/zh_Hant_MO.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/zh_Hant_TW.res | Bin 0 -> 80 bytes .../Locale/Resources/data/lang/zh_MO.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/zh_SG.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/zh_TW.res | Bin 0 -> 144 bytes .../Locale/Resources/data/lang/zu.res | Bin 0 -> 504 bytes .../Locale/Resources/data/locales/af.res | Bin 0 -> 4764 bytes .../Locale/Resources/data/locales/af_NA.res | Bin 0 -> 204 bytes .../Locale/Resources/data/locales/af_ZA.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ak.res | Bin 0 -> 3888 bytes .../Locale/Resources/data/locales/ak_GH.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/am.res | Bin 0 -> 3488 bytes .../Locale/Resources/data/locales/am_ET.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ar.res | Bin 0 -> 19712 bytes .../Locale/Resources/data/locales/ar_AE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ar_BH.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ar_DZ.res | Bin 0 -> 900 bytes .../Locale/Resources/data/locales/ar_EG.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ar_IQ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ar_JO.res | Bin 0 -> 708 bytes .../Locale/Resources/data/locales/ar_KW.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ar_LB.res | Bin 0 -> 708 bytes .../Locale/Resources/data/locales/ar_LY.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ar_MA.res | Bin 0 -> 972 bytes .../Locale/Resources/data/locales/ar_OM.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ar_QA.res | Bin 0 -> 512 bytes .../Locale/Resources/data/locales/ar_SA.res | Bin 0 -> 512 bytes .../Locale/Resources/data/locales/ar_SD.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ar_SY.res | Bin 0 -> 856 bytes .../Locale/Resources/data/locales/ar_TN.res | Bin 0 -> 1300 bytes .../Locale/Resources/data/locales/ar_YE.res | Bin 0 -> 512 bytes .../Locale/Resources/data/locales/as.res | Bin 0 -> 2524 bytes .../Locale/Resources/data/locales/as_IN.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/asa.res | Bin 0 -> 4108 bytes .../Locale/Resources/data/locales/asa_TZ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/az.res | Bin 0 -> 4272 bytes .../Locale/Resources/data/locales/az_AZ.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/az_Cyrl.res | Bin 0 -> 2104 bytes .../Resources/data/locales/az_Cyrl_AZ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/az_Latn.res | Bin 0 -> 148 bytes .../Resources/data/locales/az_Latn_AZ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/be.res | Bin 0 -> 7584 bytes .../Locale/Resources/data/locales/be_BY.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/bem.res | Bin 0 -> 3580 bytes .../Locale/Resources/data/locales/bem_ZM.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/bez.res | Bin 0 -> 4492 bytes .../Locale/Resources/data/locales/bez_TZ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/bg.res | Bin 0 -> 9140 bytes .../Locale/Resources/data/locales/bg_BG.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/bm.res | Bin 0 -> 4280 bytes .../Locale/Resources/data/locales/bm_ML.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/bn.res | Bin 0 -> 9020 bytes .../Locale/Resources/data/locales/bn_BD.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/bn_IN.res | Bin 0 -> 632 bytes .../Locale/Resources/data/locales/bo.res | Bin 0 -> 3716 bytes .../Locale/Resources/data/locales/bo_CN.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/bo_IN.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/bs.res | Bin 0 -> 4356 bytes .../Locale/Resources/data/locales/bs_BA.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ca.res | Bin 0 -> 9716 bytes .../Locale/Resources/data/locales/ca_ES.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/cgg.res | Bin 0 -> 4212 bytes .../Locale/Resources/data/locales/cgg_UG.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/chr.res | Bin 0 -> 6272 bytes .../Locale/Resources/data/locales/chr_US.res | Bin 0 -> 152 bytes .../Locale/Resources/data/locales/cs.res | Bin 0 -> 5868 bytes .../Locale/Resources/data/locales/cs_CZ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/cy.res | Bin 0 -> 6608 bytes .../Locale/Resources/data/locales/cy_GB.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/da.res | Bin 0 -> 14800 bytes .../Locale/Resources/data/locales/da_DK.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/dav.res | Bin 0 -> 4508 bytes .../Locale/Resources/data/locales/dav_KE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/de.res | Bin 0 -> 16516 bytes .../Locale/Resources/data/locales/de_AT.res | Bin 0 -> 1180 bytes .../Locale/Resources/data/locales/de_BE.res | Bin 0 -> 716 bytes .../Locale/Resources/data/locales/de_CH.res | Bin 0 -> 436 bytes .../Locale/Resources/data/locales/de_DE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/de_LI.res | Bin 0 -> 268 bytes .../Locale/Resources/data/locales/de_LU.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ebu.res | Bin 0 -> 4396 bytes .../Locale/Resources/data/locales/ebu_KE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ee.res | Bin 0 -> 4044 bytes .../Locale/Resources/data/locales/ee_GH.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ee_TG.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/el.res | Bin 0 -> 11204 bytes .../Locale/Resources/data/locales/el_CY.res | Bin 0 -> 200 bytes .../Locale/Resources/data/locales/el_GR.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/en.res | Bin 0 -> 16428 bytes .../Locale/Resources/data/locales/en_AS.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/en_AU.res | Bin 0 -> 2784 bytes .../Locale/Resources/data/locales/en_BE.res | Bin 0 -> 1036 bytes .../Locale/Resources/data/locales/en_BW.res | Bin 0 -> 1000 bytes .../Locale/Resources/data/locales/en_BZ.res | Bin 0 -> 860 bytes .../Locale/Resources/data/locales/en_CA.res | Bin 0 -> 2820 bytes .../Locale/Resources/data/locales/en_GB.res | Bin 0 -> 8352 bytes .../Locale/Resources/data/locales/en_GU.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/en_HK.res | Bin 0 -> 8788 bytes .../Locale/Resources/data/locales/en_IE.res | Bin 0 -> 2812 bytes .../Locale/Resources/data/locales/en_IN.res | Bin 0 -> 956 bytes .../Locale/Resources/data/locales/en_JM.res | Bin 0 -> 200 bytes .../Locale/Resources/data/locales/en_MH.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/en_MP.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/en_MT.res | Bin 0 -> 908 bytes .../Locale/Resources/data/locales/en_MU.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/en_NA.res | Bin 0 -> 200 bytes .../Locale/Resources/data/locales/en_NZ.res | Bin 0 -> 2828 bytes .../Locale/Resources/data/locales/en_PH.res | Bin 0 -> 132 bytes .../Locale/Resources/data/locales/en_PK.res | Bin 0 -> 528 bytes .../Locale/Resources/data/locales/en_RH.res | Bin 0 -> 92 bytes .../Locale/Resources/data/locales/en_SG.res | Bin 0 -> 1560 bytes .../Locale/Resources/data/locales/en_TT.res | Bin 0 -> 200 bytes .../Locale/Resources/data/locales/en_UM.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/en_US.res | Bin 0 -> 152 bytes .../Resources/data/locales/en_US_POSIX.res | Bin 0 -> 408 bytes .../Locale/Resources/data/locales/en_VI.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/en_ZA.res | Bin 0 -> 1224 bytes .../Locale/Resources/data/locales/en_ZW.res | Bin 0 -> 920 bytes .../Locale/Resources/data/locales/eo.res | Bin 0 -> 2080 bytes .../Locale/Resources/data/locales/es.res | Bin 0 -> 16324 bytes .../Locale/Resources/data/locales/es_419.res | Bin 0 -> 200 bytes .../Locale/Resources/data/locales/es_AR.res | Bin 0 -> 952 bytes .../Locale/Resources/data/locales/es_BO.res | Bin 0 -> 232 bytes .../Locale/Resources/data/locales/es_CL.res | Bin 0 -> 992 bytes .../Locale/Resources/data/locales/es_CO.res | Bin 0 -> 708 bytes .../Locale/Resources/data/locales/es_CR.res | Bin 0 -> 264 bytes .../Locale/Resources/data/locales/es_DO.res | Bin 0 -> 140 bytes .../Locale/Resources/data/locales/es_EC.res | Bin 0 -> 776 bytes .../Locale/Resources/data/locales/es_ES.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/es_GQ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/es_GT.res | Bin 0 -> 620 bytes .../Locale/Resources/data/locales/es_HN.res | Bin 0 -> 604 bytes .../Locale/Resources/data/locales/es_MX.res | Bin 0 -> 164 bytes .../Locale/Resources/data/locales/es_NI.res | Bin 0 -> 164 bytes .../Locale/Resources/data/locales/es_PA.res | Bin 0 -> 816 bytes .../Locale/Resources/data/locales/es_PE.res | Bin 0 -> 608 bytes .../Locale/Resources/data/locales/es_PR.res | Bin 0 -> 816 bytes .../Locale/Resources/data/locales/es_PY.res | Bin 0 -> 324 bytes .../Locale/Resources/data/locales/es_SV.res | Bin 0 -> 164 bytes .../Locale/Resources/data/locales/es_US.res | Bin 0 -> 996 bytes .../Locale/Resources/data/locales/es_UY.res | Bin 0 -> 324 bytes .../Locale/Resources/data/locales/es_VE.res | Bin 0 -> 352 bytes .../Locale/Resources/data/locales/et.res | Bin 0 -> 7228 bytes .../Locale/Resources/data/locales/et_EE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/eu.res | Bin 0 -> 4088 bytes .../Locale/Resources/data/locales/eu_ES.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fa.res | Bin 0 -> 11020 bytes .../Locale/Resources/data/locales/fa_AF.res | Bin 0 -> 1636 bytes .../Locale/Resources/data/locales/fa_IR.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ff.res | Bin 0 -> 4256 bytes .../Locale/Resources/data/locales/ff_SN.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fi.res | Bin 0 -> 16744 bytes .../Locale/Resources/data/locales/fi_FI.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fil.res | Bin 0 -> 5588 bytes .../Locale/Resources/data/locales/fil_PH.res | Bin 0 -> 132 bytes .../Locale/Resources/data/locales/fo.res | Bin 0 -> 2448 bytes .../Locale/Resources/data/locales/fo_FO.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr.res | Bin 0 -> 17728 bytes .../Locale/Resources/data/locales/fr_BE.res | Bin 0 -> 612 bytes .../Locale/Resources/data/locales/fr_BF.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_BI.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_BJ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_BL.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_CA.res | Bin 0 -> 2792 bytes .../Locale/Resources/data/locales/fr_CD.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_CF.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_CG.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_CH.res | Bin 0 -> 712 bytes .../Locale/Resources/data/locales/fr_CI.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_CM.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_DJ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_FR.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_GA.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_GN.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_GP.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_GQ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_KM.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_LU.res | Bin 0 -> 176 bytes .../Locale/Resources/data/locales/fr_MC.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_MF.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_MG.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_ML.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_MQ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_NE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_RE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_RW.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_SN.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_TD.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/fr_TG.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ga.res | Bin 0 -> 2496 bytes .../Locale/Resources/data/locales/ga_IE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/gl.res | Bin 0 -> 5492 bytes .../Locale/Resources/data/locales/gl_ES.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/gsw.res | Bin 0 -> 8844 bytes .../Locale/Resources/data/locales/gsw_CH.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/gu.res | Bin 0 -> 4532 bytes .../Locale/Resources/data/locales/gu_IN.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/guz.res | Bin 0 -> 4160 bytes .../Locale/Resources/data/locales/guz_KE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/gv.res | Bin 0 -> 1688 bytes .../Locale/Resources/data/locales/gv_GB.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ha.res | Bin 0 -> 4424 bytes .../Locale/Resources/data/locales/ha_GH.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/ha_Latn.res | Bin 0 -> 148 bytes .../Resources/data/locales/ha_Latn_GH.res | Bin 0 -> 100 bytes .../Resources/data/locales/ha_Latn_NE.res | Bin 0 -> 100 bytes .../Resources/data/locales/ha_Latn_NG.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ha_NE.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/ha_NG.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/haw.res | Bin 0 -> 1976 bytes .../Locale/Resources/data/locales/haw_US.res | Bin 0 -> 152 bytes .../Locale/Resources/data/locales/he.res | Bin 0 -> 15440 bytes .../Locale/Resources/data/locales/he_IL.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/hi.res | Bin 0 -> 17860 bytes .../Locale/Resources/data/locales/hi_IN.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/hr.res | Bin 0 -> 13340 bytes .../Locale/Resources/data/locales/hr_HR.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/hu.res | Bin 0 -> 8940 bytes .../Locale/Resources/data/locales/hu_HU.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/hy.res | Bin 0 -> 2076 bytes .../Locale/Resources/data/locales/hy_AM.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/id.res | Bin 0 -> 6524 bytes .../Locale/Resources/data/locales/id_ID.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ig.res | Bin 0 -> 3784 bytes .../Locale/Resources/data/locales/ig_NG.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ii.res | Bin 0 -> 1804 bytes .../Locale/Resources/data/locales/ii_CN.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/in.res | Bin 0 -> 128 bytes .../Locale/Resources/data/locales/in_ID.res | Bin 0 -> 92 bytes .../Locale/Resources/data/locales/is.res | Bin 0 -> 8028 bytes .../Locale/Resources/data/locales/is_IS.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/it.res | Bin 0 -> 15896 bytes .../Locale/Resources/data/locales/it_CH.res | Bin 0 -> 712 bytes .../Locale/Resources/data/locales/it_IT.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/iw.res | Bin 0 -> 128 bytes .../Locale/Resources/data/locales/iw_IL.res | Bin 0 -> 92 bytes .../Locale/Resources/data/locales/ja.res | Bin 0 -> 22376 bytes .../Locale/Resources/data/locales/ja_JP.res | Bin 0 -> 100 bytes .../data/locales/ja_JP_TRADITIONAL.res | Bin 0 -> 120 bytes .../Locale/Resources/data/locales/jmc.res | Bin 0 -> 3992 bytes .../Locale/Resources/data/locales/jmc_TZ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ka.res | Bin 0 -> 1668 bytes .../Locale/Resources/data/locales/ka_GE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/kab.res | Bin 0 -> 4480 bytes .../Locale/Resources/data/locales/kab_DZ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/kam.res | Bin 0 -> 4308 bytes .../Locale/Resources/data/locales/kam_KE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/kde.res | Bin 0 -> 4516 bytes .../Locale/Resources/data/locales/kde_TZ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/kea.res | Bin 0 -> 4656 bytes .../Locale/Resources/data/locales/kea_CV.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/khq.res | Bin 0 -> 4224 bytes .../Locale/Resources/data/locales/khq_ML.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ki.res | Bin 0 -> 4312 bytes .../Locale/Resources/data/locales/ki_KE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/kk.res | Bin 0 -> 1920 bytes .../Locale/Resources/data/locales/kk_Cyrl.res | Bin 0 -> 148 bytes .../Resources/data/locales/kk_Cyrl_KZ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/kk_KZ.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/kl.res | Bin 0 -> 1580 bytes .../Locale/Resources/data/locales/kl_GL.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/kln.res | Bin 0 -> 4192 bytes .../Locale/Resources/data/locales/kln_KE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/km.res | Bin 0 -> 2376 bytes .../Locale/Resources/data/locales/km_KH.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/kn.res | Bin 0 -> 2920 bytes .../Locale/Resources/data/locales/kn_IN.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ko.res | Bin 0 -> 18568 bytes .../Locale/Resources/data/locales/ko_KR.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/kok.res | Bin 0 -> 1720 bytes .../Locale/Resources/data/locales/kok_IN.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/kw.res | Bin 0 -> 1532 bytes .../Locale/Resources/data/locales/kw_GB.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/lag.res | Bin 0 -> 4172 bytes .../Locale/Resources/data/locales/lag_TZ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/lg.res | Bin 0 -> 4068 bytes .../Locale/Resources/data/locales/lg_UG.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/lt.res | Bin 0 -> 10180 bytes .../Locale/Resources/data/locales/lt_LT.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/luo.res | Bin 0 -> 4300 bytes .../Locale/Resources/data/locales/luo_KE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/luy.res | Bin 0 -> 4160 bytes .../Locale/Resources/data/locales/luy_KE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/lv.res | Bin 0 -> 10496 bytes .../Locale/Resources/data/locales/lv_LV.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/mas.res | Bin 0 -> 4224 bytes .../Locale/Resources/data/locales/mas_KE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/mas_TZ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/mer.res | Bin 0 -> 3964 bytes .../Locale/Resources/data/locales/mer_KE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/mfe.res | Bin 0 -> 3964 bytes .../Locale/Resources/data/locales/mfe_MU.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/mg.res | Bin 0 -> 4172 bytes .../Locale/Resources/data/locales/mg_MG.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/mk.res | Bin 0 -> 7508 bytes .../Locale/Resources/data/locales/mk_MK.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ml.res | Bin 0 -> 9384 bytes .../Locale/Resources/data/locales/ml_IN.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/mo.res | Bin 0 -> 132 bytes .../Locale/Resources/data/locales/mr.res | Bin 0 -> 3964 bytes .../Locale/Resources/data/locales/mr_IN.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ms.res | Bin 0 -> 5348 bytes .../Locale/Resources/data/locales/ms_BN.res | Bin 0 -> 684 bytes .../Locale/Resources/data/locales/ms_MY.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/mt.res | Bin 0 -> 3372 bytes .../Locale/Resources/data/locales/mt_MT.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/my.res | Bin 0 -> 7492 bytes .../Locale/Resources/data/locales/my_MM.res | Bin 0 -> 128 bytes .../Locale/Resources/data/locales/naq.res | Bin 0 -> 4244 bytes .../Locale/Resources/data/locales/naq_NA.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/nb.res | Bin 0 -> 13952 bytes .../Locale/Resources/data/locales/nb_NO.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/nd.res | Bin 0 -> 4024 bytes .../Locale/Resources/data/locales/nd_ZW.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ne.res | Bin 0 -> 2464 bytes .../Locale/Resources/data/locales/ne_IN.res | Bin 0 -> 1864 bytes .../Locale/Resources/data/locales/ne_NP.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/nl.res | Bin 0 -> 15864 bytes .../Locale/Resources/data/locales/nl_BE.res | Bin 0 -> 612 bytes .../Locale/Resources/data/locales/nl_NL.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/nn.res | Bin 0 -> 7236 bytes .../Locale/Resources/data/locales/nn_NO.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/no.res | Bin 0 -> 128 bytes .../Locale/Resources/data/locales/no_NO.res | Bin 0 -> 92 bytes .../Resources/data/locales/no_NO_NY.res | Bin 0 -> 92 bytes .../Locale/Resources/data/locales/nyn.res | Bin 0 -> 4204 bytes .../Locale/Resources/data/locales/nyn_UG.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/om.res | Bin 0 -> 2504 bytes .../Locale/Resources/data/locales/om_ET.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/om_KE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/or.res | Bin 0 -> 2724 bytes .../Locale/Resources/data/locales/or_IN.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/pa.res | Bin 0 -> 3268 bytes .../Locale/Resources/data/locales/pa_Arab.res | Bin 0 -> 2264 bytes .../Resources/data/locales/pa_Arab_PK.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/pa_Guru.res | Bin 0 -> 148 bytes .../Resources/data/locales/pa_Guru_IN.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/pa_IN.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/pa_PK.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/pl.res | Bin 0 -> 15120 bytes .../Locale/Resources/data/locales/pl_PL.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ps.res | Bin 0 -> 2440 bytes .../Locale/Resources/data/locales/ps_AF.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/pt.res | Bin 0 -> 17928 bytes .../Locale/Resources/data/locales/pt_BR.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/pt_GW.res | Bin 0 -> 136 bytes .../Locale/Resources/data/locales/pt_MZ.res | Bin 0 -> 136 bytes .../Locale/Resources/data/locales/pt_PT.res | Bin 0 -> 5400 bytes .../Locale/Resources/data/locales/rm.res | Bin 0 -> 8644 bytes .../Locale/Resources/data/locales/rm_CH.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ro.res | Bin 0 -> 10092 bytes .../Locale/Resources/data/locales/ro_MD.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ro_RO.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/rof.res | Bin 0 -> 4280 bytes .../Locale/Resources/data/locales/rof_TZ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/root.res | Bin 0 -> 43680 bytes .../Locale/Resources/data/locales/ru.res | Bin 0 -> 29220 bytes .../Locale/Resources/data/locales/ru_MD.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ru_RU.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ru_UA.res | Bin 0 -> 528 bytes .../Locale/Resources/data/locales/rw.res | Bin 0 -> 2488 bytes .../Locale/Resources/data/locales/rw_RW.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/rwk.res | Bin 0 -> 3992 bytes .../Locale/Resources/data/locales/rwk_TZ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/saq.res | Bin 0 -> 4328 bytes .../Locale/Resources/data/locales/saq_KE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/seh.res | Bin 0 -> 3960 bytes .../Locale/Resources/data/locales/seh_MZ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ses.res | Bin 0 -> 4232 bytes .../Locale/Resources/data/locales/ses_ML.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/sg.res | Bin 0 -> 4184 bytes .../Locale/Resources/data/locales/sg_CF.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/sh.res | Bin 0 -> 136 bytes .../Locale/Resources/data/locales/sh_BA.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/sh_CS.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/sh_YU.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/shi.res | Bin 0 -> 4072 bytes .../Resources/data/locales/shi_Latn.res | Bin 0 -> 100 bytes .../Resources/data/locales/shi_Latn_MA.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/shi_MA.res | Bin 0 -> 144 bytes .../Resources/data/locales/shi_Tfng.res | Bin 0 -> 4032 bytes .../Resources/data/locales/shi_Tfng_MA.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/si.res | Bin 0 -> 3580 bytes .../Locale/Resources/data/locales/si_LK.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/sk.res | Bin 0 -> 8896 bytes .../Locale/Resources/data/locales/sk_SK.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/sl.res | Bin 0 -> 9360 bytes .../Locale/Resources/data/locales/sl_SI.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/sn.res | Bin 0 -> 3980 bytes .../Locale/Resources/data/locales/sn_ZW.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/so.res | Bin 0 -> 3960 bytes .../Locale/Resources/data/locales/so_DJ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/so_ET.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/so_KE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/so_SO.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/sq.res | Bin 0 -> 4204 bytes .../Locale/Resources/data/locales/sq_AL.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/sr.res | Bin 0 -> 18212 bytes .../Locale/Resources/data/locales/sr_BA.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/sr_CS.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/sr_Cyrl.res | Bin 0 -> 148 bytes .../Resources/data/locales/sr_Cyrl_BA.res | Bin 0 -> 1276 bytes .../Resources/data/locales/sr_Cyrl_CS.res | Bin 0 -> 144 bytes .../Resources/data/locales/sr_Cyrl_ME.res | Bin 0 -> 100 bytes .../Resources/data/locales/sr_Cyrl_RS.res | Bin 0 -> 100 bytes .../Resources/data/locales/sr_Cyrl_YU.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/sr_Latn.res | Bin 0 -> 5972 bytes .../Resources/data/locales/sr_Latn_BA.res | Bin 0 -> 100 bytes .../Resources/data/locales/sr_Latn_CS.res | Bin 0 -> 144 bytes .../Resources/data/locales/sr_Latn_ME.res | Bin 0 -> 628 bytes .../Resources/data/locales/sr_Latn_RS.res | Bin 0 -> 100 bytes .../Resources/data/locales/sr_Latn_YU.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/sr_ME.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/sr_RS.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/sr_YU.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/sv.res | Bin 0 -> 15520 bytes .../Locale/Resources/data/locales/sv_FI.res | Bin 0 -> 284 bytes .../Locale/Resources/data/locales/sv_SE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/sw.res | Bin 0 -> 3884 bytes .../Locale/Resources/data/locales/sw_KE.res | Bin 0 -> 200 bytes .../Locale/Resources/data/locales/sw_TZ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ta.res | Bin 0 -> 3576 bytes .../Locale/Resources/data/locales/ta_IN.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ta_LK.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/te.res | Bin 0 -> 2948 bytes .../Locale/Resources/data/locales/te_IN.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/teo.res | Bin 0 -> 4096 bytes .../Locale/Resources/data/locales/teo_KE.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/teo_UG.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/th.res | Bin 0 -> 26112 bytes .../Locale/Resources/data/locales/th_TH.res | Bin 0 -> 100 bytes .../data/locales/th_TH_TRADITIONAL.res | Bin 0 -> 120 bytes .../Locale/Resources/data/locales/ti.res | Bin 0 -> 2624 bytes .../Locale/Resources/data/locales/ti_ER.res | Bin 0 -> 1348 bytes .../Locale/Resources/data/locales/ti_ET.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/tl.res | Bin 0 -> 128 bytes .../Locale/Resources/data/locales/tl_PH.res | Bin 0 -> 136 bytes .../Locale/Resources/data/locales/to.res | Bin 0 -> 7116 bytes .../Locale/Resources/data/locales/to_TO.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/tr.res | Bin 0 -> 15796 bytes .../Locale/Resources/data/locales/tr_TR.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/tzm.res | Bin 0 -> 4252 bytes .../Resources/data/locales/tzm_Latn.res | Bin 0 -> 148 bytes .../Resources/data/locales/tzm_Latn_MA.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/tzm_MA.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/uk.res | Bin 0 -> 11048 bytes .../Locale/Resources/data/locales/uk_UA.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/ur.res | Bin 0 -> 2552 bytes .../Locale/Resources/data/locales/ur_IN.res | Bin 0 -> 304 bytes .../Locale/Resources/data/locales/ur_PK.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/uz.res | Bin 0 -> 364 bytes .../Locale/Resources/data/locales/uz_AF.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/uz_Arab.res | Bin 0 -> 900 bytes .../Resources/data/locales/uz_Arab_AF.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/uz_Cyrl.res | Bin 0 -> 148 bytes .../Resources/data/locales/uz_Cyrl_UZ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/uz_Latn.res | Bin 0 -> 2336 bytes .../Resources/data/locales/uz_Latn_UZ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/uz_UZ.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/vi.res | Bin 0 -> 12524 bytes .../Locale/Resources/data/locales/vi_VN.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/vun.res | Bin 0 -> 4000 bytes .../Locale/Resources/data/locales/vun_TZ.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/xog.res | Bin 0 -> 4296 bytes .../Locale/Resources/data/locales/xog_UG.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/yo.res | Bin 0 -> 4172 bytes .../Locale/Resources/data/locales/yo_NG.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/zh.res | Bin 0 -> 23112 bytes .../Locale/Resources/data/locales/zh_CN.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/zh_HK.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/zh_Hans.res | Bin 0 -> 148 bytes .../Resources/data/locales/zh_Hans_CN.res | Bin 0 -> 100 bytes .../Resources/data/locales/zh_Hans_HK.res | Bin 0 -> 100 bytes .../Resources/data/locales/zh_Hans_MO.res | Bin 0 -> 100 bytes .../Resources/data/locales/zh_Hans_SG.res | Bin 0 -> 516 bytes .../Locale/Resources/data/locales/zh_Hant.res | Bin 0 -> 23444 bytes .../Resources/data/locales/zh_Hant_HK.res | Bin 0 -> 856 bytes .../Resources/data/locales/zh_Hant_MO.res | Bin 0 -> 512 bytes .../Resources/data/locales/zh_Hant_TW.res | Bin 0 -> 100 bytes .../Locale/Resources/data/locales/zh_MO.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/zh_SG.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/zh_TW.res | Bin 0 -> 144 bytes .../Locale/Resources/data/locales/zu.res | Bin 0 -> 3224 bytes .../Locale/Resources/data/locales/zu_ZA.res | Bin 0 -> 100 bytes .../Locale/Resources/data/names/ar.res | Bin 0 -> 9820 bytes .../Locale/Resources/data/names/bg.res | Bin 0 -> 9476 bytes .../Locale/Resources/data/names/bs.res | Bin 0 -> 9728 bytes .../Locale/Resources/data/names/ca.res | Bin 0 -> 8924 bytes .../Locale/Resources/data/names/da.res | Bin 0 -> 9200 bytes .../Locale/Resources/data/names/de.res | Bin 0 -> 10152 bytes .../Locale/Resources/data/names/de_CH.res | Bin 0 -> 120 bytes .../Locale/Resources/data/names/el.res | Bin 0 -> 9748 bytes .../Locale/Resources/data/names/en.res | Bin 0 -> 9912 bytes .../Locale/Resources/data/names/en_RH.res | Bin 0 -> 9912 bytes .../Locale/Resources/data/names/en_ZW.res | Bin 0 -> 9912 bytes .../Locale/Resources/data/names/es.res | Bin 0 -> 9148 bytes .../Locale/Resources/data/names/es_AR.res | Bin 0 -> 9148 bytes .../Locale/Resources/data/names/es_CL.res | Bin 0 -> 3548 bytes .../Locale/Resources/data/names/et.res | Bin 0 -> 9268 bytes .../Locale/Resources/data/names/fa.res | Bin 0 -> 8816 bytes .../Locale/Resources/data/names/fa_AF.res | Bin 0 -> 1764 bytes .../Locale/Resources/data/names/fi.res | Bin 0 -> 9052 bytes .../Locale/Resources/data/names/fr.res | Bin 0 -> 9136 bytes .../Locale/Resources/data/names/gsw.res | Bin 0 -> 10268 bytes .../Locale/Resources/data/names/gu.res | Bin 0 -> 8932 bytes .../Locale/Resources/data/names/he.res | Bin 0 -> 7996 bytes .../Locale/Resources/data/names/he_IL.res | Bin 0 -> 7996 bytes .../Locale/Resources/data/names/hi.res | Bin 0 -> 8992 bytes .../Locale/Resources/data/names/hr.res | Bin 0 -> 9620 bytes .../Locale/Resources/data/names/hu.res | Bin 0 -> 8720 bytes .../Locale/Resources/data/names/it.res | Bin 0 -> 9408 bytes .../Locale/Resources/data/names/iw.res | Bin 0 -> 7996 bytes .../Locale/Resources/data/names/iw_IL.res | Bin 0 -> 7996 bytes .../Locale/Resources/data/names/ja.res | Bin 0 -> 7404 bytes .../Locale/Resources/data/names/ja_JP.res | Bin 0 -> 7404 bytes .../data/names/ja_JP_TRADITIONAL.res | Bin 0 -> 7404 bytes .../Locale/Resources/data/names/ko.res | Bin 0 -> 6852 bytes .../Locale/Resources/data/names/lt.res | Bin 0 -> 8992 bytes .../Locale/Resources/data/names/lv.res | Bin 0 -> 9108 bytes .../Locale/Resources/data/names/mk.res | Bin 0 -> 9724 bytes .../Locale/Resources/data/names/ml.res | Bin 0 -> 9796 bytes .../Locale/Resources/data/names/mo.res | Bin 0 -> 8276 bytes .../Locale/Resources/data/names/mr.res | Bin 0 -> 8928 bytes .../Locale/Resources/data/names/mt.res | Bin 0 -> 8488 bytes .../Locale/Resources/data/names/my.res | Bin 0 -> 6844 bytes .../Locale/Resources/data/names/nb.res | Bin 0 -> 9228 bytes .../Locale/Resources/data/names/nb_NO.res | Bin 0 -> 9228 bytes .../Locale/Resources/data/names/ne.res | Bin 0 -> 856 bytes .../Locale/Resources/data/names/nl.res | Bin 0 -> 9272 bytes .../Locale/Resources/data/names/nl_BE.res | Bin 0 -> 104 bytes .../Locale/Resources/data/names/nn.res | Bin 0 -> 9216 bytes .../Locale/Resources/data/names/nn_NO.res | Bin 0 -> 9216 bytes .../Locale/Resources/data/names/no.res | Bin 0 -> 9228 bytes .../Locale/Resources/data/names/no_NO.res | Bin 0 -> 9228 bytes .../Locale/Resources/data/names/no_NO_NY.res | Bin 0 -> 9216 bytes .../Locale/Resources/data/names/pl.res | Bin 0 -> 9636 bytes .../Locale/Resources/data/names/pt.res | Bin 0 -> 9104 bytes .../Locale/Resources/data/names/pt_PT.res | Bin 0 -> 688 bytes .../Locale/Resources/data/names/rm.res | Bin 0 -> 9188 bytes .../Locale/Resources/data/names/ro.res | Bin 0 -> 8276 bytes .../Locale/Resources/data/names/ro_MD.res | Bin 0 -> 8276 bytes .../Locale/Resources/data/names/ru.res | Bin 0 -> 10080 bytes .../Locale/Resources/data/names/sh.res | Bin 0 -> 9592 bytes .../Locale/Resources/data/names/sh_BA.res | Bin 0 -> 9592 bytes .../Locale/Resources/data/names/sh_CS.res | Bin 0 -> 9592 bytes .../Locale/Resources/data/names/sh_YU.res | Bin 0 -> 9592 bytes .../Locale/Resources/data/names/sl.res | Bin 0 -> 10560 bytes .../Locale/Resources/data/names/sr.res | Bin 0 -> 9540 bytes .../Locale/Resources/data/names/sr_BA.res | Bin 0 -> 9540 bytes .../Locale/Resources/data/names/sr_CS.res | Bin 0 -> 9540 bytes .../Locale/Resources/data/names/sr_Cyrl.res | Bin 0 -> 9540 bytes .../Resources/data/names/sr_Cyrl_BA.res | Bin 0 -> 9540 bytes .../Resources/data/names/sr_Cyrl_CS.res | Bin 0 -> 9540 bytes .../Resources/data/names/sr_Cyrl_RS.res | Bin 0 -> 9540 bytes .../Resources/data/names/sr_Cyrl_YU.res | Bin 0 -> 9540 bytes .../Locale/Resources/data/names/sr_Latn.res | Bin 0 -> 9592 bytes .../Resources/data/names/sr_Latn_BA.res | Bin 0 -> 9592 bytes .../Resources/data/names/sr_Latn_CS.res | Bin 0 -> 9592 bytes .../Resources/data/names/sr_Latn_ME.res | Bin 0 -> 9592 bytes .../Resources/data/names/sr_Latn_RS.res | Bin 0 -> 9592 bytes .../Resources/data/names/sr_Latn_YU.res | Bin 0 -> 9592 bytes .../Locale/Resources/data/names/sr_ME.res | Bin 0 -> 9592 bytes .../Locale/Resources/data/names/sr_RS.res | Bin 0 -> 9540 bytes .../Locale/Resources/data/names/sr_YU.res | Bin 0 -> 9540 bytes .../Locale/Resources/data/names/sv.res | Bin 0 -> 9476 bytes .../Locale/Resources/data/names/sv_FI.res | Bin 0 -> 4548 bytes .../Locale/Resources/data/names/ta.res | Bin 0 -> 9712 bytes .../Locale/Resources/data/names/te.res | Bin 0 -> 9356 bytes .../Locale/Resources/data/names/th.res | Bin 0 -> 8820 bytes .../Locale/Resources/data/names/th_TH.res | Bin 0 -> 8820 bytes .../data/names/th_TH_TRADITIONAL.res | Bin 0 -> 8820 bytes .../Locale/Resources/data/names/tr.res | Bin 0 -> 9516 bytes .../Locale/Resources/data/names/uk.res | Bin 0 -> 9752 bytes .../Locale/Resources/data/names/zh.res | Bin 0 -> 6592 bytes .../Locale/Resources/data/names/zh_CN.res | Bin 0 -> 6592 bytes .../Locale/Resources/data/names/zh_HK.res | Bin 0 -> 144 bytes .../Locale/Resources/data/names/zh_Hans.res | Bin 0 -> 6592 bytes .../Resources/data/names/zh_Hans_CN.res | Bin 0 -> 6592 bytes .../Resources/data/names/zh_Hans_SG.res | Bin 0 -> 6592 bytes .../Locale/Resources/data/names/zh_Hant.res | Bin 0 -> 6516 bytes .../Resources/data/names/zh_Hant_HK.res | Bin 0 -> 144 bytes .../Resources/data/names/zh_Hant_MO.res | Bin 0 -> 6516 bytes .../Resources/data/names/zh_Hant_TW.res | Bin 0 -> 6516 bytes .../Locale/Resources/data/names/zh_MO.res | Bin 0 -> 6516 bytes .../Locale/Resources/data/names/zh_SG.res | Bin 0 -> 6592 bytes .../Locale/Resources/data/names/zh_TW.res | Bin 0 -> 6516 bytes .../Locale/Resources/data/region/af.res | Bin 0 -> 9136 bytes .../Locale/Resources/data/region/ak.res | Bin 0 -> 7832 bytes .../Locale/Resources/data/region/am.res | Bin 0 -> 6240 bytes .../Locale/Resources/data/region/ar.res | Bin 0 -> 10292 bytes .../Locale/Resources/data/region/as.res | Bin 0 -> 868 bytes .../Locale/Resources/data/region/asa.res | Bin 0 -> 8040 bytes .../Locale/Resources/data/region/az.res | Bin 0 -> 10272 bytes .../Locale/Resources/data/region/az_AZ.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/az_Cyrl.res | Bin 0 -> 468 bytes .../Locale/Resources/data/region/az_Latn.res | Bin 0 -> 100 bytes .../Resources/data/region/az_Latn_AZ.res | Bin 0 -> 80 bytes .../Locale/Resources/data/region/be.res | Bin 0 -> 10476 bytes .../Locale/Resources/data/region/bem.res | Bin 0 -> 152 bytes .../Locale/Resources/data/region/bez.res | Bin 0 -> 8932 bytes .../Locale/Resources/data/region/bg.res | Bin 0 -> 11192 bytes .../Locale/Resources/data/region/bm.res | Bin 0 -> 7832 bytes .../Locale/Resources/data/region/bn.res | Bin 0 -> 11176 bytes .../Locale/Resources/data/region/bo.res | Bin 0 -> 488 bytes .../Locale/Resources/data/region/bs.res | Bin 0 -> 10672 bytes .../Locale/Resources/data/region/ca.res | Bin 0 -> 11048 bytes .../Locale/Resources/data/region/cgg.res | Bin 0 -> 8340 bytes .../Locale/Resources/data/region/chr.res | Bin 0 -> 520 bytes .../Locale/Resources/data/region/cs.res | Bin 0 -> 10616 bytes .../Locale/Resources/data/region/cy.res | Bin 0 -> 164 bytes .../Locale/Resources/data/region/da.res | Bin 0 -> 10684 bytes .../Locale/Resources/data/region/dav.res | Bin 0 -> 7960 bytes .../Locale/Resources/data/region/de.res | Bin 0 -> 11084 bytes .../Locale/Resources/data/region/de_CH.res | Bin 0 -> 632 bytes .../Locale/Resources/data/region/ebu.res | Bin 0 -> 7960 bytes .../Locale/Resources/data/region/ee.res | Bin 0 -> 8912 bytes .../Locale/Resources/data/region/el.res | Bin 0 -> 11104 bytes .../Locale/Resources/data/region/en.res | Bin 0 -> 10912 bytes .../Locale/Resources/data/region/en_RH.res | Bin 0 -> 92 bytes .../Locale/Resources/data/region/en_ZW.res | Bin 0 -> 80 bytes .../Locale/Resources/data/region/eo.res | Bin 0 -> 7840 bytes .../Locale/Resources/data/region/es.res | Bin 0 -> 11184 bytes .../Locale/Resources/data/region/es_CL.res | Bin 0 -> 212 bytes .../Locale/Resources/data/region/et.res | Bin 0 -> 10680 bytes .../Locale/Resources/data/region/eu.res | Bin 0 -> 8772 bytes .../Locale/Resources/data/region/fa.res | Bin 0 -> 10052 bytes .../Locale/Resources/data/region/fa_AF.res | Bin 0 -> 3200 bytes .../Locale/Resources/data/region/ff.res | Bin 0 -> 8060 bytes .../Locale/Resources/data/region/fi.res | Bin 0 -> 10800 bytes .../Locale/Resources/data/region/fil.res | Bin 0 -> 4776 bytes .../Locale/Resources/data/region/fil_PH.res | Bin 0 -> 80 bytes .../Locale/Resources/data/region/fo.res | Bin 0 -> 4424 bytes .../Locale/Resources/data/region/fr.res | Bin 0 -> 11264 bytes .../Locale/Resources/data/region/ga.res | Bin 0 -> 11016 bytes .../Locale/Resources/data/region/gl.res | Bin 0 -> 10468 bytes .../Locale/Resources/data/region/gsw.res | Bin 0 -> 11124 bytes .../Locale/Resources/data/region/gu.res | Bin 0 -> 11008 bytes .../Locale/Resources/data/region/guz.res | Bin 0 -> 7960 bytes .../Locale/Resources/data/region/gv.res | Bin 0 -> 168 bytes .../Locale/Resources/data/region/ha.res | Bin 0 -> 7996 bytes .../Locale/Resources/data/region/ha_GH.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/ha_Latn.res | Bin 0 -> 100 bytes .../Resources/data/region/ha_Latn_GH.res | Bin 0 -> 80 bytes .../Resources/data/region/ha_Latn_NE.res | Bin 0 -> 80 bytes .../Resources/data/region/ha_Latn_NG.res | Bin 0 -> 80 bytes .../Locale/Resources/data/region/ha_NE.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/ha_NG.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/haw.res | Bin 0 -> 792 bytes .../Locale/Resources/data/region/he.res | Bin 0 -> 9656 bytes .../Locale/Resources/data/region/he_IL.res | Bin 0 -> 80 bytes .../Locale/Resources/data/region/hi.res | Bin 0 -> 10524 bytes .../Locale/Resources/data/region/hr.res | Bin 0 -> 10964 bytes .../Locale/Resources/data/region/hu.res | Bin 0 -> 11184 bytes .../Locale/Resources/data/region/hy.res | Bin 0 -> 6540 bytes .../Locale/Resources/data/region/id.res | Bin 0 -> 8832 bytes .../Locale/Resources/data/region/id_ID.res | Bin 0 -> 80 bytes .../Locale/Resources/data/region/ig.res | Bin 0 -> 356 bytes .../Locale/Resources/data/region/ii.res | Bin 0 -> 360 bytes .../Locale/Resources/data/region/in.res | Bin 0 -> 128 bytes .../Locale/Resources/data/region/in_ID.res | Bin 0 -> 92 bytes .../Locale/Resources/data/region/is.res | Bin 0 -> 10112 bytes .../Locale/Resources/data/region/it.res | Bin 0 -> 11096 bytes .../Locale/Resources/data/region/iw.res | Bin 0 -> 128 bytes .../Locale/Resources/data/region/iw_IL.res | Bin 0 -> 92 bytes .../Locale/Resources/data/region/ja.res | Bin 0 -> 8088 bytes .../Locale/Resources/data/region/ja_JP.res | Bin 0 -> 80 bytes .../data/region/ja_JP_TRADITIONAL.res | Bin 0 -> 120 bytes .../Locale/Resources/data/region/jmc.res | Bin 0 -> 7960 bytes .../Locale/Resources/data/region/ka.res | Bin 0 -> 10360 bytes .../Locale/Resources/data/region/kab.res | Bin 0 -> 7816 bytes .../Locale/Resources/data/region/kam.res | Bin 0 -> 7972 bytes .../Locale/Resources/data/region/kde.res | Bin 0 -> 8096 bytes .../Locale/Resources/data/region/kea.res | Bin 0 -> 7760 bytes .../Locale/Resources/data/region/khq.res | Bin 0 -> 7956 bytes .../Locale/Resources/data/region/ki.res | Bin 0 -> 7980 bytes .../Locale/Resources/data/region/kk.res | Bin 0 -> 156 bytes .../Locale/Resources/data/region/kk_Cyrl.res | Bin 0 -> 100 bytes .../Resources/data/region/kk_Cyrl_KZ.res | Bin 0 -> 80 bytes .../Locale/Resources/data/region/kk_KZ.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/kl.res | Bin 0 -> 172 bytes .../Locale/Resources/data/region/kln.res | Bin 0 -> 11140 bytes .../Locale/Resources/data/region/km.res | Bin 0 -> 6220 bytes .../Locale/Resources/data/region/kn.res | Bin 0 -> 11184 bytes .../Locale/Resources/data/region/ko.res | Bin 0 -> 7364 bytes .../Locale/Resources/data/region/kok.res | Bin 0 -> 148 bytes .../Locale/Resources/data/region/kw.res | Bin 0 -> 168 bytes .../Locale/Resources/data/region/lag.res | Bin 0 -> 8484 bytes .../Locale/Resources/data/region/lg.res | Bin 0 -> 8524 bytes .../Locale/Resources/data/region/lt.res | Bin 0 -> 11332 bytes .../Locale/Resources/data/region/luo.res | Bin 0 -> 7920 bytes .../Locale/Resources/data/region/luy.res | Bin 0 -> 7964 bytes .../Locale/Resources/data/region/lv.res | Bin 0 -> 11104 bytes .../Locale/Resources/data/region/mas.res | Bin 0 -> 7960 bytes .../Locale/Resources/data/region/mer.res | Bin 0 -> 8008 bytes .../Locale/Resources/data/region/mfe.res | Bin 0 -> 7608 bytes .../Locale/Resources/data/region/mg.res | Bin 0 -> 7916 bytes .../Locale/Resources/data/region/mk.res | Bin 0 -> 11044 bytes .../Locale/Resources/data/region/ml.res | Bin 0 -> 11736 bytes .../Locale/Resources/data/region/mo.res | Bin 0 -> 132 bytes .../Locale/Resources/data/region/mr.res | Bin 0 -> 10804 bytes .../Locale/Resources/data/region/ms.res | Bin 0 -> 8680 bytes .../Locale/Resources/data/region/mt.res | Bin 0 -> 10352 bytes .../Locale/Resources/data/region/my.res | Bin 0 -> 8260 bytes .../Locale/Resources/data/region/naq.res | Bin 0 -> 8264 bytes .../Locale/Resources/data/region/nb.res | Bin 0 -> 10528 bytes .../Locale/Resources/data/region/nb_NO.res | Bin 0 -> 80 bytes .../Locale/Resources/data/region/nd.res | Bin 0 -> 8156 bytes .../Locale/Resources/data/region/ne.res | Bin 0 -> 10532 bytes .../Locale/Resources/data/region/nl.res | Bin 0 -> 10988 bytes .../Locale/Resources/data/region/nl_BE.res | Bin 0 -> 168 bytes .../Locale/Resources/data/region/nn.res | Bin 0 -> 10580 bytes .../Locale/Resources/data/region/nn_NO.res | Bin 0 -> 80 bytes .../Locale/Resources/data/region/no.res | Bin 0 -> 128 bytes .../Locale/Resources/data/region/no_NO.res | Bin 0 -> 92 bytes .../Locale/Resources/data/region/no_NO_NY.res | Bin 0 -> 92 bytes .../Locale/Resources/data/region/nyn.res | Bin 0 -> 8460 bytes .../Locale/Resources/data/region/om.res | Bin 0 -> 496 bytes .../Locale/Resources/data/region/or.res | Bin 0 -> 10980 bytes .../Locale/Resources/data/region/pa.res | Bin 0 -> 148 bytes .../Locale/Resources/data/region/pa_Arab.res | Bin 0 -> 152 bytes .../Resources/data/region/pa_Arab_PK.res | Bin 0 -> 80 bytes .../Locale/Resources/data/region/pa_Guru.res | Bin 0 -> 100 bytes .../Resources/data/region/pa_Guru_IN.res | Bin 0 -> 80 bytes .../Locale/Resources/data/region/pa_IN.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/pa_PK.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/pl.res | Bin 0 -> 11112 bytes .../Locale/Resources/data/region/ps.res | Bin 0 -> 1896 bytes .../Locale/Resources/data/region/pt.res | Bin 0 -> 11016 bytes .../Locale/Resources/data/region/pt_PT.res | Bin 0 -> 2776 bytes .../Locale/Resources/data/region/rm.res | Bin 0 -> 11048 bytes .../Locale/Resources/data/region/ro.res | Bin 0 -> 11224 bytes .../Locale/Resources/data/region/ro_MD.res | Bin 0 -> 80 bytes .../Locale/Resources/data/region/rof.res | Bin 0 -> 7952 bytes .../Locale/Resources/data/region/root.res | Bin 0 -> 100 bytes .../Locale/Resources/data/region/ru.res | Bin 0 -> 11212 bytes .../Locale/Resources/data/region/rw.res | Bin 0 -> 184 bytes .../Locale/Resources/data/region/rwk.res | Bin 0 -> 7960 bytes .../Locale/Resources/data/region/saq.res | Bin 0 -> 7960 bytes .../Locale/Resources/data/region/seh.res | Bin 0 -> 7852 bytes .../Locale/Resources/data/region/ses.res | Bin 0 -> 7956 bytes .../Locale/Resources/data/region/sg.res | Bin 0 -> 8168 bytes .../Locale/Resources/data/region/sh.res | Bin 0 -> 136 bytes .../Locale/Resources/data/region/sh_BA.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/sh_CS.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/sh_YU.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/shi.res | Bin 0 -> 7792 bytes .../Locale/Resources/data/region/shi_Latn.res | Bin 0 -> 100 bytes .../Resources/data/region/shi_Latn_MA.res | Bin 0 -> 80 bytes .../Locale/Resources/data/region/shi_MA.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/shi_Tfng.res | Bin 0 -> 7792 bytes .../Locale/Resources/data/region/si.res | Bin 0 -> 216 bytes .../Locale/Resources/data/region/sk.res | Bin 0 -> 11004 bytes .../Locale/Resources/data/region/sl.res | Bin 0 -> 11164 bytes .../Locale/Resources/data/region/sn.res | Bin 0 -> 7968 bytes .../Locale/Resources/data/region/so.res | Bin 0 -> 8432 bytes .../Locale/Resources/data/region/sq.res | Bin 0 -> 5484 bytes .../Locale/Resources/data/region/sr.res | Bin 0 -> 10952 bytes .../Locale/Resources/data/region/sr_BA.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/sr_CS.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/sr_Cyrl.res | Bin 0 -> 100 bytes .../Resources/data/region/sr_Cyrl_BA.res | Bin 0 -> 80 bytes .../Resources/data/region/sr_Cyrl_CS.res | Bin 0 -> 144 bytes .../Resources/data/region/sr_Cyrl_RS.res | Bin 0 -> 80 bytes .../Resources/data/region/sr_Cyrl_YU.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/sr_Latn.res | Bin 0 -> 10676 bytes .../Resources/data/region/sr_Latn_BA.res | Bin 0 -> 80 bytes .../Resources/data/region/sr_Latn_CS.res | Bin 0 -> 144 bytes .../Resources/data/region/sr_Latn_ME.res | Bin 0 -> 80 bytes .../Resources/data/region/sr_Latn_RS.res | Bin 0 -> 80 bytes .../Resources/data/region/sr_Latn_YU.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/sr_ME.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/sr_RS.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/sr_YU.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/sv.res | Bin 0 -> 10628 bytes .../Locale/Resources/data/region/sv_FI.res | Bin 0 -> 168 bytes .../Locale/Resources/data/region/sw.res | Bin 0 -> 7960 bytes .../Locale/Resources/data/region/ta.res | Bin 0 -> 11752 bytes .../Locale/Resources/data/region/te.res | Bin 0 -> 11328 bytes .../Locale/Resources/data/region/teo.res | Bin 0 -> 7960 bytes .../Locale/Resources/data/region/th.res | Bin 0 -> 10792 bytes .../Locale/Resources/data/region/th_TH.res | Bin 0 -> 80 bytes .../data/region/th_TH_TRADITIONAL.res | Bin 0 -> 120 bytes .../Locale/Resources/data/region/ti.res | Bin 0 -> 100 bytes .../Locale/Resources/data/region/tl.res | Bin 0 -> 128 bytes .../Locale/Resources/data/region/tl_PH.res | Bin 0 -> 136 bytes .../Locale/Resources/data/region/to.res | Bin 0 -> 11148 bytes .../Locale/Resources/data/region/tr.res | Bin 0 -> 10852 bytes .../Locale/Resources/data/region/tzm.res | Bin 0 -> 7996 bytes .../Locale/Resources/data/region/tzm_Latn.res | Bin 0 -> 100 bytes .../Resources/data/region/tzm_Latn_MA.res | Bin 0 -> 80 bytes .../Locale/Resources/data/region/tzm_MA.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/uk.res | Bin 0 -> 11064 bytes .../Locale/Resources/data/region/ur.res | Bin 0 -> 176 bytes .../Locale/Resources/data/region/uz.res | Bin 0 -> 160 bytes .../Locale/Resources/data/region/uz_AF.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/uz_Arab.res | Bin 0 -> 156 bytes .../Resources/data/region/uz_Arab_AF.res | Bin 0 -> 80 bytes .../Locale/Resources/data/region/uz_Cyrl.res | Bin 0 -> 100 bytes .../Resources/data/region/uz_Cyrl_UZ.res | Bin 0 -> 80 bytes .../Locale/Resources/data/region/uz_Latn.res | Bin 0 -> 548 bytes .../Locale/Resources/data/region/uz_UZ.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/vi.res | Bin 0 -> 10300 bytes .../Locale/Resources/data/region/vun.res | Bin 0 -> 7960 bytes .../Locale/Resources/data/region/xog.res | Bin 0 -> 8472 bytes .../Locale/Resources/data/region/yo.res | Bin 0 -> 12388 bytes .../Locale/Resources/data/region/zh.res | Bin 0 -> 7044 bytes .../Locale/Resources/data/region/zh_CN.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/zh_HK.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/zh_Hans.res | Bin 0 -> 100 bytes .../Resources/data/region/zh_Hans_CN.res | Bin 0 -> 80 bytes .../Resources/data/region/zh_Hans_SG.res | Bin 0 -> 80 bytes .../Locale/Resources/data/region/zh_Hant.res | Bin 0 -> 6736 bytes .../Resources/data/region/zh_Hant_HK.res | Bin 0 -> 80 bytes .../Resources/data/region/zh_Hant_MO.res | Bin 0 -> 80 bytes .../Resources/data/region/zh_Hant_TW.res | Bin 0 -> 80 bytes .../Locale/Resources/data/region/zh_MO.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/zh_SG.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/zh_TW.res | Bin 0 -> 144 bytes .../Locale/Resources/data/region/zu.res | Bin 0 -> 172 bytes .../Locale/Resources/data/stub/curr/en.php | 1771 ++++++++++ .../Locale/Resources/data/stub/lang/en.php | 556 +++ .../Locale/Resources/data/stub/names/en.php | 248 ++ .../Locale/Resources/data/stub/region/en.php | 268 ++ .../Locale/Resources/data/update-data.php | 499 +++ .../Locale/Resources/stubs/Collator.php | 23 + .../Resources/stubs/IntlDateFormatter.php | 23 + .../Locale/Resources/stubs/Locale.php | 23 + .../Resources/stubs/NumberFormatter.php | 23 + .../Locale/Resources/stubs/functions.php | 63 + .../Stub/DateFormat/AmPmTransformer.php | 46 + .../Stub/DateFormat/DayOfWeekTransformer.php | 59 + .../Stub/DateFormat/DayOfYearTransformer.php | 46 + .../Locale/Stub/DateFormat/DayTransformer.php | 46 + .../Stub/DateFormat/FullTransformer.php | 345 ++ .../Stub/DateFormat/Hour1200Transformer.php | 62 + .../Stub/DateFormat/Hour1201Transformer.php | 62 + .../Stub/DateFormat/Hour2400Transformer.php | 61 + .../Stub/DateFormat/Hour2401Transformer.php | 64 + .../Stub/DateFormat/HourTransformer.php | 30 + .../Stub/DateFormat/MinuteTransformer.php | 48 + .../Stub/DateFormat/MonthTransformer.php | 144 + .../Stub/DateFormat/QuarterTransformer.php | 64 + .../Stub/DateFormat/SecondTransformer.php | 48 + .../Stub/DateFormat/TimeZoneTransformer.php | 96 + .../Locale/Stub/DateFormat/Transformer.php | 64 + .../Stub/DateFormat/YearTransformer.php | 50 + .../Component/Locale/Stub/StubCollator.php | 280 ++ .../Component/Locale/Stub/StubIntl.php | 135 + .../Locale/Stub/StubIntlDateFormatter.php | 523 +++ .../Component/Locale/Stub/StubLocale.php | 493 +++ .../Locale/Stub/StubNumberFormatter.php | 883 +++++ .../Component/Locale/Tests/LocaleTest.php | 51 + .../Locale/Tests/Stub/StubCollatorTest.php | 154 + .../Tests/Stub/StubIntlDateFormatterTest.php | 1003 ++++++ .../Locale/Tests/Stub/StubIntlTest.php | 49 + .../Locale/Tests/Stub/StubLocaleTest.php | 252 ++ .../Tests/Stub/StubNumberFormatterTest.php | 1136 ++++++ .../Component/Locale/Tests/TestCase.php | 120 + .../Component/Locale/Tests/bootstrap.php | 26 + .../Symfony/Component/Locale/composer.json | 33 + .../Symfony/Component/Locale/phpunit.xml.dist | 30 + .../Exception/ExceptionInterface.php | 21 + .../Exception/InvalidOptionsException.php | 21 + .../Exception/MissingOptionsException.php | 21 + .../Exception/OptionDefinitionException.php | 21 + .../Symfony/Component/OptionsResolver/LICENSE | 19 + .../Component/OptionsResolver/LazyOption.php | 69 + .../Component/OptionsResolver/Options.php | 436 +++ .../OptionsResolver/OptionsResolver.php | 343 ++ .../OptionsResolverInterface.php | 210 ++ .../Component/OptionsResolver/README.md | 104 + .../Tests/OptionsResolverTest.php | 615 ++++ .../OptionsResolver/Tests/OptionsTest.php | 300 ++ .../OptionsResolver/Tests/bootstrap.php | 18 + .../Component/OptionsResolver/composer.json | 30 + .../OptionsResolver/phpunit.xml.dist | 29 + .../Symfony/Component/Process/CHANGELOG.md | 11 + .../Process/Exception/ExceptionInterface.php | 21 + .../Exception/ProcessFailedException.php | 45 + .../Process/Exception/RuntimeException.php | 21 + .../Component/Process/ExecutableFinder.php | 81 + .../src/Symfony/Component/Process/LICENSE | 19 + .../Component/Process/PhpExecutableFinder.php | 64 + .../Symfony/Component/Process/PhpProcess.php | 78 + .../src/Symfony/Component/Process/Process.php | 730 ++++ .../Component/Process/ProcessBuilder.php | 116 + .../src/Symfony/Component/Process/README.md | 45 + .../Process/Tests/PhpExecutableFinderTest.php | 64 + .../Process/Tests/ProcessBuilderTest.php | 86 + .../Tests/ProcessFailedExceptionTest.php | 75 + .../Component/Process/Tests/ProcessTest.php | 193 + .../Process/Tests/ProcessTestHelper.php | 63 + .../Component/Process/Tests/bootstrap.php | 18 + .../Symfony/Component/Process/composer.json | 30 + .../Component/Process/phpunit.xml.dist | 28 + .../Component/Routing/Annotation/Route.php | 103 + .../Symfony/Component/Routing/CHANGELOG.md | 26 + .../Component/Routing/CompiledRoute.php | 134 + .../Routing/Exception/ExceptionInterface.php | 23 + .../Exception/InvalidParameterException.php | 23 + .../Exception/MethodNotAllowedException.php | 38 + .../MissingMandatoryParametersException.php | 24 + .../Exception/ResourceNotFoundException.php | 25 + .../Exception/RouteNotFoundException.php | 23 + .../Generator/Dumper/GeneratorDumper.php | 42 + .../Dumper/GeneratorDumperInterface.php | 41 + .../Generator/Dumper/PhpGeneratorDumper.php | 124 + .../Routing/Generator/UrlGenerator.php | 191 + .../Generator/UrlGeneratorInterface.php | 43 + .../src/Symfony/Component/Routing/LICENSE | 19 + .../Routing/Loader/AnnotationClassLoader.php | 204 ++ .../Loader/AnnotationDirectoryLoader.php | 77 + .../Routing/Loader/AnnotationFileLoader.php | 120 + .../Routing/Loader/ClosureLoader.php | 49 + .../Routing/Loader/PhpFileLoader.php | 59 + .../Routing/Loader/XmlFileLoader.php | 227 ++ .../Routing/Loader/YamlFileLoader.php | 141 + .../Loader/schema/routing/routing-1.0.xsd | 44 + .../Routing/Matcher/ApacheUrlMatcher.php | 73 + .../Matcher/Dumper/ApacheMatcherDumper.php | 165 + .../Routing/Matcher/Dumper/MatcherDumper.php | 42 + .../Matcher/Dumper/MatcherDumperInterface.php | 37 + .../Matcher/Dumper/PhpMatcherDumper.php | 293 ++ .../Matcher/RedirectableUrlMatcher.php | 61 + .../RedirectableUrlMatcherInterface.php | 35 + .../Matcher/RequestMatcherInterface.php | 40 + .../Routing/Matcher/TraceableUrlMatcher.php | 121 + .../Component/Routing/Matcher/UrlMatcher.php | 186 + .../Routing/Matcher/UrlMatcherInterface.php | 43 + .../src/Symfony/Component/Routing/README.md | 37 + .../Component/Routing/RequestContext.php | 262 ++ .../Routing/RequestContextAwareInterface.php | 36 + .../src/Symfony/Component/Routing/Route.php | 372 ++ .../Component/Routing/RouteCollection.php | 329 ++ .../Component/Routing/RouteCompiler.php | 134 + .../Routing/RouteCompilerInterface.php | 29 + .../src/Symfony/Component/Routing/Router.php | 253 ++ .../Component/Routing/RouterInterface.php | 32 + .../Routing/Tests/Annotation/RouteTest.php | 46 + .../Routing/Tests/CompiledRouteTest.php | 43 + .../AnnotatedClasses/AbstractClass.php | 16 + .../Fixtures/AnnotatedClasses/FooClass.php | 16 + .../Tests/Fixtures/CustomXmlFileLoader.php | 25 + .../Tests/Fixtures/RedirectableUrlMatcher.php | 30 + .../Routing/Tests/Fixtures/annotated.php | 0 .../Tests/Fixtures/dumper/url_matcher1.apache | 71 + .../Tests/Fixtures/dumper/url_matcher1.php | 239 ++ .../Tests/Fixtures/dumper/url_matcher2.apache | 7 + .../Tests/Fixtures/dumper/url_matcher2.php | 269 ++ .../Tests/Fixtures/dumper/url_matcher3.php | 45 + .../Routing/Tests/Fixtures/empty.yml | 0 .../Component/Routing/Tests/Fixtures/foo.xml | 0 .../Component/Routing/Tests/Fixtures/foo1.xml | 0 .../Routing/Tests/Fixtures/incomplete.yml | 2 + .../Routing/Tests/Fixtures/nonvalid.xml | 12 + .../Routing/Tests/Fixtures/nonvalid.yml | 1 + .../Routing/Tests/Fixtures/nonvalidkeys.yml | 3 + .../Routing/Tests/Fixtures/nonvalidnode.xml | 8 + .../Routing/Tests/Fixtures/nonvalidroute.xml | 13 + .../Routing/Tests/Fixtures/validpattern.php | 13 + .../Routing/Tests/Fixtures/validpattern.xml | 12 + .../Routing/Tests/Fixtures/validpattern.yml | 6 + .../Routing/Tests/Fixtures/validresource.xml | 12 + .../Routing/Tests/Fixtures/validresource.yml | 6 + .../Dumper/PhpGeneratorDumperTest.php | 117 + .../Tests/Generator/UrlGeneratorTest.php | 251 ++ .../Loader/AbstractAnnotationLoaderTest.php | 39 + .../Loader/AnnotationClassLoaderTest.php | 74 + .../Loader/AnnotationDirectoryLoaderTest.php | 50 + .../Tests/Loader/AnnotationFileLoaderTest.php | 50 + .../Tests/Loader/ClosureLoaderTest.php | 61 + .../Tests/Loader/PhpFileLoaderTest.php | 53 + .../Tests/Loader/XmlFileLoaderTest.php | 91 + .../Tests/Loader/YamlFileLoaderTest.php | 115 + .../Tests/Matcher/ApacheUrlMatcherTest.php | 69 + .../Dumper/ApacheMatcherDumperTest.php | 125 + .../Matcher/Dumper/PhpMatcherDumperTest.php | 203 ++ .../Matcher/RedirectableUrlMatcherTest.php | 44 + .../Tests/Matcher/TraceableUrlMatcherTest.php | 60 + .../Routing/Tests/Matcher/UrlMatcherTest.php | 245 ++ .../Routing/Tests/RouteCollectionTest.php | 279 ++ .../Routing/Tests/RouteCompilerTest.php | 136 + .../Component/Routing/Tests/RouteTest.php | 127 + .../Component/Routing/Tests/bootstrap.php | 22 + .../Symfony/Component/Routing/composer.json | 41 + .../Component/Routing/phpunit.xml.dist | 29 + .../Security/Acl/Dbal/AclProvider.php | 637 ++++ .../Security/Acl/Dbal/MutableAclProvider.php | 881 +++++ .../Component/Security/Acl/Dbal/Schema.php | 154 + .../Component/Security/Acl/Domain/Acl.php | 666 ++++ .../Acl/Domain/AclCollectionCache.php | 64 + .../Security/Acl/Domain/AuditLogger.php | 51 + .../Security/Acl/Domain/DoctrineAclCache.php | 221 ++ .../Component/Security/Acl/Domain/Entry.php | 208 ++ .../Security/Acl/Domain/FieldEntry.php | 74 + .../Security/Acl/Domain/ObjectIdentity.php | 110 + .../ObjectIdentityRetrievalStrategy.php | 35 + .../Acl/Domain/PermissionGrantingStrategy.php | 207 ++ .../Acl/Domain/RoleSecurityIdentity.php | 73 + .../SecurityIdentityRetrievalStrategy.php | 79 + .../Acl/Domain/UserSecurityIdentity.php | 120 + .../Exception/AclAlreadyExistsException.php | 22 + .../Acl/Exception/AclNotFoundException.php | 22 + .../ConcurrentModificationException.php | 22 + .../Security/Acl/Exception/Exception.php | 21 + .../InvalidDomainObjectException.php | 22 + .../Acl/Exception/NoAceFoundException.php | 26 + .../Exception/NotAllAclsFoundException.php | 46 + .../Acl/Exception/SidNotLoadedException.php | 22 + .../Security/Acl/Model/AclCacheInterface.php | 64 + .../Security/Acl/Model/AclInterface.php | 106 + .../Acl/Model/AclProviderInterface.php | 49 + .../Acl/Model/AuditLoggerInterface.php | 29 + .../Acl/Model/AuditableAclInterface.php | 58 + .../Acl/Model/AuditableEntryInterface.php | 34 + .../Acl/Model/DomainObjectInterface.php | 29 + .../Security/Acl/Model/EntryInterface.php | 65 + .../Acl/Model/FieldEntryInterface.php | 27 + .../Acl/Model/MutableAclInterface.php | 159 + .../Acl/Model/MutableAclProviderInterface.php | 50 + .../Acl/Model/ObjectIdentityInterface.php | 49 + ...jectIdentityRetrievalStrategyInterface.php | 28 + .../PermissionGrantingStrategyInterface.php | 44 + .../Acl/Model/SecurityIdentityInterface.php | 30 + ...rityIdentityRetrievalStrategyInterface.php | 34 + .../Acl/Permission/BasicPermissionMap.php | 103 + .../Security/Acl/Permission/MaskBuilder.php | 201 ++ .../Acl/Permission/PermissionMapInterface.php | 40 + .../Acl/Resources/bin/generateSql.php | 52 + .../Security/Acl/Resources/schema/db2.sql | 43 + .../Security/Acl/Resources/schema/drizzle.sql | 21 + .../Security/Acl/Resources/schema/mssql.sql | 43 + .../Security/Acl/Resources/schema/mysql.sql | 21 + .../Security/Acl/Resources/schema/oracle.sql | 175 + .../Acl/Resources/schema/postgresql.sql | 43 + .../Security/Acl/Resources/schema/sqlite.sql | 31 + .../Component/Security/Acl/Voter/AclVoter.php | 143 + .../Security/Acl/Voter/FieldVote.php | 40 + .../Symfony/Component/Security/CHANGELOG.md | 20 + .../AuthenticationManagerInterface.php | 35 + .../AuthenticationProviderManager.php | 110 + .../AuthenticationTrustResolver.php | 73 + .../AuthenticationTrustResolverInterface.php | 53 + .../AnonymousAuthenticationProvider.php | 60 + .../AuthenticationProviderInterface.php | 35 + .../Provider/DaoAuthenticationProvider.php | 96 + ...PreAuthenticatedAuthenticationProvider.php | 84 + .../RememberMeAuthenticationProvider.php | 55 + .../Provider/UserAuthenticationProvider.php | 128 + .../RememberMe/InMemoryTokenProvider.php | 59 + .../RememberMe/PersistentToken.php | 107 + .../RememberMe/PersistentTokenInterface.php | 51 + .../RememberMe/TokenProviderInterface.php | 54 + .../Authentication/Token/AbstractToken.php | 279 ++ .../Authentication/Token/AnonymousToken.php | 74 + .../Token/PreAuthenticatedToken.php | 74 + .../Authentication/Token/RememberMeToken.php | 96 + .../Authentication/Token/TokenInterface.php | 127 + .../Token/UsernamePasswordToken.php | 91 + .../Security/Core/AuthenticationEvents.php | 19 + .../Authorization/AccessDecisionManager.php | 208 ++ .../AccessDecisionManagerInterface.php | 51 + .../Voter/AuthenticatedVoter.php | 94 + .../Voter/RoleHierarchyVoter.php | 41 + .../Core/Authorization/Voter/RoleVoter.php | 79 + .../Authorization/Voter/VoterInterface.php | 58 + .../Core/Encoder/BasePasswordEncoder.php | 91 + .../Security/Core/Encoder/EncoderFactory.php | 70 + .../Core/Encoder/EncoderFactoryInterface.php | 33 + .../Encoder/MessageDigestPasswordEncoder.php | 66 + .../Core/Encoder/PasswordEncoderInterface.php | 41 + .../Core/Encoder/PlaintextPasswordEncoder.php | 54 + .../Core/Event/AuthenticationEvent.php | 35 + .../Core/Event/AuthenticationFailureEvent.php | 37 + .../Core/Exception/AccessDeniedException.php | 25 + .../Exception/AccountExpiredException.php | 21 + .../Core/Exception/AccountStatusException.php | 22 + ...enticationCredentialsNotFoundException.php | 22 + .../Exception/AuthenticationException.php | 61 + .../AuthenticationServiceException.php | 21 + .../Exception/BadCredentialsException.php | 25 + .../Core/Exception/CookieTheftException.php | 22 + .../Exception/CredentialsExpiredException.php | 21 + .../Core/Exception/DisabledException.php | 21 + .../InsufficientAuthenticationException.php | 23 + .../Exception/InvalidCsrfTokenException.php | 21 + .../Core/Exception/LockedException.php | 21 + .../Core/Exception/LogoutException.php | 25 + .../Core/Exception/NonceExpiredException.php | 24 + .../Exception/ProviderNotFoundException.php | 22 + .../Exception/SessionUnavailableException.php | 27 + .../Core/Exception/TokenNotFoundException.php | 20 + .../Exception/UnsupportedUserException.php | 22 + .../Exception/UsernameNotFoundException.php | 21 + .../Component/Security/Core/Role/Role.php | 41 + .../Security/Core/Role/RoleHierarchy.php | 77 + .../Core/Role/RoleHierarchyInterface.php | 32 + .../Security/Core/Role/RoleInterface.php | 35 + .../Security/Core/Role/SwitchUserRole.php | 48 + .../Security/Core/SecurityContext.php | 94 + .../Core/SecurityContextInterface.php | 50 + .../Core/User/AdvancedUserInterface.php | 87 + .../Security/Core/User/ChainUserProvider.php | 88 + .../Security/Core/User/EquatableInterface.php | 37 + .../Core/User/InMemoryUserProvider.php | 97 + .../Component/Security/Core/User/User.php | 115 + .../Security/Core/User/UserChecker.php | 61 + .../Core/User/UserCheckerInterface.php | 36 + .../Security/Core/User/UserInterface.php | 87 + .../Core/User/UserProviderInterface.php | 76 + .../Security/Core/Util/ClassUtils.php | 55 + .../Validator/Constraint/UserPassword.php | 27 + .../Constraint/UserPasswordValidator.php | 46 + .../Component/Security/Http/AccessMap.php | 49 + .../Security/Http/AccessMapInterface.php | 33 + .../AuthenticationFailureHandlerInterface.php | 39 + .../AuthenticationSuccessHandlerInterface.php | 39 + .../AccessDeniedHandlerInterface.php | 34 + .../AuthenticationEntryPointInterface.php | 34 + .../BasicAuthenticationEntryPoint.php | 41 + .../DigestAuthenticationEntryPoint.php | 74 + .../FormAuthenticationEntryPoint.php | 61 + .../RetryAuthenticationEntryPoint.php | 57 + .../Http/Event/InteractiveLoginEvent.php | 39 + .../Security/Http/Event/SwitchUserEvent.php | 39 + .../Component/Security/Http/Firewall.php | 71 + .../AbstractAuthenticationListener.php | 286 ++ .../AbstractPreAuthenticatedListener.php | 103 + .../Security/Http/Firewall/AccessListener.php | 73 + .../AnonymousAuthenticationListener.php | 55 + .../Firewall/BasicAuthenticationListener.php | 90 + .../Http/Firewall/ChannelListener.php | 71 + .../Http/Firewall/ContextListener.php | 161 + .../Firewall/DigestAuthenticationListener.php | 216 ++ .../Http/Firewall/ExceptionListener.php | 186 + .../Http/Firewall/ListenerInterface.php | 29 + .../Security/Http/Firewall/LogoutListener.php | 135 + .../Http/Firewall/RememberMeListener.php | 95 + .../Http/Firewall/SwitchUserListener.php | 183 + ...namePasswordFormAuthenticationListener.php | 93 + .../Firewall/X509AuthenticationListener.php | 47 + .../Component/Security/Http/FirewallMap.php | 43 + .../Security/Http/FirewallMapInterface.php | 38 + .../Component/Security/Http/HttpUtils.php | 129 + .../Logout/CookieClearingLogoutHandler.php | 50 + .../Http/Logout/LogoutHandlerInterface.php | 35 + .../Logout/LogoutSuccessHandlerInterface.php | 37 + .../Http/Logout/SessionLogoutHandler.php | 36 + .../RememberMe/AbstractRememberMeServices.php | 294 ++ ...PersistentTokenBasedRememberMeServices.php | 151 + .../RememberMeServicesInterface.php | 82 + .../TokenBasedRememberMeServices.php | 152 + .../Security/Http/SecurityEvents.php | 19 + .../Session/SessionAuthenticationStrategy.php | 63 + ...SessionAuthenticationStrategyInterface.php | 37 + .../src/Symfony/Component/Security/LICENSE | 19 + .../src/Symfony/Component/Security/README.md | 26 + .../Acl/Dbal/AclProviderBenchmarkTest.php | 271 ++ .../Tests/Acl/Dbal/AclProviderTest.php | 267 ++ .../Tests/Acl/Dbal/MutableAclProviderTest.php | 492 +++ .../Security/Tests/Acl/Domain/AclTest.php | 521 +++ .../Tests/Acl/Domain/AuditLoggerTest.php | 83 + .../Tests/Acl/Domain/DoctrineAclCacheTest.php | 108 + .../Security/Tests/Acl/Domain/EntryTest.php | 119 + .../Tests/Acl/Domain/FieldEntryTest.php | 74 + .../ObjectIdentityRetrievalStrategyTest.php | 41 + .../Tests/Acl/Domain/ObjectIdentityTest.php | 116 + .../Domain/PermissionGrantingStrategyTest.php | 192 + .../Acl/Domain/RoleSecurityIdentityTest.php | 55 + .../SecurityIdentityRetrievalStrategyTest.php | 198 ++ .../Acl/Domain/UserSecurityIdentityTest.php | 73 + .../Acl/Permission/BasicPermissionMapTest.php | 23 + .../Tests/Acl/Permission/MaskBuilderTest.php | 103 + .../Security/Tests/Acl/Voter/AclVoterTest.php | 405 +++ .../AuthenticationProviderManagerTest.php | 138 + .../AuthenticationTrustResolverTest.php | 72 + .../AnonymousAuthenticationProviderTest.php | 66 + .../DaoAuthenticationProviderTest.php | 301 ++ ...uthenticatedAuthenticationProviderTest.php | 133 + .../RememberMeAuthenticationProviderTest.php | 111 + .../UserAuthenticationProviderTest.php | 206 ++ .../RememberMe/InMemoryTokenProviderTest.php | 63 + .../RememberMe/PersistentTokenTest.php | 29 + .../Token/AbstractTokenTest.php | 244 ++ .../Token/AnonymousTokenTest.php | 45 + .../Token/PreAuthenticatedTokenTest.php | 48 + .../Token/RememerMeTokenTest.php | 83 + .../Token/UsernamePasswordTokenTest.php | 58 + .../AccessDecisionManagerTest.php | 151 + .../Voter/AuthenticatedVoterTest.php | 78 + .../Voter/RoleHierarchyVoterTest.php | 36 + .../Authorization/Voter/RoleVoterTest.php | 62 + .../Core/Encoder/BasePasswordEncoderTest.php | 85 + .../Tests/Core/Encoder/EncoderFactoryTest.php | 94 + .../MessageDigestPasswordEncoderTest.php | 45 + .../Encoder/PlaintextPasswordEncoderTest.php | 39 + .../Tests/Core/Role/RoleHierarchyTest.php | 32 + .../Security/Tests/Core/Role/RoleTest.php | 24 + .../Tests/Core/Role/SwitchUserRoleTest.php | 31 + .../Tests/Core/SecurityContextTest.php | 92 + .../Tests/Core/User/AccountCheckerTest.php | 108 + .../Tests/Core/User/ChainUserProviderTest.php | 185 + .../Tests/Core/User/InMemoryProviderTest.php | 62 + .../Security/Tests/Core/User/UserTest.php | 126 + .../Tests/Core/Util/ClassUtilsTest.php | 41 + .../BasicAuthenticationEntryPointTest.php | 52 + .../DigestAuthenticationEntryPointTest.php | 66 + .../FormAuthenticationEntryPointTest.php | 75 + .../RetryAuthenticationEntryPointTest.php | 71 + .../Http/Firewall/AccessListenerTest.php | 223 ++ .../AnonymousAuthenticationListenerTest.php | 62 + .../BasicAuthenticationListenerTest.php | 198 ++ .../Http/Firewall/ChannelListenerTest.php | 196 ++ .../Http/Firewall/ContextListenerTest.php | 128 + .../Http/Firewall/LogoutListenerTest.php | 256 ++ .../Http/Firewall/RememberMeListenerTest.php | 199 ++ .../Security/Tests/Http/FirewallMapTest.php | 128 + .../Security/Tests/Http/FirewallTest.php | 123 + .../Security/Tests/Http/HttpUtilsTest.php | 151 + .../CookieClearingLogoutHandlerTest.php | 56 + .../Http/Logout/SessionLogoutHandlerTest.php | 47 + .../AbstractRememberMeServicesTest.php | 268 ++ ...istentTokenBasedRememberMeServicesTest.php | 335 ++ .../TokenBasedRememberMeServicesTest.php | 280 ++ .../Component/Security/Tests/bootstrap.php | 22 + .../Symfony/Component/Security/composer.json | 48 + .../Component/Security/phpunit.xml.dist | 29 + .../Symfony/Component/Serializer/CHANGELOG.md | 44 + .../Serializer/Encoder/DecoderInterface.php | 38 + .../Serializer/Encoder/EncoderInterface.php | 38 + .../Serializer/Encoder/JsonDecode.php | 65 + .../Serializer/Encoder/JsonEncode.php | 63 + .../Serializer/Encoder/JsonEncoder.php | 90 + .../Encoder/NormalizationAwareInterface.php | 24 + .../Encoder/SerializerAwareEncoder.php | 33 + .../Serializer/Encoder/XmlEncoder.php | 383 ++ .../Serializer/Exception/Exception.php | 21 + .../Exception/InvalidArgumentException.php | 21 + .../Serializer/Exception/LogicException.php | 21 + .../Serializer/Exception/RuntimeException.php | 21 + .../Exception/UnexpectedValueException.php | 21 + .../Exception/UnsupportedException.php | 21 + .../src/Symfony/Component/Serializer/LICENSE | 19 + .../Normalizer/CustomNormalizer.php | 64 + .../Normalizer/DenormalizableInterface.php | 37 + .../Normalizer/DenormalizerInterface.php | 40 + .../Normalizer/GetSetMethodNormalizer.php | 190 + .../Normalizer/NormalizableInterface.php | 37 + .../Normalizer/NormalizerInterface.php | 38 + .../Normalizer/SerializerAwareNormalizer.php | 33 + .../Symfony/Component/Serializer/README.md | 13 + .../Component/Serializer/Serializer.php | 344 ++ .../Serializer/SerializerAwareInterface.php | 29 + .../Serializer/SerializerInterface.php | 38 + .../Tests/Encoder/XmlEncoderTest.php | 285 ++ .../Tests/Fixtures/DenormalizableDummy.php | 25 + .../Serializer/Tests/Fixtures/Dummy.php | 43 + .../Fixtures/NormalizableTraversableDummy.php | 36 + .../Serializer/Tests/Fixtures/ScalarDummy.php | 37 + .../Tests/Fixtures/TraversableDummy.php | 23 + .../Tests/Normalizer/CustomNormalizerTest.php | 58 + .../Normalizer/GetSetMethodNormalizerTest.php | 220 ++ .../Serializer/Tests/SerializerTest.php | 227 ++ .../Component/Serializer/Tests/bootstrap.php | 18 + .../Component/Serializer/composer.json | 30 + .../Component/Serializer/phpunit.xml.dist | 29 + .../Component/Templating/Asset/Package.php | 71 + .../Templating/Asset/PackageInterface.php | 36 + .../Templating/Asset/PathPackage.php | 70 + .../Component/Templating/Asset/UrlPackage.php | 77 + .../Symfony/Component/Templating/CHANGELOG.md | 8 + .../Templating/DebuggerInterface.php | 28 + .../Component/Templating/DelegatingEngine.php | 145 + .../Component/Templating/EngineInterface.php | 70 + .../Templating/Helper/AssetsHelper.php | 50 + .../Templating/Helper/CoreAssetsHelper.php | 128 + .../Component/Templating/Helper/Helper.php | 51 + .../Templating/Helper/HelperInterface.php | 49 + .../Templating/Helper/SlotsHelper.php | 147 + .../src/Symfony/Component/Templating/LICENSE | 19 + .../Templating/Loader/CacheLoader.php | 95 + .../Templating/Loader/ChainLoader.php | 83 + .../Templating/Loader/FilesystemLoader.php | 125 + .../Component/Templating/Loader/Loader.php | 34 + .../Templating/Loader/LoaderInterface.php | 47 + .../Component/Templating/PhpEngine.php | 552 +++ .../Symfony/Component/Templating/README.md | 16 + .../Templating/Storage/FileStorage.php | 34 + .../Component/Templating/Storage/Storage.php | 55 + .../Templating/Storage/StringStorage.php | 34 + .../Templating/StreamingEngineInterface.php | 32 + .../Templating/TemplateNameParser.php | 51 + .../TemplateNameParserInterface.php | 34 + .../Templating/TemplateReference.php | 120 + .../Templating/TemplateReferenceInterface.php | 80 + .../Fixtures/ProjectTemplateDebugger.php | 40 + .../Tests/Fixtures/SimpleHelper.php | 34 + .../Tests/Fixtures/templates/foo.php | 1 + .../Tests/Helper/AssetsHelperTest.php | 65 + .../Tests/Helper/CoreAssetsHelperTest.php | 54 + .../Templating/Tests/Helper/HelperTest.php | 32 + .../Tests/Helper/SlotsHelperTest.php | 80 + .../Tests/Loader/CacheLoaderTest.php | 82 + .../Tests/Loader/ChainLoaderTest.php | 63 + .../Tests/Loader/FilesystemLoaderTest.php | 85 + .../Templating/Tests/Loader/LoaderTest.php | 43 + .../Templating/Tests/PhpEngineTest.php | 196 ++ .../Tests/Storage/FileStorageTest.php | 26 + .../Templating/Tests/Storage/StorageTest.php | 30 + .../Tests/Storage/StringStorageTest.php | 26 + .../Tests/TemplateNameParserTest.php | 50 + .../Component/Templating/Tests/bootstrap.php | 18 + .../Component/Templating/composer.json | 30 + .../Component/Templating/phpunit.xml.dist | 29 + .../Component/Translation/CHANGELOG.md | 10 + .../Translation/Dumper/CsvFileDumper.php | 63 + .../Translation/Dumper/DumperInterface.php | 31 + .../Translation/Dumper/FileDumper.php | 62 + .../Translation/Dumper/IcuResFileDumper.php | 135 + .../Translation/Dumper/IniFileDumper.php | 45 + .../Translation/Dumper/MoFileDumper.php | 82 + .../Translation/Dumper/PhpFileDumper.php | 40 + .../Translation/Dumper/PoFileDumper.php | 55 + .../Translation/Dumper/QtFileDumper.php | 50 + .../Translation/Dumper/XliffFileDumper.php | 60 + .../Translation/Dumper/YamlFileDumper.php | 39 + .../Translation/Extractor/ChainExtractor.php | 60 + .../Extractor/ExtractorInterface.php | 38 + .../Translation/IdentityTranslator.php | 74 + .../Component/Translation/Interval.php | 103 + .../src/Symfony/Component/Translation/LICENSE | 19 + .../Translation/Loader/ArrayLoader.php | 70 + .../Translation/Loader/CsvFileLoader.php | 86 + .../Translation/Loader/IcuDatFileLoader.php | 44 + .../Translation/Loader/IcuResFileLoader.php | 74 + .../Translation/Loader/IniFileLoader.php | 39 + .../Translation/Loader/LoaderInterface.php | 37 + .../Translation/Loader/MoFileLoader.php | 174 + .../Translation/Loader/PhpFileLoader.php | 43 + .../Translation/Loader/PoFileLoader.php | 168 + .../Loader/QtTranslationsLoader.php | 85 + .../Translation/Loader/XliffFileLoader.php | 116 + .../Translation/Loader/YamlFileLoader.php | 50 + .../dic/xliff-core/xliff-core-1.2-strict.xsd | 2223 ++++++++++++ .../Loader/schema/dic/xliff-core/xml.xsd | 309 ++ .../Translation/MessageCatalogue.php | 234 ++ .../Translation/MessageCatalogueInterface.php | 172 + .../Component/Translation/MessageSelector.php | 82 + .../Translation/PluralizationRules.php | 217 ++ .../Symfony/Component/Translation/README.md | 38 + .../Tests/Dumper/CsvFileDumperTest.php | 33 + .../Tests/Dumper/IcuResFileDumperTest.php | 37 + .../Tests/Dumper/IniFileDumperTest.php | 32 + .../Tests/Dumper/MoFileDumperTest.php | 31 + .../Tests/Dumper/PhpFileDumperTest.php | 32 + .../Tests/Dumper/PoFileDumperTest.php | 31 + .../Tests/Dumper/QtFileDumperTest.php | 32 + .../Tests/Dumper/XliffFileDumperTest.php | 32 + .../Tests/Dumper/YamlFileDumperTest.php | 39 + .../Tests/IdentityTranslatorTest.php | 61 + .../Translation/Tests/IntervalTest.php | 48 + .../Tests/Loader/CsvFileLoaderTest.php | 67 + .../Tests/Loader/IcuDatFileLoaderTest.php | 64 + .../Tests/Loader/IcuResFileLoaderTest.php | 51 + .../Tests/Loader/IniFileLoaderTest.php | 57 + .../Tests/Loader/LocalizedTestCase.php | 22 + .../Tests/Loader/MoFileLoaderTest.php | 57 + .../Tests/Loader/PhpFileLoaderTest.php | 46 + .../Tests/Loader/PoFileLoaderTest.php | 69 + .../Tests/Loader/QtTranslationsLoaderTest.php | 36 + .../Tests/Loader/XliffFileLoaderTest.php | 72 + .../Tests/Loader/YamlFileLoaderTest.php | 61 + .../Tests/MessageCatalogueTest.php | 173 + .../Translation/Tests/MessageSelectorTest.php | 72 + .../Translation/Tests/TranslatorTest.php | 248 ++ .../Component/Translation/Tests/bootstrap.php | 22 + .../Tests/fixtures/empty-translation.po | 3 + .../Translation/Tests/fixtures/empty.csv | 0 .../Translation/Tests/fixtures/empty.ini | 0 .../Translation/Tests/fixtures/empty.mo | 0 .../Translation/Tests/fixtures/empty.po | 0 .../Translation/Tests/fixtures/empty.yml | 0 .../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 + .../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 + .../resourcebundle/dat/packagelist.txt | 2 + .../fixtures/resourcebundle/dat/resources.dat | Bin 0 -> 352 bytes .../Tests/fixtures/resourcebundle/res/en.res | Bin 0 -> 84 bytes .../Tests/fixtures/resourcebundle/res/en.txt | 3 + .../Tests/fixtures/resources-clean.xlf | 15 + .../Translation/Tests/fixtures/resources.csv | 4 + .../Translation/Tests/fixtures/resources.ini | 1 + .../Translation/Tests/fixtures/resources.mo | Bin 0 -> 52 bytes .../Translation/Tests/fixtures/resources.php | 5 + .../Translation/Tests/fixtures/resources.po | 2 + .../Translation/Tests/fixtures/resources.ts | 10 + .../Translation/Tests/fixtures/resources.xlf | 18 + .../Translation/Tests/fixtures/resources.yml | 1 + .../Translation/Tests/fixtures/valid.csv | 4 + .../Component/Translation/Translator.php | 212 ++ .../Translation/TranslatorInterface.php | 69 + .../Translation/Writer/TranslationWriter.php | 71 + .../Component/Translation/composer.json | 38 + .../Component/Translation/phpunit.xml.dist | 29 + .../Symfony/Component/Validator/CHANGELOG.md | 25 + .../Component/Validator/Constraint.php | 220 ++ .../Validator/ConstraintValidator.php | 111 + .../Validator/ConstraintValidatorFactory.php | 41 + .../ConstraintValidatorFactoryInterface.php | 31 + .../ConstraintValidatorInterface.php | 37 + .../Validator/ConstraintViolation.php | 127 + .../Validator/ConstraintViolationList.php | 197 ++ .../Component/Validator/Constraints/All.php | 34 + .../Validator/Constraints/AllValidator.php | 57 + .../Component/Validator/Constraints/Blank.php | 24 + .../Validator/Constraints/BlankValidator.php | 38 + .../Validator/Constraints/Callback.php | 48 + .../Constraints/CallbackValidator.php | 66 + .../Validator/Constraints/Choice.php | 41 + .../Validator/Constraints/ChoiceValidator.php | 88 + .../Validator/Constraints/Collection.php | 47 + .../Constraints/Collection/Optional.php | 27 + .../Constraints/Collection/Required.php | 27 + .../Constraints/CollectionValidator.php | 85 + .../Validator/Constraints/Country.php | 24 + .../Constraints/CountryValidator.php | 51 + .../Component/Validator/Constraints/Date.php | 24 + .../Validator/Constraints/DateTime.php | 24 + .../Constraints/DateTimeValidator.php | 22 + .../Validator/Constraints/DateValidator.php | 51 + .../Component/Validator/Constraints/Email.php | 26 + .../Validator/Constraints/EmailValidator.php | 90 + .../Component/Validator/Constraints/False.php | 24 + .../Validator/Constraints/FalseValidator.php | 40 + .../Component/Validator/Constraints/File.php | 38 + .../Validator/Constraints/FileValidator.php | 163 + .../Validator/Constraints/GroupSequence.php | 34 + .../Constraints/GroupSequenceProvider.php | 22 + .../Component/Validator/Constraints/Image.php | 33 + .../Validator/Constraints/ImageValidator.php | 110 + .../Component/Validator/Constraints/Ip.php | 80 + .../Validator/Constraints/IpValidator.php | 102 + .../Validator/Constraints/Language.php | 24 + .../Constraints/LanguageValidator.php | 51 + .../Validator/Constraints/Locale.php | 24 + .../Validator/Constraints/LocaleValidator.php | 51 + .../Component/Validator/Constraints/Max.php | 42 + .../Validator/Constraints/MaxLength.php | 42 + .../Constraints/MaxLengthValidator.php | 60 + .../Validator/Constraints/MaxValidator.php | 54 + .../Component/Validator/Constraints/Min.php | 42 + .../Validator/Constraints/MinLength.php | 42 + .../Constraints/MinLengthValidator.php | 60 + .../Validator/Constraints/MinValidator.php | 54 + .../Validator/Constraints/NotBlank.php | 24 + .../Constraints/NotBlankValidator.php | 38 + .../Validator/Constraints/NotNull.php | 24 + .../Constraints/NotNullValidator.php | 38 + .../Component/Validator/Constraints/Null.php | 24 + .../Validator/Constraints/NullValidator.php | 38 + .../Component/Validator/Constraints/Range.php | 36 + .../Validator/Constraints/RangeValidator.php | 64 + .../Component/Validator/Constraints/Regex.php | 42 + .../Validator/Constraints/RegexValidator.php | 52 + .../Component/Validator/Constraints/Size.php | 89 + .../Validator/Constraints/SizeValidator.php | 163 + .../Component/Validator/Constraints/Time.php | 24 + .../Validator/Constraints/TimeValidator.php | 51 + .../Component/Validator/Constraints/True.php | 24 + .../Validator/Constraints/TrueValidator.php | 46 + .../Component/Validator/Constraints/Type.php | 41 + .../Validator/Constraints/TypeValidator.php | 56 + .../Component/Validator/Constraints/Url.php | 25 + .../Validator/Constraints/UrlValidator.php | 66 + .../Component/Validator/Constraints/Valid.php | 26 + .../ConstraintDefinitionException.php | 16 + .../Exception/GroupDefinitionException.php | 16 + .../Exception/InvalidOptionsException.php | 29 + .../Validator/Exception/MappingException.php | 16 + .../Exception/MissingOptionsException.php | 29 + .../Exception/UnexpectedTypeException.php | 20 + .../Exception/ValidatorException.php | 16 + .../Component/Validator/ExecutionContext.php | 187 + .../Validator/GlobalExecutionContext.php | 76 + .../Component/Validator/GraphWalker.php | 184 + .../GroupSequenceProviderInterface.php | 26 + .../src/Symfony/Component/Validator/LICENSE | 19 + .../Mapping/BlackholeMetadataFactory.php | 25 + .../Validator/Mapping/Cache/ApcCache.php | 51 + .../Mapping/Cache/CacheInterface.php | 45 + .../Validator/Mapping/ClassMetadata.php | 330 ++ .../Mapping/ClassMetadataFactory.php | 79 + .../Mapping/ClassMetadataFactoryInterface.php | 17 + .../Validator/Mapping/ElementMetadata.php | 98 + .../Validator/Mapping/GetterMetadata.php | 55 + .../Mapping/Loader/AbstractLoader.php | 65 + .../Mapping/Loader/AnnotationLoader.php | 81 + .../Validator/Mapping/Loader/FileLoader.php | 40 + .../Validator/Mapping/Loader/FilesLoader.php | 61 + .../Validator/Mapping/Loader/LoaderChain.php | 62 + .../Mapping/Loader/LoaderInterface.php | 26 + .../Mapping/Loader/StaticMethodLoader.php | 51 + .../Mapping/Loader/XmlFileLoader.php | 215 ++ .../Mapping/Loader/XmlFilesLoader.php | 30 + .../Mapping/Loader/YamlFileLoader.php | 124 + .../Mapping/Loader/YamlFilesLoader.php | 30 + .../constraint-mapping-1.0.xsd | 147 + .../Validator/Mapping/MemberMetadata.php | 202 ++ .../Validator/Mapping/PropertyMetadata.php | 51 + .../Validator/ObjectInitializerInterface.php | 34 + .../src/Symfony/Component/Validator/README.md | 55 + .../Resources/translations/validators.ca.xlf | 187 + .../Resources/translations/validators.cs.xlf | 207 ++ .../Resources/translations/validators.da.xlf | 207 ++ .../Resources/translations/validators.de.xlf | 187 + .../Resources/translations/validators.en.xlf | 219 ++ .../Resources/translations/validators.es.xlf | 187 + .../Resources/translations/validators.et.xlf | 131 + .../Resources/translations/validators.eu.xlf | 155 + .../Resources/translations/validators.fa.xlf | 155 + .../Resources/translations/validators.fi.xlf | 131 + .../Resources/translations/validators.fr.xlf | 219 ++ .../Resources/translations/validators.he.xlf | 207 ++ .../Resources/translations/validators.hr.xlf | 207 ++ .../Resources/translations/validators.hu.xlf | 207 ++ .../Resources/translations/validators.hy.xlf | 187 + .../Resources/translations/validators.id.xlf | 187 + .../Resources/translations/validators.it.xlf | 187 + .../Resources/translations/validators.ja.xlf | 151 + .../Resources/translations/validators.lb.xlf | 131 + .../Resources/translations/validators.lt.xlf | 155 + .../Resources/translations/validators.mn.xlf | 151 + .../Resources/translations/validators.nb.xlf | 155 + .../Resources/translations/validators.nl.xlf | 219 ++ .../Resources/translations/validators.pl.xlf | 207 ++ .../Resources/translations/validators.pt.xlf | 207 ++ .../translations/validators.pt_BR.xlf | 207 ++ .../Resources/translations/validators.ro.xlf | 207 ++ .../Resources/translations/validators.ru.xlf | 219 ++ .../Resources/translations/validators.sk.xlf | 207 ++ .../Resources/translations/validators.sl.xlf | 207 ++ .../translations/validators.sr_Cyrl.xlf | 187 + .../translations/validators.sr_Latn.xlf | 187 + .../Resources/translations/validators.sv.xlf | 119 + .../Resources/translations/validators.ua.xlf | 151 + .../translations/validators.zh_CN.xlf | 179 + .../Validator/Tests/ConstraintTest.php | 131 + .../Tests/ConstraintValidatorTest.php | 60 + .../Tests/ConstraintViolationListTest.php | 134 + .../Tests/ConstraintViolationTest.php | 35 + .../Tests/Constraints/AllValidatorTest.php | 123 + .../Tests/Constraints/BlankValidatorTest.php | 78 + .../Constraints/CallbackValidatorTest.php | 157 + .../Tests/Constraints/ChoiceValidatorTest.php | 297 ++ .../CollectionValidatorArrayObjectTest.php | 20 + .../CollectionValidatorArrayTest.php | 20 + ...llectionValidatorCustomArrayObjectTest.php | 78 + .../Constraints/CollectionValidatorTest.php | 420 +++ .../Constraints/CountryValidatorTest.php | 114 + .../Constraints/DateTimeValidatorTest.php | 120 + .../Tests/Constraints/DateValidatorTest.php | 116 + .../Tests/Constraints/EmailValidatorTest.php | 106 + .../Tests/Constraints/FalseValidatorTest.php | 63 + .../Constraints/FileValidatorObjectTest.php | 22 + .../Constraints/FileValidatorPathTest.php | 37 + .../Tests/Constraints/FileValidatorTest.php | 329 ++ .../Tests/Constraints/Fixtures/test.gif | Bin 0 -> 801 bytes .../Tests/Constraints/ImageValidatorTest.php | 226 ++ .../Tests/Constraints/IpValidatorTest.php | 478 +++ .../Constraints/LanguageValidatorTest.php | 114 + .../Tests/Constraints/LocaleValidatorTest.php | 115 + .../Tests/Constraints/LocalizedTestCase.php | 22 + .../Constraints/MaxLengthValidatorTest.php | 127 + .../Tests/Constraints/MaxValidatorTest.php | 103 + .../Constraints/MinLengthValidatorTest.php | 127 + .../Tests/Constraints/MinValidatorTest.php | 97 + .../Constraints/NotBlankValidatorTest.php | 109 + .../Constraints/NotNullValidatorTest.php | 69 + .../Tests/Constraints/NullValidatorTest.php | 70 + .../Tests/Constraints/RangeValidatorTest.php | 121 + .../Tests/Constraints/RegexValidatorTest.php | 116 + .../Validator/Tests/Constraints/SizeTest.php | 98 + .../Tests/Constraints/SizeValidatorTest.php | 216 ++ .../Tests/Constraints/TimeValidatorTest.php | 117 + .../Tests/Constraints/TrueValidatorTest.php | 64 + .../Tests/Constraints/TypeValidatorTest.php | 183 + .../Tests/Constraints/UrlValidatorTest.php | 168 + .../Validator/Tests/ExecutionContextTest.php | 250 ++ .../Tests/Fixtures/ClassConstraint.php | 22 + .../Validator/Tests/Fixtures/ConstraintA.php | 31 + .../Tests/Fixtures/ConstraintAValidator.php | 39 + .../Validator/Tests/Fixtures/ConstraintB.php | 23 + .../Validator/Tests/Fixtures/ConstraintC.php | 30 + .../Validator/Tests/Fixtures/Entity.php | 56 + .../Tests/Fixtures/EntityInterface.php | 16 + .../Validator/Tests/Fixtures/EntityParent.php | 25 + .../Tests/Fixtures/FailingConstraint.php | 24 + .../Fixtures/FailingConstraintValidator.php | 25 + .../Fixtures/FakeClassMetadataFactory.php | 34 + .../Validator/Tests/Fixtures/FilesLoader.php | 39 + .../Fixtures/GroupSequenceProviderEntity.php | 36 + .../Tests/Fixtures/InvalidConstraint.php | 16 + .../Fixtures/InvalidConstraintValidator.php | 14 + .../Tests/Fixtures/PropertyConstraint.php | 22 + .../Validator/Tests/Fixtures/Reference.php | 16 + .../Tests/GlobalExecutionContextTest.php | 63 + .../Validator/Tests/GraphWalkerTest.php | 539 +++ .../Tests/Mapping/Cache/ApcCacheTest.php | 78 + .../Mapping/ClassMetadataFactoryTest.php | 119 + .../Tests/Mapping/ClassMetadataTest.php | 225 ++ .../Tests/Mapping/ElementMetadataTest.php | 73 + .../Tests/Mapping/GetterMetadataTest.php | 39 + .../Mapping/Loader/AnnotationLoaderTest.php | 157 + .../Tests/Mapping/Loader/FilesLoaderTest.php | 48 + .../Tests/Mapping/Loader/LoaderChainTest.php | 85 + .../Mapping/Loader/StaticMethodLoaderTest.php | 80 + .../Mapping/Loader/XmlFileLoaderTest.php | 82 + .../Mapping/Loader/YamlFileLoaderTest.php | 107 + .../Mapping/Loader/constraint-mapping.xml | 87 + .../Mapping/Loader/constraint-mapping.yml | 45 + .../Tests/Mapping/Loader/empty-mapping.yml | 0 .../Tests/Mapping/Loader/nonvalid-mapping.yml | 1 + .../Tests/Mapping/MemberMetadataTest.php | 83 + .../Tests/Mapping/PropertyMetadataTest.php | 36 + .../Validator/Tests/ValidatorContextTest.php | 61 + .../Validator/Tests/ValidatorFactoryTest.php | 178 + .../Validator/Tests/ValidatorTest.php | 210 ++ .../Component/Validator/Tests/bootstrap.php | 34 + .../Symfony/Component/Validator/Validator.php | 125 + .../Component/Validator/ValidatorContext.php | 85 + .../Validator/ValidatorContextInterface.php | 53 + .../Component/Validator/ValidatorFactory.php | 203 ++ .../Validator/ValidatorInterface.php | 85 + .../Symfony/Component/Validator/composer.json | 40 + .../Component/Validator/phpunit.xml.dist | 29 + .../src/Symfony/Component/Yaml/CHANGELOG.md | 8 + .../src/Symfony/Component/Yaml/Dumper.php | 54 + .../src/Symfony/Component/Yaml/Escaper.php | 88 + .../Yaml/Exception/DumpException.php | 23 + .../Yaml/Exception/ExceptionInterface.php | 23 + .../Yaml/Exception/ParseException.php | 143 + .../src/Symfony/Component/Yaml/Inline.php | 424 +++ .../src/Symfony/Component/Yaml/LICENSE | 19 + .../src/Symfony/Component/Yaml/Parser.php | 609 ++++ .../src/Symfony/Component/Yaml/README.md | 17 + .../Component/Yaml/Tests/DumperTest.php | 166 + .../Yaml/Tests/Fixtures/YtsAnchorAlias.yml | 31 + .../Yaml/Tests/Fixtures/YtsBasicTests.yml | 178 + .../Yaml/Tests/Fixtures/YtsBlockMapping.yml | 51 + .../Tests/Fixtures/YtsDocumentSeparator.yml | 85 + .../Yaml/Tests/Fixtures/YtsErrorTests.yml | 26 + .../Tests/Fixtures/YtsFlowCollections.yml | 60 + .../Yaml/Tests/Fixtures/YtsFoldedScalars.yml | 176 + .../Tests/Fixtures/YtsNullsAndEmpties.yml | 45 + .../Fixtures/YtsSpecificationExamples.yml | 1695 +++++++++ .../Yaml/Tests/Fixtures/YtsTypeTransfers.yml | 244 ++ .../Yaml/Tests/Fixtures/escapedCharacters.yml | 139 + .../Component/Yaml/Tests/Fixtures/index.yml | 18 + .../Yaml/Tests/Fixtures/sfComments.yml | 51 + .../Yaml/Tests/Fixtures/sfCompact.yml | 159 + .../Yaml/Tests/Fixtures/sfMergeKey.yml | 27 + .../Yaml/Tests/Fixtures/sfObjects.yml | 11 + .../Yaml/Tests/Fixtures/sfQuotes.yml | 33 + .../Component/Yaml/Tests/Fixtures/sfTests.yml | 135 + .../Tests/Fixtures/unindentedCollections.yml | 62 + .../Component/Yaml/Tests/InlineTest.php | 211 ++ .../Component/Yaml/Tests/ParserTest.php | 168 + .../Component/Yaml/Tests/bootstrap.php | 18 + .../src/Symfony/Component/Yaml/Unescaper.php | 145 + .../src/Symfony/Component/Yaml/Yaml.php | 111 + .../src/Symfony/Component/Yaml/composer.json | 30 + .../Symfony/Component/Yaml/phpunit.xml.dist | 29 + vendor/twig/extensions/LICENSE | 19 + vendor/twig/extensions/composer.json | 20 + .../lib/Twig/Extensions/Autoloader.php | 46 + .../lib/Twig/Extensions/Extension/Debug.php | 34 + .../lib/Twig/Extensions/Extension/I18n.php | 44 + .../lib/Twig/Extensions/Extension/Intl.php | 70 + .../lib/Twig/Extensions/Extension/Text.php | 109 + .../lib/Twig/Extensions/Grammar.php | 30 + .../lib/Twig/Extensions/Grammar/Arguments.php | 22 + .../lib/Twig/Extensions/Grammar/Array.php | 22 + .../lib/Twig/Extensions/Grammar/Body.php | 39 + .../lib/Twig/Extensions/Grammar/Boolean.php | 24 + .../lib/Twig/Extensions/Grammar/Constant.php | 37 + .../Twig/Extensions/Grammar/Expression.php | 22 + .../lib/Twig/Extensions/Grammar/Hash.php | 22 + .../lib/Twig/Extensions/Grammar/Number.php | 24 + .../lib/Twig/Extensions/Grammar/Optional.php | 69 + .../lib/Twig/Extensions/Grammar/Switch.php | 24 + .../lib/Twig/Extensions/Grammar/Tag.php | 56 + .../lib/Twig/Extensions/GrammarInterface.php | 18 + .../lib/Twig/Extensions/Node/Debug.php | 69 + .../lib/Twig/Extensions/Node/Trans.php | 133 + .../lib/Twig/Extensions/SimpleTokenParser.php | 132 + .../lib/Twig/Extensions/TokenParser/Debug.php | 42 + .../lib/Twig/Extensions/TokenParser/Trans.php | 80 + vendor/twig/twig/.travis.yml | 14 + vendor/twig/twig/LICENSE | 31 + vendor/twig/twig/composer.json | 31 + vendor/twig/twig/ext/twig/LICENSE | 22 + vendor/twig/twig/ext/twig/config.m4 | 8 + vendor/twig/twig/ext/twig/config.w32 | 8 + vendor/twig/twig/ext/twig/php_twig.h | 49 + vendor/twig/twig/ext/twig/twig.c | 1025 ++++++ vendor/twig/twig/lib/Twig/Autoloader.php | 44 + vendor/twig/twig/lib/Twig/Compiler.php | 256 ++ .../twig/twig/lib/Twig/CompilerInterface.php | 35 + vendor/twig/twig/lib/Twig/Environment.php | 1105 ++++++ vendor/twig/twig/lib/Twig/Error.php | 199 ++ vendor/twig/twig/lib/Twig/Error/Loader.php | 20 + vendor/twig/twig/lib/Twig/Error/Runtime.php | 21 + vendor/twig/twig/lib/Twig/Error/Syntax.php | 21 + .../twig/twig/lib/Twig/ExpressionParser.php | 488 +++ vendor/twig/twig/lib/Twig/Extension.php | 93 + vendor/twig/twig/lib/Twig/Extension/Core.php | 1039 ++++++ vendor/twig/twig/lib/Twig/Extension/Debug.php | 70 + .../twig/twig/lib/Twig/Extension/Escaper.php | 108 + .../twig/lib/Twig/Extension/Optimizer.php | 35 + .../twig/twig/lib/Twig/Extension/Sandbox.php | 112 + .../twig/twig/lib/Twig/ExtensionInterface.php | 84 + vendor/twig/twig/lib/Twig/Filter.php | 75 + vendor/twig/twig/lib/Twig/Filter/Function.php | 33 + vendor/twig/twig/lib/Twig/Filter/Method.php | 35 + vendor/twig/twig/lib/Twig/Filter/Node.php | 37 + vendor/twig/twig/lib/Twig/FilterInterface.php | 40 + vendor/twig/twig/lib/Twig/Function.php | 63 + .../twig/twig/lib/Twig/Function/Function.php | 34 + vendor/twig/twig/lib/Twig/Function/Method.php | 36 + vendor/twig/twig/lib/Twig/Function/Node.php | 37 + .../twig/twig/lib/Twig/FunctionInterface.php | 37 + vendor/twig/twig/lib/Twig/Lexer.php | 406 +++ vendor/twig/twig/lib/Twig/LexerInterface.php | 29 + vendor/twig/twig/lib/Twig/Loader/Array.php | 102 + vendor/twig/twig/lib/Twig/Loader/Chain.php | 100 + .../twig/twig/lib/Twig/Loader/Filesystem.php | 152 + vendor/twig/twig/lib/Twig/Loader/String.php | 59 + vendor/twig/twig/lib/Twig/LoaderInterface.php | 53 + vendor/twig/twig/lib/Twig/Markup.php | 38 + vendor/twig/twig/lib/Twig/Node.php | 227 ++ vendor/twig/twig/lib/Twig/Node/AutoEscape.php | 40 + vendor/twig/twig/lib/Twig/Node/Block.php | 45 + .../twig/lib/Twig/Node/BlockReference.php | 38 + vendor/twig/twig/lib/Twig/Node/Body.php | 20 + vendor/twig/twig/lib/Twig/Node/Do.php | 39 + vendor/twig/twig/lib/Twig/Node/Embed.php | 39 + vendor/twig/twig/lib/Twig/Node/Expression.php | 21 + .../twig/lib/Twig/Node/Expression/Array.php | 86 + .../lib/Twig/Node/Expression/AssignName.php | 28 + .../twig/lib/Twig/Node/Expression/Binary.php | 40 + .../lib/Twig/Node/Expression/Binary/Add.php | 18 + .../lib/Twig/Node/Expression/Binary/And.php | 18 + .../Node/Expression/Binary/BitwiseAnd.php | 18 + .../Twig/Node/Expression/Binary/BitwiseOr.php | 18 + .../Node/Expression/Binary/BitwiseXor.php | 18 + .../Twig/Node/Expression/Binary/Concat.php | 18 + .../lib/Twig/Node/Expression/Binary/Div.php | 18 + .../lib/Twig/Node/Expression/Binary/Equal.php | 17 + .../Twig/Node/Expression/Binary/FloorDiv.php | 29 + .../Twig/Node/Expression/Binary/Greater.php | 17 + .../Node/Expression/Binary/GreaterEqual.php | 17 + .../lib/Twig/Node/Expression/Binary/In.php | 33 + .../lib/Twig/Node/Expression/Binary/Less.php | 17 + .../Twig/Node/Expression/Binary/LessEqual.php | 17 + .../lib/Twig/Node/Expression/Binary/Mod.php | 18 + .../lib/Twig/Node/Expression/Binary/Mul.php | 18 + .../Twig/Node/Expression/Binary/NotEqual.php | 17 + .../lib/Twig/Node/Expression/Binary/NotIn.php | 33 + .../lib/Twig/Node/Expression/Binary/Or.php | 18 + .../lib/Twig/Node/Expression/Binary/Power.php | 33 + .../lib/Twig/Node/Expression/Binary/Range.php | 33 + .../lib/Twig/Node/Expression/Binary/Sub.php | 18 + .../Twig/Node/Expression/BlockReference.php | 52 + .../lib/Twig/Node/Expression/Conditional.php | 31 + .../lib/Twig/Node/Expression/Constant.php | 23 + .../Node/Expression/ExtensionReference.php | 34 + .../twig/lib/Twig/Node/Expression/Filter.php | 61 + .../Twig/Node/Expression/Filter/Default.php | 44 + .../lib/Twig/Node/Expression/Function.php | 66 + .../twig/lib/Twig/Node/Expression/GetAttr.php | 53 + .../lib/Twig/Node/Expression/MethodCall.php | 37 + .../twig/lib/Twig/Node/Expression/Name.php | 76 + .../twig/lib/Twig/Node/Expression/Parent.php | 48 + .../lib/Twig/Node/Expression/TempName.php | 26 + .../twig/lib/Twig/Node/Expression/Test.php | 54 + .../Twig/Node/Expression/Test/Constant.php | 36 + .../lib/Twig/Node/Expression/Test/Defined.php | 55 + .../Twig/Node/Expression/Test/Divisibleby.php | 34 + .../lib/Twig/Node/Expression/Test/Even.php | 33 + .../lib/Twig/Node/Expression/Test/Null.php | 32 + .../lib/Twig/Node/Expression/Test/Odd.php | 33 + .../lib/Twig/Node/Expression/Test/Sameas.php | 30 + .../twig/lib/Twig/Node/Expression/Unary.php | 30 + .../lib/Twig/Node/Expression/Unary/Neg.php | 18 + .../lib/Twig/Node/Expression/Unary/Not.php | 18 + .../lib/Twig/Node/Expression/Unary/Pos.php | 18 + vendor/twig/twig/lib/Twig/Node/Flush.php | 37 + vendor/twig/twig/lib/Twig/Node/For.php | 113 + vendor/twig/twig/lib/Twig/Node/ForLoop.php | 56 + vendor/twig/twig/lib/Twig/Node/If.php | 67 + vendor/twig/twig/lib/Twig/Node/Import.php | 51 + vendor/twig/twig/lib/Twig/Node/Include.php | 100 + vendor/twig/twig/lib/Twig/Node/Macro.php | 84 + vendor/twig/twig/lib/Twig/Node/Module.php | 372 ++ vendor/twig/twig/lib/Twig/Node/Print.php | 40 + vendor/twig/twig/lib/Twig/Node/Sandbox.php | 48 + .../twig/lib/Twig/Node/SandboxedModule.php | 61 + .../twig/lib/Twig/Node/SandboxedPrint.php | 60 + vendor/twig/twig/lib/Twig/Node/Set.php | 102 + vendor/twig/twig/lib/Twig/Node/SetTemp.php | 35 + vendor/twig/twig/lib/Twig/Node/Spaceless.php | 41 + vendor/twig/twig/lib/Twig/Node/Text.php | 40 + vendor/twig/twig/lib/Twig/NodeInterface.php | 30 + .../twig/lib/Twig/NodeOutputInterface.php | 20 + vendor/twig/twig/lib/Twig/NodeTraverser.php | 89 + .../twig/lib/Twig/NodeVisitor/Escaper.php | 164 + .../twig/lib/Twig/NodeVisitor/Optimizer.php | 247 ++ .../lib/Twig/NodeVisitor/SafeAnalysis.php | 119 + .../twig/lib/Twig/NodeVisitor/Sandbox.php | 106 + .../twig/lib/Twig/NodeVisitorInterface.php | 48 + vendor/twig/twig/lib/Twig/Parser.php | 384 ++ vendor/twig/twig/lib/Twig/ParserInterface.php | 28 + .../twig/lib/Twig/Sandbox/SecurityError.php | 20 + .../twig/lib/Twig/Sandbox/SecurityPolicy.php | 120 + .../Twig/Sandbox/SecurityPolicyInterface.php | 25 + vendor/twig/twig/lib/Twig/Template.php | 442 +++ .../twig/twig/lib/Twig/TemplateInterface.php | 47 + vendor/twig/twig/lib/Twig/Test/Function.php | 31 + vendor/twig/twig/lib/Twig/Test/Method.php | 33 + vendor/twig/twig/lib/Twig/Test/Node.php | 35 + vendor/twig/twig/lib/Twig/TestInterface.php | 26 + vendor/twig/twig/lib/Twig/Token.php | 219 ++ vendor/twig/twig/lib/Twig/TokenParser.php | 34 + .../twig/lib/Twig/TokenParser/AutoEscape.php | 88 + .../twig/twig/lib/Twig/TokenParser/Block.php | 83 + vendor/twig/twig/lib/Twig/TokenParser/Do.php | 42 + .../twig/twig/lib/Twig/TokenParser/Embed.php | 66 + .../twig/lib/Twig/TokenParser/Extends.php | 54 + .../twig/twig/lib/Twig/TokenParser/Filter.php | 61 + .../twig/twig/lib/Twig/TokenParser/Flush.php | 42 + vendor/twig/twig/lib/Twig/TokenParser/For.php | 89 + .../twig/twig/lib/Twig/TokenParser/From.php | 74 + vendor/twig/twig/lib/Twig/TokenParser/If.php | 93 + .../twig/twig/lib/Twig/TokenParser/Import.php | 47 + .../twig/lib/Twig/TokenParser/Include.php | 80 + .../twig/twig/lib/Twig/TokenParser/Macro.php | 69 + .../twig/lib/Twig/TokenParser/Sandbox.php | 55 + vendor/twig/twig/lib/Twig/TokenParser/Set.php | 84 + .../twig/lib/Twig/TokenParser/Spaceless.php | 59 + vendor/twig/twig/lib/Twig/TokenParser/Use.php | 85 + .../twig/twig/lib/Twig/TokenParserBroker.php | 113 + .../lib/Twig/TokenParserBrokerInterface.php | 45 + .../twig/lib/Twig/TokenParserInterface.php | 42 + vendor/twig/twig/lib/Twig/TokenStream.php | 145 + web/.htaccess | 10 + web/app.php | 24 + web/app_dev.php | 30 + web/apple-touch-icon.png | Bin 0 -> 10784 bytes web/bundles/acmedemo/css/demo.css | 294 ++ web/bundles/acmedemo/images/blue-arrow.png | Bin 0 -> 181 bytes .../acmedemo/images/field-background.gif | Bin 0 -> 63 bytes web/bundles/acmedemo/images/logo.gif | Bin 0 -> 1698 bytes web/bundles/acmedemo/images/search.png | Bin 0 -> 737 bytes .../acmedemo/images/welcome-configure.gif | Bin 0 -> 3530 bytes web/bundles/acmedemo/images/welcome-demo.gif | Bin 0 -> 4053 bytes .../acmedemo/images/welcome-quick-tour.gif | Bin 0 -> 4770 bytes web/bundles/framework/css/exception.css | 228 ++ .../framework/css/exception_layout.css | 136 + .../framework/images/blue_picto_less.gif | Bin 0 -> 197 bytes .../framework/images/blue_picto_more.gif | Bin 0 -> 213 bytes web/bundles/framework/images/border_l.png | Bin 0 -> 249 bytes web/bundles/framework/images/border_r.png | Bin 0 -> 253 bytes web/bundles/framework/images/btn_bg.png | Bin 0 -> 87 bytes web/bundles/framework/images/close_quote.gif | Bin 0 -> 284 bytes .../framework/images/exception_detected.gif | Bin 0 -> 3996 bytes .../framework/images/exception_detected.png | Bin 0 -> 3637 bytes .../framework/images/grey_magnifier.png | Bin 0 -> 393 bytes web/bundles/framework/images/icon_log.png | Bin 0 -> 283 bytes web/bundles/framework/images/input_bg.gif | Bin 0 -> 63 bytes web/bundles/framework/images/logo_symfony.gif | Bin 0 -> 1698 bytes web/bundles/framework/images/logo_symfony.png | Bin 0 -> 1459 bytes web/bundles/framework/images/open_quote.gif | Bin 0 -> 281 bytes .../webconfigurator/css/configure.css | 153 + .../webconfigurator/css/install.css | 137 + .../images/background-textfield.gif | Bin 0 -> 63 bytes .../webconfigurator/images/blue-arrow.png | Bin 0 -> 181 bytes .../webconfigurator/images/favicon.ico | Bin 0 -> 1150 bytes .../webconfigurator/images/logo-big.gif | Bin 0 -> 4060 bytes .../webconfigurator/images/logo-small.gif | Bin 0 -> 1698 bytes .../webconfigurator/images/notification.gif | Bin 0 -> 206 bytes web/bundles/webprofiler/css/profiler.css | 485 +++ web/bundles/webprofiler/favicon.ico | Bin 0 -> 1150 bytes web/bundles/webprofiler/images/close.png | Bin 0 -> 402 bytes web/bundles/webprofiler/images/config.png | Bin 0 -> 379 bytes web/bundles/webprofiler/images/db.png | Bin 0 -> 246 bytes web/bundles/webprofiler/images/events.png | Bin 0 -> 730 bytes web/bundles/webprofiler/images/exception.png | Bin 0 -> 921 bytes web/bundles/webprofiler/images/import.png | Bin 0 -> 988 bytes web/bundles/webprofiler/images/logger.png | Bin 0 -> 283 bytes web/bundles/webprofiler/images/mail.png | Bin 0 -> 568 bytes web/bundles/webprofiler/images/memory.png | Bin 0 -> 199 bytes .../images/profiler/bg_submenu.gif | Bin 0 -> 176 bytes .../images/profiler/bg_submenu.png | Bin 0 -> 114 bytes .../webprofiler/images/profiler/border_l.png | Bin 0 -> 249 bytes .../webprofiler/images/profiler/border_r.png | Bin 0 -> 253 bytes .../webprofiler/images/profiler/btn_bg.png | Bin 0 -> 87 bytes .../webprofiler/images/profiler/config.png | Bin 0 -> 379 bytes .../webprofiler/images/profiler/db.png | Bin 0 -> 358 bytes .../webprofiler/images/profiler/events.png | Bin 0 -> 1060 bytes .../webprofiler/images/profiler/exception.png | Bin 0 -> 1148 bytes .../images/profiler/grey_magnifier.png | Bin 0 -> 393 bytes .../webprofiler/images/profiler/input_bg.gif | Bin 0 -> 63 bytes .../webprofiler/images/profiler/logger.png | Bin 0 -> 453 bytes .../images/profiler/logo_symfony_profiler.gif | Bin 0 -> 2589 bytes .../images/profiler/logo_symfony_profiler.png | Bin 0 -> 2222 bytes .../webprofiler/images/profiler/mail.png | Bin 0 -> 1093 bytes .../webprofiler/images/profiler/request.png | Bin 0 -> 1042 bytes .../webprofiler/images/profiler/routing.png | Bin 0 -> 696 bytes .../webprofiler/images/profiler/security.png | Bin 0 -> 994 bytes .../webprofiler/images/profiler/spinner.gif | Bin 0 -> 1505 bytes .../webprofiler/images/profiler/time.png | Bin 0 -> 776 bytes web/bundles/webprofiler/images/request.png | Bin 0 -> 757 bytes web/bundles/webprofiler/images/routing.png | Bin 0 -> 337 bytes web/bundles/webprofiler/images/search.png | Bin 0 -> 785 bytes web/bundles/webprofiler/images/security.png | Bin 0 -> 808 bytes web/bundles/webprofiler/images/spacer.gif | Bin 0 -> 45 bytes web/bundles/webprofiler/images/symfony.png | Bin 0 -> 1332 bytes web/bundles/webprofiler/images/time.png | Bin 0 -> 482 bytes web/config.php | 92 + web/favicon.ico | Bin 0 -> 1150 bytes web/robots.txt | 4 + 5381 files changed, 416709 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 app/.htaccess create mode 100644 app/AppCache.php create mode 100644 app/AppKernel.php create mode 100644 app/Resources/views/base.html.twig create mode 100644 app/SymfonyRequirements.php create mode 100644 app/autoload.php create mode 100644 app/bootstrap.php.cache create mode 100644 app/cache/.gitkeep create mode 100644 app/check.php create mode 100644 app/config/config.yml create mode 100644 app/config/config_dev.yml create mode 100644 app/config/config_prod.yml create mode 100644 app/config/config_test.yml create mode 100644 app/config/parameters.yml create mode 100644 app/config/routing.yml create mode 100644 app/config/routing_dev.yml create mode 100644 app/config/security.yml create mode 100755 app/console create mode 100755 app/logs/.gitkeep create mode 100644 app/phpunit.xml.dist create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 src/.htaccess create mode 100644 src/Acme/DemoBundle/AcmeDemoBundle.php create mode 100644 src/Acme/DemoBundle/Controller/DemoController.php create mode 100644 src/Acme/DemoBundle/Controller/SecuredController.php create mode 100644 src/Acme/DemoBundle/Controller/WelcomeController.php create mode 100644 src/Acme/DemoBundle/DependencyInjection/AcmeDemoExtension.php create mode 100644 src/Acme/DemoBundle/EventListener/ControllerListener.php create mode 100644 src/Acme/DemoBundle/Form/ContactType.php create mode 100644 src/Acme/DemoBundle/Resources/config/services.xml create mode 100644 src/Acme/DemoBundle/Resources/public/css/demo.css create mode 100644 src/Acme/DemoBundle/Resources/public/images/blue-arrow.png create mode 100644 src/Acme/DemoBundle/Resources/public/images/field-background.gif create mode 100644 src/Acme/DemoBundle/Resources/public/images/logo.gif create mode 100644 src/Acme/DemoBundle/Resources/public/images/search.png create mode 100644 src/Acme/DemoBundle/Resources/public/images/welcome-configure.gif create mode 100644 src/Acme/DemoBundle/Resources/public/images/welcome-demo.gif create mode 100644 src/Acme/DemoBundle/Resources/public/images/welcome-quick-tour.gif create mode 100644 src/Acme/DemoBundle/Resources/views/Demo/contact.html.twig create mode 100644 src/Acme/DemoBundle/Resources/views/Demo/hello.html.twig create mode 100644 src/Acme/DemoBundle/Resources/views/Demo/index.html.twig create mode 100644 src/Acme/DemoBundle/Resources/views/Secured/hello.html.twig create mode 100644 src/Acme/DemoBundle/Resources/views/Secured/helloadmin.html.twig create mode 100644 src/Acme/DemoBundle/Resources/views/Secured/layout.html.twig create mode 100644 src/Acme/DemoBundle/Resources/views/Secured/login.html.twig create mode 100644 src/Acme/DemoBundle/Resources/views/Welcome/index.html.twig create mode 100644 src/Acme/DemoBundle/Resources/views/layout.html.twig create mode 100644 src/Acme/DemoBundle/Tests/Controller/DemoControllerTest.php create mode 100644 src/Acme/DemoBundle/Twig/Extension/DemoExtension.php create mode 100644 vendor/ClassLoader.php create mode 100644 vendor/autoload.php create mode 100644 vendor/autoload_classmap.php create mode 100644 vendor/autoload_namespaces.php 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/installed.json create mode 100644 vendor/composer/installed_dev.json create mode 100644 vendor/doctrine/common/.travis.yml create mode 100644 vendor/doctrine/common/LICENSE create mode 100644 vendor/doctrine/common/README.md create mode 100644 vendor/doctrine/common/UPGRADE_TO_2_1 create mode 100644 vendor/doctrine/common/UPGRADE_TO_2_2 create mode 100644 vendor/doctrine/common/composer.json create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation/Attribute.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation/Attributes.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation/Required.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation/Target.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Annotations/AnnotationException.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Annotations/AnnotationReader.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Annotations/AnnotationRegistry.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Annotations/CachedReader.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Annotations/DocLexer.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Annotations/DocParser.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Annotations/FileCacheReader.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Annotations/IndexedReader.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Annotations/PhpParser.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Annotations/Reader.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Annotations/SimpleAnnotationReader.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Cache/ApcCache.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Cache/ArrayCache.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Cache/Cache.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Cache/CacheProvider.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Cache/MemcacheCache.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Cache/MemcachedCache.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Cache/WinCacheCache.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Cache/XcacheCache.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Cache/ZendDataCache.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/ClassLoader.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Collections/ArrayCollection.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Collections/Collection.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/CommonException.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Comparable.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/EventArgs.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/EventManager.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/EventSubscriber.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Lexer.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/NotifyPropertyChanged.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/AbstractManagerRegistry.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/ConnectionRegistry.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/LifecycleEventArgs.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/LoadClassMetadataEventArgs.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/ManagerEventArgs.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/OnClearEventArgs.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/PreUpdateEventArgs.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/ManagerRegistry.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/ClassMetadata.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/ClassMetadataFactory.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/DefaultFileLocator.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/FileDriver.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/FileLocator.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriver.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/PHPDriver.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/StaticPHPDriver.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/SymfonyFileLocator.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/MappingException.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/ReflectionService.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/RuntimeReflectionService.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/StaticReflectionService.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/ObjectManager.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/ObjectManagerAware.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/ObjectRepository.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/PersistentObject.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Persistence/Proxy.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/PropertyChangedListener.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Util/ClassUtils.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Util/Debug.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Util/Inflector.php create mode 100644 vendor/doctrine/common/lib/Doctrine/Common/Version.php create mode 100644 vendor/doctrine/common/phpunit.xml.dist create mode 100644 vendor/doctrine/dbal/.travis.yml create mode 100644 vendor/doctrine/dbal/LICENSE create mode 100644 vendor/doctrine/dbal/README.md create mode 100644 vendor/doctrine/dbal/UPGRADE create mode 100644 vendor/doctrine/dbal/composer.json create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/ArrayStatement.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/CacheException.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/QueryCacheProfile.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/ResultCacheStatement.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Configuration.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/ConnectionException.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Connection.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Exception.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Statement.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliException.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Driver.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Exception.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Statement.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOIbm/Driver.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Connection.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/ResultStatement.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Statement.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/DriverManager.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/ConnectionEventArgs.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/MysqlSessionInit.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/OracleSessionInit.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/SQLSessionInit.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableAddColumnEventArgs.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableChangeColumnEventArgs.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableEventArgs.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRemoveColumnEventArgs.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRenameColumnEventArgs.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaColumnDefinitionEventArgs.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableColumnEventArgs.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableEventArgs.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaDropTableEventArgs.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaEventArgs.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaIndexDefinitionEventArgs.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Events.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/LockMode.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/DebugStack.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/EchoSQLLogger.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/LoggerChain.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/SQLLogger.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DB2Platform.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/DB2Keywords.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/KeywordList.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MsSQLKeywords.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MySQLKeywords.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/OracleKeywords.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/PostgreSQLKeywords.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/ReservedKeywordsValidator.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLiteKeywords.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/OraclePlatform.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServer2005Platform.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServer2008Platform.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Portability/Connection.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Portability/Statement.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/CompositeExpression.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/ExpressionBuilder.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryBuilder.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryException.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/README.markdown create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtils.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractAsset.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Column.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/ColumnDiff.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Comparator.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Constraint.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/DB2SchemaManager.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/ForeignKeyConstraint.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Index.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SQLServerSchemaManager.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Schema.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaConfig.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaDiff.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaException.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Sequence.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Table.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/TableDiff.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/View.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/DropSchemaSqlCollector.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/Graphviz.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/RemoveNamespacedAssets.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/Visitor.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Statement.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ImportCommand.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ReservedWordsCommand.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/RunSqlCommand.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Helper/ConnectionHelper.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ArrayType.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BigIntType.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BlobType.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BooleanType.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ConversionException.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeType.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeTzType.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateType.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DecimalType.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/FloatType.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/IntegerType.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ObjectType.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/SmallIntType.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/StringType.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/TextType.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeType.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Type.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/VarDateTimeType.php create mode 100644 vendor/doctrine/dbal/lib/Doctrine/DBAL/Version.php create mode 100644 vendor/doctrine/dbal/phpunit.xml.dist create mode 100755 vendor/doctrine/dbal/run-all.sh create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/.travis.yml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/CreateDatabaseDoctrineCommand.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/DoctrineCommand.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/DropDatabaseDoctrineCommand.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/GenerateEntitiesDoctrineCommand.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/ImportMappingDoctrineCommand.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/ClearMetadataCacheDoctrineCommand.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/ClearQueryCacheDoctrineCommand.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/ClearResultCacheDoctrineCommand.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/ConvertMappingDoctrineCommand.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/CreateSchemaDoctrineCommand.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/DoctrineCommandHelper.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/DropSchemaDoctrineCommand.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/EnsureProductionSettingsDoctrineCommand.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/InfoDoctrineCommand.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/RunDqlDoctrineCommand.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/RunSqlDoctrineCommand.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/UpdateSchemaDoctrineCommand.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/ValidateSchemaCommand.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/ConnectionFactory.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Controller/ProfilerController.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/DependencyInjection/Configuration.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/DoctrineBundle.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/LICENSE create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/ManagerConfigurator.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Mapping/ClassMetadataCollection.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Mapping/DisconnectedMetadataFactory.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Mapping/MetadataFactory.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/README.md create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Registry.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/config/dbal.xml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/config/orm.xml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/config/schema/doctrine-1.0.xsd create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/doc/configuration.rst create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/doc/installation.rst create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/views/Collector/db.html.twig create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/views/Collector/explain.html.twig create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/BundleTest.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/ContainerTest.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/AnnotationsBundle/AnnotationsBundle.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/AnnotationsBundle/Entity/Test.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/Vendor/AnnotationsBundle/AnnotationsBundle.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/Vendor/AnnotationsBundle/Entity/Test.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/XmlBundle/Entity/Test.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/XmlBundle/Resources/config/doctrine/Test.orm.xml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/XmlBundle/XmlBundle.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/YamlBundle/Entity/Test.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/YamlBundle/Resources/config/doctrine/Test.orm.yml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/YamlBundle/YamlBundle.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_logging.xml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_service_multiple_connections.xml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_service_single_connection.xml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_service_single_master_slave_connection.xml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_types.xml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_filters.xml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_functions.xml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_hydration_mode.xml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_imports.xml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_imports_import.xml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_multiple_em_bundle_mappings.xml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_proxy.xml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_resolve_target_entity.xml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_multiple_entity_managers.xml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_simple_single_entity_manager.xml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_single_entity_manager.xml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_single_em_bundle_mappings.xml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_single_em_dql_functions.xml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/dbal_logging.yml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/dbal_service_multiple_connections.yml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/dbal_service_single_connection.yml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/dbal_service_single_master_slave_connection.yml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/dbal_types.yml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_filters.yml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_functions.yml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_hydration_mode.yml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_imports.yml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_imports_import.yml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_multiple_em_bundle_mappings.yml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_resolve_target_entity.yml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_service_multiple_entity_managers.yml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_service_simple_single_entity_manager.yml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_service_single_entity_manager.yml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_single_em_bundle_mappings.yml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_single_em_dql_functions.yml create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/TestDatetimeFunction.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/TestFilter.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/TestNumericFunction.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/TestStringFunction.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/TestType.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/XMLSchemaTest.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/XmlDoctrineExtensionTest.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/YamlDoctrineExtensionTest.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/Mapping/MetadataFactoryTest.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/RegistryTest.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/TestCase.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/bootstrap.php create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/composer.json create mode 100644 vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/phpunit.xml.dist create mode 100644 vendor/doctrine/orm/.travis.yml create mode 100644 vendor/doctrine/orm/LICENSE create mode 100644 vendor/doctrine/orm/README.markdown create mode 100644 vendor/doctrine/orm/composer.json create mode 100644 vendor/doctrine/orm/doctrine-mapping.xsd create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Configuration.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/EntityNotFoundException.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Event/LifecycleEventArgs.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Event/LoadClassMetadataEventArgs.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Event/OnClearEventArgs.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Event/OnFlushEventArgs.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Event/PostFlushEventArgs.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Event/PreFlushEventArgs.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Event/PreUpdateEventArgs.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Events.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Id/AbstractIdGenerator.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Id/AssignedGenerator.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Id/IdentityGenerator.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Id/SequenceGenerator.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Id/TableGenerator.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Internal/CommitOrderCalculator.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ArrayHydrator.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/HydrationException.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/IterableResult.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ScalarHydrator.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/SingleScalarHydrator.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Annotation.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Builder/AssociationBuilder.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Builder/ClassMetadataBuilder.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Builder/FieldBuilder.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Builder/ManyToManyAssociationBuilder.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Builder/OneToManyAssociationBuilder.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ChangeTrackingPolicy.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadata.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Column.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/DiscriminatorColumn.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/DiscriminatorMap.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/AbstractFileDriver.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/Driver.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DriverChain.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/PHPDriver.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/SimplifiedXmlDriver.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/SimplifiedYamlDriver.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/StaticPHPDriver.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ElementCollection.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Entity.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/GeneratedValue.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/HasLifecycleCallbacks.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Id.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Index.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/InheritanceType.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/JoinColumn.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/JoinColumns.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/JoinTable.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ManyToMany.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ManyToOne.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/MappedSuperclass.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/MappingException.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/NamedQueries.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/NamedQuery.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/OneToMany.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/OneToOne.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/OrderBy.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PostLoad.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PostPersist.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PostRemove.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PostUpdate.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PreFlush.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PrePersist.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PreRemove.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PreUpdate.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/SequenceGenerator.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Table.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/UniqueConstraint.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Version.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/NativeQuery.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/NoResultException.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/NonUniqueResultException.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/ORMException.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/ORMInvalidArgumentException.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/OptimisticLockException.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/PersistentCollection.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/AbstractCollectionPersister.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/AbstractEntityInheritancePersister.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/ElementCollectionPersister.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/OneToManyPersister.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/SingleTablePersister.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/UnionSubclassPersister.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/PessimisticLockException.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Proxy/Autoloader.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Proxy/Proxy.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Proxy/ProxyException.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Proxy/ProxyFactory.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ASTException.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/AggregateExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ArithmeticExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ArithmeticFactor.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ArithmeticTerm.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/BetweenExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/CoalesceExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/CollectionMemberExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ComparisonExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ConditionalExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ConditionalFactor.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ConditionalPrimary.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ConditionalTerm.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/DeleteClause.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/DeleteStatement.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/EmptyCollectionComparisonExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ExistsExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/FromClause.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/AbsFunction.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/BitAndFunction.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/BitOrFunction.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/CurrentDateFunction.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimestampFunction.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/DateAddFunction.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/DateDiffFunction.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/DateSubFunction.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/FunctionNode.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/IdentityFunction.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/LengthFunction.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/LocateFunction.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/LowerFunction.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/ModFunction.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/SqrtFunction.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/SubstringFunction.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/TrimFunction.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/UpperFunction.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/GeneralCaseExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/GroupByClause.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/HavingClause.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/IdentificationVariableDeclaration.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/InExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/IndexBy.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/InputParameter.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/InstanceOfExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Join.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/JoinAssociationPathExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/JoinVariableDeclaration.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/LikeExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Literal.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Node.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/NullComparisonExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/NullIfExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/OrderByClause.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/OrderByItem.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/PartialObjectExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/PathExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/QuantifiedExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/RangeVariableDeclaration.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SelectClause.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SelectExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SelectStatement.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SimpleArithmeticExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SimpleCaseExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SimpleSelectClause.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SimpleSelectExpression.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SimpleWhenClause.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Subselect.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SubselectFromClause.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/UpdateClause.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/UpdateItem.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/UpdateStatement.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/WhenClause.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/WhereClause.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Exec/SingleSelectExecutor.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Exec/SingleTableDeleteUpdateExecutor.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Andx.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Comparison.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Composite.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/From.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Func.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/GroupBy.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Join.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Literal.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Math.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/OrderBy.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Orx.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Select.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Filter/SQLFilter.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/FilterCollection.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Lexer.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/ParameterTypeInferer.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/ParserResult.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Printer.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/ResultSetMapping.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/SqlWalker.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/TreeWalker.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/TreeWalkerAdapter.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Query/TreeWalkerChain.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/QueryBuilder.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/README.markdown create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/MetadataCommand.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryCommand.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/EnsureProductionSettingsCommand.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/InfoCommand.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Helper/EntityManagerHelper.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/MetadataFilter.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ConvertDoctrine1Schema.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/DebugUnitOfWorkListener.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/DisconnectedClassMetadataFactory.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/EntityGenerator.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/EntityRepositoryGenerator.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Event/GenerateSchemaEventArgs.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Event/GenerateSchemaTableEventArgs.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/ClassMetadataExporter.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/ExportException.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/CountWalker.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/Paginator.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/WhereInWalker.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ResolveTargetEntityListener.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/SchemaTool.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/SchemaValidator.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Setup.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ToolEvents.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ToolsException.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/TransactionRequiredException.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php create mode 100644 vendor/doctrine/orm/lib/Doctrine/ORM/Version.php create mode 100644 vendor/doctrine/orm/phpunit.xml.dist create mode 100755 vendor/doctrine/orm/run-all.sh create mode 100644 vendor/jms/aop-bundle/JMS/AopBundle/Aop/InterceptorLoader.php create mode 100644 vendor/jms/aop-bundle/JMS/AopBundle/Aop/PointcutContainer.php create mode 100644 vendor/jms/aop-bundle/JMS/AopBundle/Aop/PointcutInterface.php create mode 100644 vendor/jms/aop-bundle/JMS/AopBundle/Aop/RegexPointcut.php create mode 100644 vendor/jms/aop-bundle/JMS/AopBundle/DependencyInjection/Compiler/PointcutMatchingPass.php create mode 100644 vendor/jms/aop-bundle/JMS/AopBundle/DependencyInjection/Configuration.php create mode 100644 vendor/jms/aop-bundle/JMS/AopBundle/DependencyInjection/JMSAopExtension.php create mode 100644 vendor/jms/aop-bundle/JMS/AopBundle/Exception/Exception.php create mode 100644 vendor/jms/aop-bundle/JMS/AopBundle/Exception/RuntimeException.php create mode 100644 vendor/jms/aop-bundle/JMS/AopBundle/JMSAopBundle.php create mode 100644 vendor/jms/aop-bundle/JMS/AopBundle/README create mode 100644 vendor/jms/aop-bundle/JMS/AopBundle/Resources/config/services.xml create mode 100644 vendor/jms/aop-bundle/JMS/AopBundle/Resources/doc/index.rst create mode 100644 vendor/jms/aop-bundle/JMS/AopBundle/Resources/meta/LICENSE create mode 100644 vendor/jms/aop-bundle/JMS/AopBundle/composer.json create mode 100644 vendor/jms/cg/LICENSE create mode 100644 vendor/jms/cg/composer.json create mode 100644 vendor/jms/cg/src/CG/Core/AbstractClassGenerator.php create mode 100644 vendor/jms/cg/src/CG/Core/ClassGeneratorInterface.php create mode 100644 vendor/jms/cg/src/CG/Core/ClassUtils.php create mode 100644 vendor/jms/cg/src/CG/Core/DefaultGeneratorStrategy.php create mode 100644 vendor/jms/cg/src/CG/Core/DefaultNamingStrategy.php create mode 100644 vendor/jms/cg/src/CG/Core/GeneratorStrategyInterface.php create mode 100644 vendor/jms/cg/src/CG/Core/NamingStrategyInterface.php create mode 100644 vendor/jms/cg/src/CG/Core/ReflectionUtils.php create mode 100644 vendor/jms/cg/src/CG/Generator/AbstractPhpMember.php create mode 100644 vendor/jms/cg/src/CG/Generator/DefaultNavigator.php create mode 100644 vendor/jms/cg/src/CG/Generator/DefaultVisitor.php create mode 100644 vendor/jms/cg/src/CG/Generator/DefaultVisitorInterface.php create mode 100644 vendor/jms/cg/src/CG/Generator/GeneratorUtils.php create mode 100644 vendor/jms/cg/src/CG/Generator/PhpClass.php create mode 100644 vendor/jms/cg/src/CG/Generator/PhpFunction.php create mode 100644 vendor/jms/cg/src/CG/Generator/PhpMethod.php create mode 100644 vendor/jms/cg/src/CG/Generator/PhpParameter.php create mode 100644 vendor/jms/cg/src/CG/Generator/PhpProperty.php create mode 100644 vendor/jms/cg/src/CG/Generator/Writer.php create mode 100644 vendor/jms/cg/src/CG/Proxy/Enhancer.php create mode 100644 vendor/jms/cg/src/CG/Proxy/GeneratorInterface.php create mode 100644 vendor/jms/cg/src/CG/Proxy/InterceptionGenerator.php create mode 100644 vendor/jms/cg/src/CG/Proxy/InterceptorLoaderInterface.php create mode 100644 vendor/jms/cg/src/CG/Proxy/LazyInitializerGenerator.php create mode 100644 vendor/jms/cg/src/CG/Proxy/LazyInitializerInterface.php create mode 100644 vendor/jms/cg/src/CG/Proxy/MethodInterceptorInterface.php create mode 100644 vendor/jms/cg/src/CG/Proxy/MethodInvocation.php create mode 100644 vendor/jms/cg/src/CG/Proxy/RegexInterceptionLoader.php create mode 100644 vendor/jms/cg/src/CG/Version.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/AfterSetup.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/DoctrineListener.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/FormType.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Inject.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/InjectParams.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/LookupMethod.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Observe.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Reference.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Service.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Tag.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Validator.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Config/FastDirectoriesResource.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Config/ServiceFilesResource.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/Compiler/AnnotationConfigurationPass.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/Compiler/IntegrationPass.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/Compiler/ResourceOptimizationPass.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/Configuration.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/JMSDiExtraExtension.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/LookupMethodClassInterface.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/EventListener/ControllerListener.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/EventListener/TemplateListener.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Exception/Exception.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Exception/InvalidArgumentException.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Exception/InvalidTypeException.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Exception/RuntimeException.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Finder/PatternFinder.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Generator/DefinitionInjectorGenerator.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Generator/LookupMethodClassGenerator.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Generator/NameGenerator.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/HttpKernel/ControllerResolver.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/JMSDiExtraBundle.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Metadata/ClassMetadata.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Metadata/Driver/AnnotationDriver.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Metadata/MetadataConverter.php create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/README create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Resources/config/services.xml create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Resources/doc/index.rst create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Resources/meta/LICENSE create mode 100644 vendor/jms/di-extra-bundle/JMS/DiExtraBundle/composer.json create mode 100644 vendor/jms/metadata/CHANGELOG.md create mode 100644 vendor/jms/metadata/LICENSE create mode 100644 vendor/jms/metadata/composer.json create mode 100644 vendor/jms/metadata/src/Metadata/Cache/CacheInterface.php create mode 100644 vendor/jms/metadata/src/Metadata/Cache/FileCache.php create mode 100644 vendor/jms/metadata/src/Metadata/ClassHierarchyMetadata.php create mode 100644 vendor/jms/metadata/src/Metadata/ClassMetadata.php create mode 100644 vendor/jms/metadata/src/Metadata/Driver/AbstractFileDriver.php create mode 100644 vendor/jms/metadata/src/Metadata/Driver/DriverChain.php create mode 100644 vendor/jms/metadata/src/Metadata/Driver/DriverInterface.php create mode 100644 vendor/jms/metadata/src/Metadata/Driver/FileLocator.php create mode 100644 vendor/jms/metadata/src/Metadata/Driver/FileLocatorInterface.php create mode 100644 vendor/jms/metadata/src/Metadata/Driver/LazyLoadingDriver.php create mode 100644 vendor/jms/metadata/src/Metadata/MergeableClassMetadata.php create mode 100644 vendor/jms/metadata/src/Metadata/MergeableInterface.php create mode 100644 vendor/jms/metadata/src/Metadata/MetadataFactory.php create mode 100644 vendor/jms/metadata/src/Metadata/MetadataFactoryInterface.php create mode 100644 vendor/jms/metadata/src/Metadata/MethodMetadata.php create mode 100644 vendor/jms/metadata/src/Metadata/PropertyMetadata.php create mode 100644 vendor/jms/metadata/src/Metadata/Version.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/PreAuthorize.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/RunAs.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/SatisfiesParentSecurityPolicy.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/Secure.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/SecureParam.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/SecureReturn.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/CHANGELOG-1.1.md create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/AccessControlConfiguration.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Compiler/AddAfterInvocationProvidersPass.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Compiler/AddExpressionCompilersPass.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Compiler/CollectSecuredServicesPass.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Compiler/DisableVotersPass.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Compiler/IntegrationPass.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Configuration.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/JMSSecurityExtraExtension.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/SecurityExtension.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Exception/Exception.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Exception/InvalidArgumentException.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Exception/RuntimeException.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/JMSSecurityExtraBundle.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Metadata/ClassMetadata.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Metadata/Driver/AnnotationDriver.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Metadata/Driver/ConfigDriver.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Metadata/MethodMetadata.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/README create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Resources/config/security_expressions.xml create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Resources/config/services.xml create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Resources/doc/index.rst create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Resources/meta/LICENSE create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Acl/Expression/HasPermissionFunctionCompiler.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Acl/Expression/PermissionEvaluator.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Acl/Voter/AclVoter.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authentication/Provider/RunAsAuthenticationProvider.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authentication/Token/RunAsUserToken.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/AfterInvocation/AclAfterInvocationProvider.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/AfterInvocation/AfterInvocationManager.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/AfterInvocation/AfterInvocationManagerInterface.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/AfterInvocation/AfterInvocationProviderInterface.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/AndExpression.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/ArrayExpression.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/ConstantExpression.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/ExpressionInterface.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/FunctionExpression.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/GetItemExpression.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/GetPropertyExpression.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/IsEqualExpression.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/MethodCallExpression.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/NotExpression.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/OrExpression.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/ParameterExpression.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/VariableExpression.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/AndExpressionCompiler.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/BinaryExprCompiler.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/ContainerAwareVariableCompiler.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/AuthenticationTrustFunctionCompiler.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/FunctionCompilerInterface.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/HasAnyRoleFunctionCompiler.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/HasRoleFunctionCompiler.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/IsAnonymousFunctionCompiler.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/IsAuthenticatedFunctionCompiler.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/IsFullyAuthenticatedFunctionCompiler.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/IsRememberMeFunctionCompiler.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/IsEqualExpressionCompiler.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/NotExpressionCompiler.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/OrExpressionCompiler.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/ParameterExpressionCompiler.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/TypeCompilerInterface.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/VariableExpressionCompiler.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ContainerAwareExpressionHandler.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/DefaultExpressionHandler.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Expression.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ExpressionCompiler.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ExpressionHandlerInterface.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ExpressionLexer.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ExpressionParser.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ExpressionVoter.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/LazyLoadingExpressionVoter.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Interception/MethodSecurityInterceptor.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Interception/SecurityPointcut.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/RunAsManager.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/RunAsManagerInterface.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Voter/IddqdVoter.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Twig/SecurityExtension.php create mode 100644 vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/composer.json create mode 100644 vendor/kriswallsmith/assetic/.travis.yml create mode 100644 vendor/kriswallsmith/assetic/CHANGELOG-1.0.md create mode 100755 vendor/kriswallsmith/assetic/CHANGELOG-1.1.md create mode 100644 vendor/kriswallsmith/assetic/LICENSE create mode 100644 vendor/kriswallsmith/assetic/README.md create mode 100644 vendor/kriswallsmith/assetic/composer.json create mode 100644 vendor/kriswallsmith/assetic/docs/en/build.md create mode 100644 vendor/kriswallsmith/assetic/docs/en/concepts.md create mode 100644 vendor/kriswallsmith/assetic/docs/en/define.md create mode 100644 vendor/kriswallsmith/assetic/docs/en/index.md create mode 100644 vendor/kriswallsmith/assetic/docs/en/introduction.md create mode 100644 vendor/kriswallsmith/assetic/docs/ja/build.md create mode 100644 vendor/kriswallsmith/assetic/docs/ja/concepts.md create mode 100644 vendor/kriswallsmith/assetic/docs/ja/define.md create mode 100644 vendor/kriswallsmith/assetic/docs/ja/index.md create mode 100644 vendor/kriswallsmith/assetic/docs/ja/introduction.md create mode 100644 vendor/kriswallsmith/assetic/phpunit.travis.xml create mode 100644 vendor/kriswallsmith/assetic/phpunit.xml.dist create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCache.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollection.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollectionInterface.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetInterface.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetReference.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Asset/BaseAsset.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Asset/FileAsset.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Asset/GlobAsset.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Asset/HttpAsset.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionFilterIterator.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionIterator.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Asset/StringAsset.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/AssetManager.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/AssetWriter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Cache/ApcCache.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Cache/CacheInterface.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Cache/ConfigCache.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Cache/ExpiringCache.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Cache/FilesystemCache.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Exception/Exception.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Exception/FilterException.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticExtension.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterFunction.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterInvoker.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticNode.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticTokenParser.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigFormulaLoader.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigResource.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Factory/AssetFactory.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Factory/LazyAssetManager.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/BasePhpFormulaLoader.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/CachedFormulaLoader.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FormulaLoaderInterface.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FunctionCallsFormulaLoader.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/CoalescingDirectoryResource.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/DirectoryResource.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/FileResource.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/IteratorResourceInterface.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/ResourceInterface.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/EnsureFilterWorker.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/WorkerInterface.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/BaseCssFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/CallablesFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/CoffeeScriptFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/CompassFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/CssEmbedFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/CssImportFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/CssMinFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/CssRewriteFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterCollection.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterInterface.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/BaseCompilerFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerApiFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerJarFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/GssFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/HashableInterface.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinPlusFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegoptimFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegtranFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/LessFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/LessphpFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/OptiPngFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/PackagerFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/PackerFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/PngoutFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/SassFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/ScssFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/SprocketsFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/StylusFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/UglifyJsFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/BaseCompressorFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/CssCompressorFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/JsCompressorFilter.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/FilterManager.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Util/PathUtils.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/Util/TraversableString.php create mode 100644 vendor/kriswallsmith/assetic/src/Assetic/ValueSupplierInterface.php create mode 100644 vendor/kriswallsmith/assetic/src/functions.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/AssetCacheTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/AssetCollectionTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/AssetReferenceTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/FileAssetTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/GlobAssetTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/HttpAssetTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/StringAssetTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/AssetManagerTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/AssetWriterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/ApcCacheTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/ConfigCacheTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/ExpiringCacheTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/FilesystemCacheTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/AsseticExtensionTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/TwigFormulaLoaderTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/TwigResourceTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/absolute_path.twig create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/combine.twig create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/debug.twig create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/filters.twig create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/function.twig create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/glob.twig create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/image.twig create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/mixture.twig create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/optional_filter.twig create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/output_pattern.twig create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/output_url.twig create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/reference.twig create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/variables.twig create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/AssetFactoryTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/LazyAssetManagerTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Loader/CachedFormulaLoaderTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Loader/FunctionCallsFormulaLoaderTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Loader/templates/debug.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/CoalescingDirectoryResourceTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/DirectoryResourceTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/FileResourceTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir1/file1.txt create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir1/file2.txt create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir2/file1.txt create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir2/file3.txt create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Worker/EnsureFilterWorkerTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/BaseImageFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CallablesFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CoffeeScriptFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CompassFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssEmbedFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssImportFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssMinFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssRewriteFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/FilterCollectionTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/GoogleClosure/CompilerApiFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/GoogleClosure/CompilerJarFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/GssFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JSMinFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JSMinPlusFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JpegoptimFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JpegtranFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/LessFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/LessphpFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/OptiPngFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PackagerFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PackerFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PngoutFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Sass/SassFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Sass/ScssFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/SprocketsFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/StylusFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/UglifyJsFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Yui/BaseCompressorFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Yui/CssCompressorFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Yui/JsCompressorFilterTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/compass.sass create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/partials/_sass.sass create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/partials/_scss.scss create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/stylesheet.sass create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/stylesheet.scss create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssembed/test.css create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/import.css create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/main.css create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more.sass create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/bg.gif create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/deep1.css create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/deep2.css create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/noncssimport.css create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssmin/fonts.css create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssmin/main.css create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/home.gif create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/home.jpg create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/home.png create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/jsmin/js.js create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/less/_include.less create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/less/main.less create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/packager/app/application.js create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/packager/lib/package.yml create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/packager/lib/util.js create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/packer/example.js create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sass/_include.scss create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sass/main.scss create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/include.js create mode 100755 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib1/assets/images/image.gif create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib1/header.js create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib2/footer.js create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/main.js create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/uglifyjs/script.js create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/FilterManagerTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Fixture/messages.de.js create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Fixture/messages.en.js create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Fixture/messages.fr.js create mode 100644 vendor/kriswallsmith/assetic/tests/Assetic/Test/Util/TraversableStringTest.php create mode 100644 vendor/kriswallsmith/assetic/tests/bootstrap.php create mode 100644 vendor/monolog/monolog/.travis.yml create mode 100644 vendor/monolog/monolog/CHANGELOG.mdown create mode 100644 vendor/monolog/monolog/LICENSE create mode 100644 vendor/monolog/monolog/README.mdown create mode 100644 vendor/monolog/monolog/composer.json create mode 100644 vendor/monolog/monolog/doc/extending.md create mode 100644 vendor/monolog/monolog/doc/sockets.md create mode 100644 vendor/monolog/monolog/doc/usage.md create mode 100644 vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php create mode 100644 vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php create mode 100644 vendor/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php create mode 100644 vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php create mode 100644 vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php create mode 100644 vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php create mode 100644 vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/GroupHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/HandlerInterface.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/MailHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/NullHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/SocketHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/SyslogHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/TestHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Logger.php create mode 100644 vendor/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php create mode 100644 vendor/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php create mode 100644 vendor/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php create mode 100644 vendor/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php create mode 100644 vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.php create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Composer/ScriptHandler.php create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Configurator.php create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Form/DoctrineStepType.php create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Form/SecretStepType.php create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Step/DoctrineStep.php create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Step/SecretStep.php create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Step/StepInterface.php create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Controller/ConfiguratorController.php create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/DependencyInjection/SensioDistributionExtension.php create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/LICENSE create mode 100755 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/bin/build.sh create mode 100755 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/bin/build_bootstrap.php create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/config/routing/webconfigurator.xml create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/config/webconfigurator.xml create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/css/configure.css create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/css/install.css create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/images/background-textfield.gif create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/images/blue-arrow.png create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/images/favicon.ico create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/images/logo-big.gif create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/images/logo-small.gif create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/images/notification.gif create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/Step/doctrine.html.twig create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/Step/secret.html.twig create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/check.html.twig create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/final.html.twig create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/form.html.twig create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/layout.html.twig create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/steps.html.twig create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/SensioDistributionBundle.php create mode 100644 vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/composer.json create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/.travis.yml create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/Cache.php create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/ConfigurationAnnotation.php create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/ConfigurationInterface.php create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/Method.php create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/ParamConverter.php create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/Route.php create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/Template.php create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/DependencyInjection/Compiler/AddParamConverterPass.php create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/DependencyInjection/Configuration.php create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/DependencyInjection/SensioFrameworkExtraExtension.php create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/EventListener/CacheListener.php create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/EventListener/ControllerListener.php create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/EventListener/ParamConverterListener.php create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/EventListener/TemplateListener.php create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/LICENSE create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/README.md create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Request/ParamConverter/DoctrineParamConverter.php create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Request/ParamConverter/ParamConverterInterface.php create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Request/ParamConverter/ParamConverterManager.php create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/annotations.xml create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/cache.xml create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/converters.xml create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/routing.xml create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/services.xml create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/view.xml create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/doc/annotations/cache.rst create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/doc/annotations/converters.rst create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/doc/annotations/routing.rst create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/doc/annotations/view.rst create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/doc/index.rst create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Routing/AnnotatedRouteControllerLoader.php create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/SensioFrameworkExtraBundle.php create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Templating/TemplateGuesser.php create mode 100644 vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/composer.json create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/.travis.yml create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/GenerateBundleCommand.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/GenerateDoctrineCommand.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/GenerateDoctrineCrudCommand.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/GenerateDoctrineEntityCommand.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/GenerateDoctrineFormCommand.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/Helper/DialogHelper.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/Validators.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Generator/BundleGenerator.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Generator/DoctrineCrudGenerator.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Generator/DoctrineEntityGenerator.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Generator/DoctrineFormGenerator.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Generator/Generator.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/LICENSE create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Manipulator/KernelManipulator.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Manipulator/Manipulator.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Manipulator/RoutingManipulator.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/README.md create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/doc/commands/generate_bundle.rst create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/doc/commands/generate_doctrine_crud.rst create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/doc/commands/generate_doctrine_entity.rst create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/doc/commands/generate_doctrine_form.rst create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/doc/index.rst create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/Bundle.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/Configuration.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/DefaultController.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/DefaultControllerTest.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/Extension.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/index.html.twig create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/messages.fr.xlf create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/routing.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/routing.xml create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/routing.yml create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/services.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/services.xml create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/services.yml create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/create.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/delete.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/edit.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/index.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/new.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/show.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/update.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/config/routing.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/config/routing.xml create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/config/routing.yml create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/controller.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/tests/others/full_scenario.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/tests/others/short_scenario.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/tests/test.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/views/edit.html.twig create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/views/index.html.twig create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/views/new.html.twig create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/views/others/actions.html.twig create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/views/others/record_actions.html.twig create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/views/show.html.twig create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/form/FormType.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/SensioGeneratorBundle.php create mode 100644 vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/composer.json create mode 100644 vendor/swiftmailer/swiftmailer/LICENSE create mode 100644 vendor/swiftmailer/swiftmailer/VERSION create mode 100644 vendor/swiftmailer/swiftmailer/composer.json create mode 100644 vendor/swiftmailer/swiftmailer/doc/headers.rst create mode 100644 vendor/swiftmailer/swiftmailer/doc/help-resources.rst create mode 100644 vendor/swiftmailer/swiftmailer/doc/including-the-files.rst create mode 100644 vendor/swiftmailer/swiftmailer/doc/index.rst create mode 100644 vendor/swiftmailer/swiftmailer/doc/installing.rst create mode 100644 vendor/swiftmailer/swiftmailer/doc/introduction.rst create mode 100644 vendor/swiftmailer/swiftmailer/doc/messages.rst create mode 100644 vendor/swiftmailer/swiftmailer/doc/overview.rst create mode 100644 vendor/swiftmailer/swiftmailer/doc/plugins.rst create mode 100644 vendor/swiftmailer/swiftmailer/doc/sending.rst create mode 100644 vendor/swiftmailer/swiftmailer/doc/uml/Encoders.graffle create mode 100644 vendor/swiftmailer/swiftmailer/doc/uml/Mime.graffle create mode 100644 vendor/swiftmailer/swiftmailer/doc/uml/Transports.graffle create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Attachment.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/AbstractFilterableInputStream.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/ArrayByteStream.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/FileByteStream.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/GenericFixedWidthReader.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/UsAsciiReader.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/Utf8Reader.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReaderFactory.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReaderFactory/SimpleCharacterReaderFactory.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream/ArrayCharacterStream.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream/NgCharacterStream.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/ConfigurableSpool.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/DependencyContainer.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/DependencyException.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/EmbeddedFile.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/Base64Encoder.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/QpEncoder.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/Rfc2231Encoder.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoding.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/CommandEvent.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/CommandListener.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/Event.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/EventDispatcher.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/EventListener.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/EventObject.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/ResponseEvent.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/ResponseListener.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/SendEvent.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/SendListener.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/SimpleEventDispatcher.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportChangeEvent.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportChangeListener.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportExceptionEvent.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportExceptionListener.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/FailoverTransport.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/FileSpool.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/FileStream.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Filterable.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Image.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/InputByteStream.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/IoException.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/ArrayKeyCache.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/DiskKeyCache.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/DummyKeyCache.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/KeyCacheInputStream.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/NullKeyCache.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/SimpleKeyCacheInputStream.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/LoadBalancedTransport.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/MailTransport.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer/ArrayRecipientIterator.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer/RecipientIterator.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/MemorySpool.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Message.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Attachment.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/CharsetObserver.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/Base64ContentEncoder.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/PlainContentEncoder.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/EmbeddedFile.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/EncodingObserver.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Grammar.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Header.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/Base64HeaderEncoder.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderFactory.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderSet.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/AbstractHeader.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/DateHeader.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/IdentificationHeader.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/MailboxHeader.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/ParameterizedHeader.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/PathHeader.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/UnstructuredHeader.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Message.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/MimeEntity.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/MimePart.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ParameterizedHeader.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderFactory.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderSet.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleMessage.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleMimeEntity.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/MimePart.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/NullTransport.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/OutputByteStream.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/AntiFloodPlugin.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/BandwidthMonitorPlugin.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Decorator/Replacements.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/DecoratorPlugin.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/ImpersonatePlugin.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Logger.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/LoggerPlugin.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Loggers/ArrayLogger.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Loggers/EchoLogger.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/MessageLogger.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Connection.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Exception.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/PopBeforeSmtpPlugin.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/RedirectingPlugin.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Reporter.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/ReporterPlugin.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Reporters/HitReporter.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Reporters/HtmlReporter.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Sleeper.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/ThrottlerPlugin.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Timer.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Preferences.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/ReplacementFilterFactory.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/RfcComplianceException.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/SendmailTransport.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/SmtpTransport.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Spool.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/SpoolTransport.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilter.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilters/ByteArrayReplacementFilter.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilter.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilterFactory.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/SwiftException.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/LoginAuthenticator.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Authenticator.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpHandler.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/FailoverTransport.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/IoBuffer.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/LoadBalancedTransport.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/MailInvoker.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/MailTransport.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/NullTransport.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SendmailTransport.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SimpleMailInvoker.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SmtpAgent.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SpoolTransport.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/TransportException.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/classes/Swift/Validate.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/dependency_maps/cache_deps.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/dependency_maps/message_deps.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/dependency_maps/mime_deps.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/dependency_maps/transport_deps.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/mime_types.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/preferences.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/swift_init.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/swift_required.php create mode 100644 vendor/swiftmailer/swiftmailer/lib/swift_required_pear.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/AsseticBundle.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/CacheWarmer/AssetManagerCacheWarmer.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Command/DumpCommand.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Config/AsseticResource.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Controller/AsseticController.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DefaultValueSupplier.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/AsseticExtension.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/AssetFactoryPass.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/AssetManagerPass.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/CheckClosureFilterPass.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/CheckCssEmbedFilterPass.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/CheckYuiFilterPass.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/FilterManagerPass.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/RouterResourcePass.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/SprocketsFilterPass.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/TemplateResourcesPass.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/TemplatingPass.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Configuration.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/DirectoryResourceDefinition.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/EventListener/RequestListener.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Exception/InvalidBundleException.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/AssetFactory.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Loader/AsseticHelperFormulaLoader.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Loader/ConfigurationLoader.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Resource/CoalescingDirectoryResource.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Resource/ConfigurationResource.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Resource/DirectoryResource.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Resource/DirectoryResourceIterator.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Resource/FileResource.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Worker/UseControllerWorker.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/FilterManager.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/assetic.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/controller.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/closure.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/coffee.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/compass.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/cssembed.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/cssimport.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/cssmin.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/cssrewrite.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/gss.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/jpegoptim.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/jpegtran.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/less.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/lessphp.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/optipng.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/packager.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/pngout.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/sass.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/scss.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/sprockets.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/stylus.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/uglifyjs.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/yui_css.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/yui_js.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/schema/assetic-1.0.xsd create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/templating_php.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/templating_twig.xml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Routing/AsseticLoader.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Templating/AsseticHelper.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Templating/DynamicAsseticHelper.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Templating/StaticAsseticHelper.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/CacheWarmer/AssetManagerCacheWarmerTest.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Command/DumpCommandTest.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Controller/AsseticControllerTest.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/DependencyInjection/AsseticExtensionTest.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Factory/AssetFactoryTest.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Factory/Resource/CoalescingDirectoryResourceTest.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Factory/Resource/FileResourceTest.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/FilterManagerTest.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/FunctionalTest.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/base.html.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/base.html.twig create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/layout.html.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/layout.html.twig create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/config/config.yml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/config/routing.yml create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/web/javascript1.js create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/web/javascript2.js create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/web/stylesheet1.css create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/web/stylesheet2.css create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Templating/AsseticHelperTest.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/TestBundle/Resources/css/bundle.css create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/TestBundle/TestBundle.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/TestKernel.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/bootstrap.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Twig/AsseticExtension.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Twig/AsseticNode.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Twig/AsseticNodeVisitor.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Twig/AsseticTokenParser.php create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/UPGRADE.md create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/composer.json create mode 100644 vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/phpunit.xml.dist create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/.travis.yml create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/AddProcessorsPass.php create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/DebugHandlerPass.php create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/LoggerChannelPass.php create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/DependencyInjection/Configuration.php create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/DependencyInjection/MonologExtension.php create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/LICENSE create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/MonologBundle.php create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Resources/config/monolog.xml create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Resources/config/schema/monolog-1.0.xsd create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Compiler/AddProcessorsPassTest.php create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Compiler/LoggerChannelPassTest.php create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/ConfigurationTest.php create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/handlers_with_channels.xml create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/multiple_handlers.xml create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/new_and_priority.xml create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/new_and_priority_import.xml create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/new_at_end.xml create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/new_at_end_import.xml create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/overwriting.xml create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/overwriting_import.xml create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/handlers_with_channels.yml create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/multiple_handlers.yml create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/new_and_priority.yml create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/new_and_priority_import.yml create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/new_at_end.yml create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/new_at_end_import.yml create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/overwriting.yml create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/overwriting_import.yml create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/MonologExtensionTest.php create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/XmlMonologExtensionTest.php create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/YamlMonologExtensionTest.php create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/TestCase.php create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/bootstrap.php create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/composer.json create mode 100644 vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/phpunit.xml.dist create mode 100644 vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Command/SendEmailCommand.php create mode 100644 vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/Compiler/RegisterPluginsPass.php create mode 100644 vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/Configuration.php create mode 100644 vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/SwiftmailerExtension.php create mode 100644 vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/EventListener/EmailSenderListener.php create mode 100644 vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/LICENSE create mode 100644 vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/schema/swiftmailer-1.0.xsd create mode 100644 vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/smtp.xml create mode 100644 vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/spool.xml create mode 100644 vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/spool_file.xml create mode 100644 vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/spool_memory.xml create mode 100644 vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/swiftmailer.xml create mode 100644 vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/views/Collector/swiftmailer.html.twig create mode 100644 vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/SwiftmailerBundle.php create mode 100644 vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Tests/DependencyInjection/SwiftmailerExtensionTest.php create mode 100644 vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Tests/TestCase.php create mode 100644 vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/composer.json create mode 100644 vendor/symfony/symfony/.editorconfig create mode 100644 vendor/symfony/symfony/.travis.yml create mode 100644 vendor/symfony/symfony/CHANGELOG-2.0.md create mode 100644 vendor/symfony/symfony/CONTRIBUTORS.md create mode 100644 vendor/symfony/symfony/LICENSE create mode 100644 vendor/symfony/symfony/UPGRADE-2.1.md create mode 100644 vendor/symfony/symfony/autoload.php.dist create mode 100644 vendor/symfony/symfony/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/CacheWarmer/ProxyCacheWarmer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/ContainerAwareEventManager.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DataFixtures/ContainerAwareLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/DoctrineValidationPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DependencyInjection/Security/UserProvider/EntityFactory.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityLoaderInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/DataTransformer/CollectionToArrayTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/EventListener/MergeDoctrineCollectionListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/Type/EntityType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/HttpFoundation/DbalSessionHandler.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/HttpFoundation/DbalSessionHandlerSchema.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Logger/DbalLogger.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/ManagerRegistry.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/RegistryInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/ContainerAwareEventManagerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/DataCollector/DoctrineDataCollectorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/DataFixtures/ContainerAwareLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPassTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/DoctrineOrmTestCase.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/AssociationEntity.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/CompositeIdentEntity.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/CompositeStringIdentEntity.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/ContainerAwareFixture.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/ItemGroupEntity.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/NoToStringSingleIdentEntity.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleIdentEntity.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleStringIdentEntity.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/EntityChoiceListTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/HttpFoundation/DbalSessionHandlerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Validator/DoctrineInitializer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Monolog/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Handler/ChromePhpHandler.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Handler/DebugHandler.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Handler/FirePHPHandler.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Monolog/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Logger.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Processor/WebProcessor.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Monolog/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Monolog/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Monolog/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/DataCollector/PropelDataCollector.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/DependencyInjection/Security/UserProvider/PropelFactory.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Form/DataTransformer/CollectionToArrayTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Form/PropelExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Form/PropelTypeGuesser.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Form/Type/ModelType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Logger/PropelLogger.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Security/User/PropelUserProvider.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/DataCollector/PropelDataCollectorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Fixtures/Column.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Fixtures/Item.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Fixtures/ItemQuery.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Fixtures/ReadOnlyItem.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Fixtures/ReadOnlyItemQuery.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Form/ChoiceList/ModelChoiceListTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Form/DataTransformer/CollectionToArrayTransformerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Form/PropelTypeGuesserTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Propel1TestCase.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Propel1/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Swiftmailer/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Swiftmailer/DataCollector/MessageDataCollector.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Swiftmailer/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Swiftmailer/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/FormExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/RoutingExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/SecurityExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/TranslationExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/YamlExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Node/FormThemeNode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Node/TransDefaultDomainNode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Node/TransNode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/NodeVisitor/TranslationNodeVisitor.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form/form_table_layout.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/Fixtures/StubFilesystemLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/Fixtures/StubTranslator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionDivLayoutTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionTableLayoutTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/child_label.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/custom_widgets.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/parent_label.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/theme.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/theme_extends.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/theme_use.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Node/FormThemeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/TestCase.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/TokenParser/FormThemeTokenParserTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Translation/TwigExtractorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/TokenParser/FormThemeTokenParser.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/TokenParser/TransChoiceTokenParser.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/TokenParser/TransDefaultDomainTokenParser.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/TokenParser/TransTokenParser.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/TwigEngine.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Bridge/Twig/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/RouterCacheWarmer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplateFinder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplateFinderInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplatePathsCacheWarmer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Client.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/CacheWarmupCommand.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ContainerAwareCommand.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/RouterApacheDumperCommand.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/RouterMatchCommand.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ServerRunCommand.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Shell.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerResolver.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/InternalController.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/TemplateController.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/TraceableControllerResolver.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DataCollector/RequestDataCollector.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DataCollector/RouterDataCollector.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddCacheClearerPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddCacheWarmerPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddConstraintValidatorsPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddValidatorInitializersPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CompilerDebugDumpPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ContainerBuilderDebugDumpPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/FormPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ProfilerPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/RegisterKernelListenersPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/RoutingResolverPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TemplatingPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationDumperPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationExtractorPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/EventListener/SessionListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/EventListener/TestSessionListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/HttpCache/HttpCache.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/HttpKernel.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/esi.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/form_csrf.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/router.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing/internal.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/session.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_debug.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/validator.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/css/exception.css create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/css/exception_layout.css create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/blue_picto_less.gif create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/blue_picto_more.gif create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/border_l.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/border_r.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/btn_bg.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/close_quote.gif create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/exception_detected.gif create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/exception_detected.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/grey_magnifier.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/icon_log.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/input_bg.gif create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/logo_symfony.gif create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/logo_symfony.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/open_quote.gif create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/attributes.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/checkbox_widget.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_options.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_expanded.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_options.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/collection_widget.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/container_attributes.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/date_widget.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/datetime_widget.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/email_widget.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_enctype.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_errors.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_label.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_rest.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_row.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_rows.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_widget.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_enctype.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_errors.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_label.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_rest.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_row.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_rows.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_compound.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_simple.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden_row.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden_widget.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/integer_widget.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/money_widget.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/radio_widget.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/repeated_row.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/textarea_widget.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/time_widget.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/url_widget.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget_attributes.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget_container_attributes.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_errors.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_row.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_widget_compound.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/hidden_row.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Routing/RedirectableUrlMatcher.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Asset/PackageFactory.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Asset/PathPackage.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Debugger.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/DelegatingEngine.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/EngineInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/GlobalVariables.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/ActionsHelper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/CodeHelper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/FormHelper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/RequestHelper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/RouterHelper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/SessionHelper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/TranslatorHelper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Loader/FilesystemLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Loader/TemplateLocator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/PhpEngine.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateReference.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/TemplateFinderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TestCaseMethod.tpl create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddCacheWarmerPassTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ProfilerPassTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/RegisterKernelListenersPassTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/TestBundle/Resources/config/validation.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/TestBundle/Resources/config/validation.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/TestBundle/TestBundle.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/deprecated_merge_full.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/deprecated_merge_partial.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/templating_url_package.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_annotations.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/deprecated_merge_full.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/deprecated_merge_partial.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/templating_url_package.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_annotations.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/deprecated_merge_full.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/deprecated_merge_partial.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/templating_url_package.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_annotations.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/PhpFrameworkExtensionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/XmlFrameworkExtensionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/YamlFrameworkExtensionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/EventListener/TestSessionListenerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/BaseBundle/BaseBundle.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/BaseBundle/Resources/views/base.format.engine create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/BaseBundle/Resources/views/controller/base.format.engine create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/BaseBundle/Resources/views/this.is.a.template.format.engine create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/resource.format.engine create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/this.is.a.template.format.engine create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/translation.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Fabpot/FooBundle/Controller/DefaultController.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Fabpot/FooBundle/FabpotFooBundle.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/FooBundle/Controller/DefaultController.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/FooBundle/Controller/Sub/DefaultController.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/FooBundle/Controller/Test/DefaultController.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/FooBundle/FooBundle.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Sensio/Cms/FooBundle/Controller/DefaultController.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Sensio/Cms/FooBundle/SensioCmsFooBundle.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Sensio/FooBundle/Controller/DefaultController.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Sensio/FooBundle/SensioFooBundle.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SessionController.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/TestBundle.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SessionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/WebTestCase.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AppKernel.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Session/bundles.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Session/config.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Session/routing.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/config/default.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/config/framework.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/HttpKernelTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RouterTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/CodeHelperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Fixtures/StubTemplateNameParser.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Fixtures/StubTranslator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperDivLayoutTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperTableLayoutTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/RequestHelperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Child/form_label.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Custom/_text_id_widget.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/form_label.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/form_widget_simple.html.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/SessionHelperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Loader/TemplateLocatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/PhpEngineTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateNameParserTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateReferenceTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/TestCase.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/PhpExtractorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Validator/ConstraintValidatorFactoryTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Translation/TranslationLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Validator/ConstraintValidatorFactory.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Command/InitAclCommand.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddSecurityVotersPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpBasicFactory.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpDigestFactory.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/X509Factory.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/InMemoryFactory.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/UserProviderFactoryInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/EventListener/AclSchemaListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/EventListener/ResponseListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/collectors.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl_dbal.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/security_rememberme.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/templating_php.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/templating_twig.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Security/FirewallMap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/SecurityBundle.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Templating/Helper/LogoutUrlHelper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Templating/Helper/SecurityHelper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/ConfigurationTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/container1.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/custom_acl_provider.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/merge.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/merge_import.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/container1.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/custom_acl_provider.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/merge.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/merge_import.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/container1.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/custom_acl_provider.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/merge.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/merge_import.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/PhpSecurityExtensionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/XmlSecurityExtensionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/YamlSecurityExtensionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticationCommencingTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Controller/LoginController.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/CsrfFormLoginBundle.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Form/UserLoginFormType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Resources/config/routing.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Resources/views/Login/after_login.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Resources/views/Login/login.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Controller/LocalizedController.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Controller/LoginController.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/DependencyInjection/FormLoginExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/FormLoginBundle.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/config/localized_routing.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/config/routing.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/views/Localized/login.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/views/Login/after_login.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/views/Login/login.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Security/LocalizedFormFailureHandler.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/CsrfFormLoginTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/FormLoginTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LocalizedRoutesAsPathTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityRoutingIntegrationTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SwitchUserTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/WebTestCase.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AppKernel.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/bundles.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/config.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/routes_as_path.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/routing.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Resources/views/base.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/bundles.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/config.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/localized_form_failure_handler.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/localized_routes.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/localized_routes_with_forward.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/routes_as_path.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/routing.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/switchuser.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/config/default.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/config/framework.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/config/twig.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Twig/Extension/LogoutUrlExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/CacheWarmer/TemplateCacheCacheWarmer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Command/LintCommand.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Controller/ExceptionController.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Debug/TimedTwigEngine.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExceptionListenerPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TwigEnvironmentPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Extension/ActionsExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Extension/AssetsExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Extension/CodeExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Node/RenderNode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/config/debug.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.atom.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.css.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.js.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.json.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.rdf.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.txt.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.xml.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.atom.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.css.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.js.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.json.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.rdf.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.txt.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.xml.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception_full.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/logs.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/trace.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/trace.txt.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces.txt.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces.xml.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/layout.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/Controller/ExceptionControllerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/php/full.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/xml/full.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/yml/full.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/TestCase.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/TwigEngineTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/TokenParser/RenderTokenParser.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/TwigBundle.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/TwigEngine.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Controller/ExceptionController.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/Configuration.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/WebProfilerExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/ICONS_LICENSE.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/profiler.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/wdt.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/config/schema/webprofiler-1.0.xsd create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/config/toolbar.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/css/profiler.css create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/favicon.ico create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/close.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/config.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/db.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/events.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/exception.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/import.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/logger.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/mail.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/memory.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/bg_submenu.gif create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/bg_submenu.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/border_l.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/border_r.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/btn_bg.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/config.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/db.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/events.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/exception.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/grey_magnifier.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/input_bg.gif create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/logger.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/logo_symfony_profiler.gif create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/logo_symfony_profiler.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/mail.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/request.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/routing.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/security.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/spinner.gif create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/time.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/request.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/routing.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/search.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/security.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/spacer.gif create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/symfony.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/time.png create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/config.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/events.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/memory.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/router.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/admin.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/ajax_layout.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/bag.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/header.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/info.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/results.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/search.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/table.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_item.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_js.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_redirect.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_style.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ExceptionControllerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/ConfigurationTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/WebProfilerExtensionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Tests/EventListener/WebDebugToolbarListenerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Tests/TestCase.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/WebProfilerBundle.php create mode 100644 vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/BrowserKit/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Client.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Cookie.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/BrowserKit/CookieJar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/BrowserKit/History.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/BrowserKit/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/BrowserKit/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Request.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Response.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/ClientTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/CookieJarTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/CookieTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/HistoryTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/RequestTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/ResponseTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/BrowserKit/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/BrowserKit/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/ApcClassLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/ClassLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/ClassMapGenerator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/DebugClassLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/DebugUniversalClassLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/MapClassLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/ApcUniversalClassLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/ClassCollectionLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/ClassLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/ClassMapGeneratorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Namespaced/Bar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Namespaced/Baz.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Namespaced/Foo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Namespaced/FooBar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Pearlike/Bar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Pearlike/Baz.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Pearlike/Foo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/alpha/Apc/ApcPrefixCollision/A/Bar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/alpha/Apc/ApcPrefixCollision/A/Foo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/alpha/Apc/NamespaceCollision/A/Bar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/alpha/Apc/NamespaceCollision/A/Foo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/beta/Apc/ApcPrefixCollision/A/B/Bar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/beta/Apc/ApcPrefixCollision/A/B/Foo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/beta/Apc/NamespaceCollision/A/B/Bar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/beta/Apc/NamespaceCollision/A/B/Foo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/fallback/Apc/Pearlike/FooBar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/fallback/Namespaced/FooBar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced/Bar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced/Baz.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced/Foo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced2/Bar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced2/Baz.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced2/Foo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Pearlike/Bar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Pearlike/Baz.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Pearlike/Foo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Pearlike2/Bar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Pearlike2/Baz.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Pearlike2/Foo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/alpha/NamespaceCollision/A/Bar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/alpha/NamespaceCollision/A/Foo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/alpha/NamespaceCollision/C/Bar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/alpha/NamespaceCollision/C/Foo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/alpha/PrefixCollision/A/Bar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/alpha/PrefixCollision/A/Foo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/alpha/PrefixCollision/C/Bar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/alpha/PrefixCollision/C/Foo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/beta/NamespaceCollision/A/B/Bar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/beta/NamespaceCollision/A/B/Foo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/beta/NamespaceCollision/C/B/Bar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/beta/NamespaceCollision/C/B/Foo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/beta/PrefixCollision/A/B/Bar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/beta/PrefixCollision/A/B/Foo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/beta/PrefixCollision/C/B/Bar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/beta/PrefixCollision/C/B/Foo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/classmap/SomeClass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/classmap/SomeInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/classmap/SomeParent.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/classmap/multipleNs.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/classmap/notAClass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/classmap/notPhpFile.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/classmap/sameNsMultipleClasses.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/fallback/Namespaced/FooBar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/fallback/Namespaced2/FooBar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/fallback/Pearlike/FooBar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/fallback/Pearlike2/FooBar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/includepath/Foo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/php5.4/traits.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/UniversalClassLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/UniversalClassLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/XcacheClassLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/ClassLoader/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/ConfigCache.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/ArrayNode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/BaseNode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/BooleanNode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/BooleanNodeDefinition.php create mode 100755 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/ExprBuilder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/MergeBuilder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/NodeDefinition.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/NodeParentInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/NormalizationBuilder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/ParentNodeDefinitionInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/ScalarNodeDefinition.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/TreeBuilder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/ValidationBuilder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/ConfigurationInterface.php create mode 100755 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/EnumNode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Exception/DuplicateKeyException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Exception/Exception.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Exception/ForbiddenOverwriteException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Exception/InvalidConfigurationException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Exception/InvalidDefinitionException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Exception/InvalidTypeException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Exception/UnsetKeyException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/NodeInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Processor.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/PrototypeNodeInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/PrototypedArrayNode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/ScalarNode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Definition/VariableNode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Exception/FileLoaderLoadException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/FileLocator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/FileLocatorInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Loader/DelegatingLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Loader/FileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Loader/Loader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Loader/LoaderInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Loader/LoaderResolver.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Loader/LoaderResolverInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Resource/DirectoryResource.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Resource/FileResource.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Resource/ResourceInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php create mode 100755 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/Builder/EnumNodeDefinitionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/Builder/NodeBuilderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/Builder/TreeBuilderTest.php create mode 100755 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/EnumNodeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/FinalizationTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/MergeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/NormalizationTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/ProcessorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/FileLocatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Fixtures/Again/foo.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Fixtures/Builder/BarNodeDefinition.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Fixtures/Builder/VariableNodeDefinition.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Fixtures/foo.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Loader/DelegatingLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Loader/LoaderResolverTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Loader/LoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Config/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Application.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Command/HelpCommand.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Command/ListCommand.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Formatter/OutputFormatter.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Formatter/OutputFormatterInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Formatter/OutputFormatterStyle.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Formatter/OutputFormatterStyleInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Formatter/OutputFormatterStyleStack.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Helper/DialogHelper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Helper/FormatterHelper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Helper/Helper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Helper/HelperInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Helper/HelperSet.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArrayInput.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Input/Input.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Input/InputArgument.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Input/InputDefinition.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Input/InputInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Input/InputOption.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Input/StringInput.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Output/ConsoleOutput.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Output/ConsoleOutputInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Output/NullOutput.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Output/Output.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Output/OutputInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Output/StreamOutput.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Shell.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tester/ApplicationTester.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tester/CommandTester.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/ApplicationTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Command/CommandTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Command/HelpCommandTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Command/ListCommandTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/Foo1Command.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/Foo2Command.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/Foo3Command.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/FooCommand.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/TestCommand.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_astext1.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_astext2.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_asxml1.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_asxml2.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_gethelp.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception1.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception2.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception3.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception4.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_run1.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_run2.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_run3.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_run4.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/command_astext.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/command_asxml.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/definition_astext.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/definition_asxml.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleStackTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Helper/DialogHelperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Helper/FormatterHelperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/InputArgumentTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/InputDefinitionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/InputOptionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/InputTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/StringInputTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Output/ConsoleOutputTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Output/NullOutputTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Output/OutputTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Output/StreamOutputTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Tester/ApplicationTesterTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Tester/CommandTesterTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Console/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/CssSelector.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Exception/ParseException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/AttribNode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/ClassNode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/CombinedSelectorNode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/ElementNode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/FunctionNode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/HashNode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/NodeInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/OrNode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/PseudoNode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/CssSelectorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/AttribNodeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/ClassNodeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/CombinedSelectorNodeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/ElementNodeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/FunctionNodeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/HashNodeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/OrNodeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/PseudoNodeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/TokenizerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/XPathExprTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Token.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/TokenStream.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tokenizer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/XPathExpr.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/XPathExprOr.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/CssSelector/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Alias.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/CheckDefinitionValidityPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/CheckReferenceValidityPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/Compiler.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/CompilerPassInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/LoggingFormatter.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/RemoveAbstractDefinitionsPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/RemovePrivateAliasesPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/RemoveUnusedDefinitionsPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/RepeatablePassInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/RepeatedPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ReplaceAliasByActualDefinitionPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ResolveParameterPlaceHoldersPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ResolveReferencesToAliasesPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraph.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraphEdge.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraphNode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ContainerAware.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ContainerAwareInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ContainerBuilder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ContainerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Definition.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/DefinitionDecorator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/Dumper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/DumperInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/GraphvizDumper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/BadMethodCallException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/InactiveScopeException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/InvalidArgumentException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/LogicException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/OutOfBoundsException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ParameterCircularReferenceException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ParameterNotFoundException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/RuntimeException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ScopeCrossingInjectionException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ScopeWideningInjectionException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ServiceCircularReferenceException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ServiceNotFoundException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Extension/ConfigurationExtensionInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Extension/ExtensionInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/IntrospectableContainerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/ClosureLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/IniFileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/PhpFileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Parameter.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ParameterBag/FrozenParameterBag.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBagInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Reference.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Scope.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ScopeInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/SimpleXMLElement.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/TaggedContainerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/AnalyzeServiceReferencesPassTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckCircularReferencesPassTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckDefinitionValidityPassTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckExceptionOnInvalidReferenceBehaviorPassTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckReferenceValidityPassTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/RemoveUnusedDefinitionsPassTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/ReplaceAliasByActualDefinitionPassTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInvalidReferencesPassTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveReferencesToAliasesPassTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/CrossCheckTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/DefinitionDecoratorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Dumper/GraphvizDumperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Dumper/XmlDumperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container10.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container11.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container12.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container8.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/interfaces1.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/interfaces2.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services1.dot create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services10-1.dot create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services10.dot create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/ProjectExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/ProjectWithXsdExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/ProjectWithXsdExtensionInPhar.phar create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/createphar.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/foo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/schema/project-1.0.xsd create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ini/nonvalid.ini create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ini/parameters.ini create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ini/parameters1.ini create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ini/parameters2.ini create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services10.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services8.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/simple.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extension1/services.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extension2/services.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services1.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services2.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services3.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services4.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services5.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services6.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services7.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/nonvalid.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services1.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services13.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services2.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services3.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services4.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services4_bad_import.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services5.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services6.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services7.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services8.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/badtag1.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/badtag2.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/badtag3.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/nonvalid1.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/nonvalid2.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services1.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services10.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services11.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services13.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services2.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services3.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services4.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services4_bad_import.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services6.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services7.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services8.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Loader/ClosureLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Loader/IniFileLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Loader/PhpFileLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ParameterBag/FrozenParameterBagTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ParameterBag/ParameterBagTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ParameterTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ReferenceTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Variable.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Crawler.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Field/FileFormField.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Field/FormField.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Field/InputFormField.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Field/TextareaFormField.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Form.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Link.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Tests/Field/ChoiceFormFieldTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Tests/Field/FileFormFieldTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Tests/Field/FormFieldTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Tests/Field/FormFieldTestCase.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Tests/Field/InputFormFieldTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Tests/Field/TextareaFormFieldTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Tests/FormTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Tests/LinkTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/DomCrawler/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcherInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Event.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcherInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventSubscriberInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/GenericEvent.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Tests/ContainerAwareEventDispatcherTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Tests/EventDispatcherTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Tests/EventTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Tests/GenericEventTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Tests/UnmodifiableEventDispatcherTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/UnmodifiableEventDispatcher.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Filesystem/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Filesystem/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Filesystem/Exception/IOException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Filesystem/Filesystem.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Filesystem/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Filesystem/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Filesystem/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Filesystem/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Filesystem/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Comparator/Comparator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Comparator/DateComparator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Comparator/NumberComparator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Finder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Glob.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Iterator/CustomFilterIterator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Iterator/DateRangeFilterIterator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Iterator/DepthRangeFilterIterator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Iterator/SortableIterator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/SplFileInfo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/Comparator/ComparatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/Comparator/DateComparatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/Comparator/NumberComparatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/FinderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/Fixtures/dolor.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/Fixtures/ipsum.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/Fixtures/lorem.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/GlobTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/Iterator/CustomFilterIteratorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/Iterator/DateRangeFilterIteratorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/Iterator/DepthRangeIteratorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFileIteratorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/Iterator/FileTypeFilterIteratorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/Iterator/FilenameFilterIteratorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/Iterator/Iterator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/Iterator/IteratorTestCase.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/Iterator/MultiplePcreFilterIteratorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/Iterator/RealIteratorTestCase.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/Iterator/SizeRangeFilterIteratorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Finder/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/AbstractExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/AbstractType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/AbstractTypeExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/CallbackTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/CallbackValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/DataMapperInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/DataTransformerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Event/DataEvent.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Event/FilterDataEvent.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Exception/AlreadyBoundException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Exception/CircularReferenceException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Exception/CreationException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Exception/ErrorMappingException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Exception/FormException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Exception/InvalidConfigurationException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Exception/InvalidPropertyException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Exception/InvalidPropertyPathException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Exception/NotInitializedException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Exception/NotValidException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Exception/PropertyAccessDeniedException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Exception/StringCastException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Exception/TransformationFailedException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Exception/TypeDefinitionException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Exception/TypeLoaderException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Exception/UnexpectedTypeException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceList.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceListInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/ChoiceList/LazyChoiceList.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/ChoiceList/ObjectChoiceList.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/ChoiceList/SimpleChoiceList.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/CoreExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataMapper/PropertyPathMapper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataTransformer/ArrayToPartsTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataTransformer/BaseDateTimeTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataTransformer/BooleanToStringTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoiceToBooleanArrayTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoiceToValueTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoicesToBooleanArrayTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoicesToValuesTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataTransformer/DataTransformerChain.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToTimestampTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataTransformer/PercentToLocalizedStringTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataTransformer/ValueToDuplicatesTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataTransformer/ValueToStringTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/EventListener/FixCheckboxInputListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/EventListener/FixRadioInputListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/EventListener/FixUrlProtocolListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/EventListener/MergeCollectionListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/EventListener/ResizeFormListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/EventListener/TrimListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/BirthdayType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/CheckboxType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/CollectionType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/DateType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/EmailType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/FieldType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/FileType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/FormType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/HiddenType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/IntegerType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/LocaleType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/MoneyType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/NumberType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/PasswordType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/PercentType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/RadioType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/RepeatedType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/SearchType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/TextType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/TextareaType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/UrlType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/View/ChoiceView.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Csrf/CsrfExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Csrf/CsrfProvider/CsrfProviderInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Csrf/CsrfProvider/DefaultCsrfProvider.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Csrf/CsrfProvider/SessionCsrfProvider.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/DependencyInjection/DependencyInjectionExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Validator/Constraints/Form.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Validator/EventListener/ValidationListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Validator/Type/FormTypeValidatorExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Validator/Type/RepeatedTypeValidatorExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Validator/Util/ServerParams.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Validator/ValidatorExtension.php create mode 100755 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/MappingRule.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/RelativePath.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapperInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationPath.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationPathIterator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Form.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/FormBuilder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/FormBuilderInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/FormConfig.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/FormConfigEditorInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/FormConfigInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/FormError.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/FormEvent.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/FormEvents.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/FormExtensionInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/FormFactory.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/FormFactoryInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/FormInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/FormTypeExtensionInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/FormTypeGuesserChain.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/FormTypeGuesserInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/FormTypeInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/FormValidatorInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/FormView.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/FormViewInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Guess/Guess.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Guess/TypeGuess.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Guess/ValueGuess.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/config/validation.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.ca.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.cs.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.da.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.de.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.en.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.es.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.et.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.eu.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.fa.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.fi.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.fr.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.he.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.hr.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.hu.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.hy.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.id.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.it.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.ja.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.lb.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.lt.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.mn.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.nb.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.nl.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.pl.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.pt.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.pt_BR.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.ro.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.ru.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.sk.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.sl.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.sr_Cyrl.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.sr_Latn.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.sv.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.ua.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations/validators.zh_CN.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/ReversedTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/AbstractDivLayoutTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/AbstractExtensionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/AbstractTableLayoutTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/ChoiceListTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/LazyChoiceListTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/ObjectChoiceListTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/SimpleChoiceListTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/DataMapper/PropertyPathMapperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ArrayToPartsTransformerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/BooleanToStringTransformerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoiceToValueTransformerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoicesToValuesTransformerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DataTransformerChainTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeTestCase.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToArrayTransformerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToStringTransformerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToTimestampTransformerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/LocalizedTestCase.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ValueToDuplicatesTransformerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ValueToStringTransformerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixRadioInputListenerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/Fixtures/randomhash create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerArrayObjectTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerArrayTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerCustomArrayObjectTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/ResizeFormListenerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/TrimListenerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/Type/CheckboxTypeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/Type/CollectionTypeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/Type/CountryTypeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/Type/FormTypeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/Type/LanguageTypeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/Type/LocaleTypeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/Type/LocalizedTestCase.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/Type/MoneyTypeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/Type/NumberTypeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/Type/PasswordTypeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/Type/RepeatedTypeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimezoneTypeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/Type/TypeTestCase.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Csrf/CsrfProvider/DefaultCsrfProviderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Csrf/CsrfProvider/SessionCsrfProviderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Csrf/Type/FormTypeCsrfExtensionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Validator/EventListener/ValidationListenerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Validator/Type/TypeTestCase.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationPathTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Fixtures/Author.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Fixtures/AuthorType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Fixtures/CustomArrayObject.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Fixtures/FixedDataTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Fixtures/FixedFilterListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Fixtures/FooType.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Fixtures/FooTypeBarExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Fixtures/FooTypeBazExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Fixtures/Magician.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Fixtures/TestExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Fixtures/foo create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/FormBuilderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/FormConfigTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/FormFactoryTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/FormInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/FormTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Guess/GuessTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Util/FormUtilTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Util/PropertyPathArrayObjectTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Util/PropertyPathArrayTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Util/PropertyPathBuilderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Util/PropertyPathCollectionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Util/PropertyPathCustomArrayObjectTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Util/PropertyPathTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/UnmodifiableFormConfig.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Util/FormUtil.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Util/PropertyPath.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Util/PropertyPathBuilder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Util/PropertyPathInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Util/PropertyPathIterator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Util/PropertyPathIteratorInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/Util/VirtualFormAwareIterator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Form/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/ApacheRequest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Cookie.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/File/Exception/AccessDeniedException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/File/Exception/FileException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/File/Exception/FileNotFoundException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/File/Exception/UnexpectedTypeException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/File/Exception/UploadException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/File/File.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/File/MimeType/ExtensionGuesser.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/File/MimeType/ExtensionGuesserInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/File/MimeType/FileinfoMimeTypeGuesser.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeExtensionGuesser.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeGuesser.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeGuesserInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/File/UploadedFile.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/FileBag.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/HeaderBag.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/JsonResponse.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/ParameterBag.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/RedirectResponse.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Request.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/RequestMatcher.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/RequestMatcherInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Resources/stubs/SessionHandlerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Response.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/ResponseHeaderBag.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/ServerBag.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Attribute/AttributeBag.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Attribute/AttributeBagInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Flash/AutoExpireFlashBag.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Flash/FlashBag.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Flash/FlashBagInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Session.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/SessionBagInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/SessionInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/FileSessionHandler.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcacheSessionHandler.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcachedSessionHandler.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MongoDbSessionHandler.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/NullSessionHandler.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Storage/MetadataBag.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Storage/MockFileSessionStorage.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Storage/Proxy/AbstractProxy.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Storage/Proxy/NativeProxy.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Storage/Proxy/SessionHandlerProxy.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Storage/SessionStorageInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/StreamedResponse.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/ApacheRequestTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/File/FileTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/File/Fixtures/.unknownextension create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/File/Fixtures/directory/.empty create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/File/Fixtures/test create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/File/Fixtures/test.gif create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/File/MimeType/MimeTypeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/File/UploadedFileTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/FileBagTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/HeaderBagTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/ParameterBagTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/RedirectResponseTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/RequestMatcherTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/ServerBagTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/Session/Attribute/AttributeBagTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/Session/Flash/AutoExpireFlashBagTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/Session/Flash/FlashBagTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/Session/SessionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/FileSessionHandlerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcacheSessionHandlerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MongoDbSessionHandlerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/NullSessionHandlerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/MetadataBagTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/MockArraySessionStorageTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/MockFileSessionStorageTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Proxy/AbstractProxyTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Proxy/NativeProxyTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/StreamedResponseTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Bundle/Bundle.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Bundle/BundleInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/CacheClearer/CacheClearerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/CacheClearer/ChainCacheClearer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmerAggregate.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/CacheWarmer/WarmableInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Client.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Config/FileLocator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Controller/ControllerResolverInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/DataCollector/DataCollectorInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/DataCollector/EventDataCollector.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/DataCollector/ExceptionDataCollector.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/DataCollector/MemoryDataCollector.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/DataCollector/TimeDataCollector.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Debug/ContainerAwareTraceableEventDispatcher.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Debug/ErrorHandler.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Debug/ExceptionHandler.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Debug/Stopwatch.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Debug/StopwatchEvent.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/DependencyInjection/AddClassesToCachePass.php create mode 100755 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/DependencyInjection/ConfigurableExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/DependencyInjection/Extension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/DependencyInjection/MergeExtensionConfigurationPass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Event/FilterControllerEvent.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Event/FilterResponseEvent.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Event/GetResponseEvent.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Event/GetResponseForControllerResultEvent.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Event/GetResponseForExceptionEvent.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Event/KernelEvent.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Event/PostResponseEvent.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/EventListener/EsiListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/EventListener/LocaleListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/EventListener/ProfilerListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/EventListener/ResponseListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/EventListener/StreamedResponseListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Exception/AccessDeniedHttpException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Exception/FlattenException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Exception/HttpException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Exception/HttpExceptionInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Exception/MethodNotAllowedHttpException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Exception/NotFoundHttpException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpCache/Esi.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpCache/EsiResponseCacheStrategy.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpCache/EsiResponseCacheStrategyInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpCache/Store.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpCache/StoreInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernelInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/KernelEvents.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/KernelInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Log/DebugLoggerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Log/LoggerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Log/NullLogger.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Profiler/BaseMemcacheProfilerStorage.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Profiler/MemcacheProfilerStorage.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Profiler/MemcachedProfilerStorage.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Profiler/MongoDbProfilerStorage.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Profiler/MysqlProfilerStorage.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Profiler/PdoProfilerStorage.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Profiler/Profile.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Profiler/Profiler.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Profiler/ProfilerStorageInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Profiler/RedisProfilerStorage.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Profiler/SqliteProfilerStorage.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/TerminableInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Bundle/BundleTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/CacheClearer/ChainCacheClearerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/CacheWarmer/CacheWarmerAggregateTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/CacheWarmer/CacheWarmerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/ClientTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/DataCollector/ConfigDataCollectorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/DataCollector/EventDataCollectorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/DataCollector/ExceptionDataCollectorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/DataCollector/LoggerDataCollectorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/DataCollector/MemoryDataCollectorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Debug/ContainerAwareTraceableEventDispatcherTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Debug/ErrorHandlerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Debug/ExceptionHandlerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Debug/StopwatchEventTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Debug/StopwatchTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/MergeExtensionConfigurationPassTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/EventListener/EsiListenerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/EventListener/LocaleListenerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/EventListener/ResponseListenerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Exception/FlattenExceptionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/BaseBundle/Resources/foo.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/BaseBundle/Resources/hide.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/Bundle1Bundle/Resources/foo.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/Bundle1Bundle/bar.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/Bundle1Bundle/foo.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/Bundle2Bundle/foo.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/ChildBundle/Resources/foo.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/ChildBundle/Resources/hide.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/ExtensionAbsentBundle/ExtensionAbsentBundle.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/ExtensionLoadedBundle/DependencyInjection/ExtensionLoadedExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/ExtensionLoadedBundle/ExtensionLoadedBundle.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/ExtensionPresentBundle/Command/FooCommand.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/ExtensionPresentBundle/DependencyInjection/ExtensionPresentExtension.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/ExtensionPresentBundle/ExtensionPresentBundle.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/FooBarBundle.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/KernelForTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/Resources/BaseBundle/hide.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/Resources/Bundle1Bundle/foo.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/Resources/ChildBundle/foo.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/Resources/FooBundle/foo.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/TestClient.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Fixtures/TestEventDispatcher.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/HttpCache/EsiTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTestCase.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestHttpKernel.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestMultipleHttpKernel.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/HttpKernelTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/KernelTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Logger.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Profiler/AbstractProfilerStorageTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Profiler/FileProfilerStorageTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Profiler/MemcacheProfilerStorageTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Profiler/MemcachedProfilerStorageTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Profiler/Mock/MemcacheMock.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Profiler/Mock/MemcachedMock.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Profiler/Mock/RedisMock.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Profiler/MongoDbProfilerStorageTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Profiler/ProfilerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Profiler/RedisProfilerStorageTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/Profiler/SqliteProfilerStorageTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/TestHttpKernel.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/HttpKernel/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Exception/MethodArgumentNotImplementedException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Exception/MethodArgumentValueNotImplementedException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Exception/MethodNotImplementedException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Exception/NotImplementedException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Locale.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/UPDATE.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/af.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ak.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/am.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ar.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/as.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/asa.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/az.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/az_AZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/az_Cyrl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/az_Latn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/az_Latn_AZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/be.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/bem.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/bez.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/bg.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/bm.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/bn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/bn_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/bo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/bs.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ca.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/cgg.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/chr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/cs.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/cy.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/da.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/dav.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/de.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/de_CH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ebu.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ee.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/el.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/en.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/en_RH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/en_ZW.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/eo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/es.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/es_AR.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/es_CL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/et.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/eu.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/fa.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/fa_AF.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ff.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/fi.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/fil.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/fil_PH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/fo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/fr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ga.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/gl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/gsw.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/gu.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/guz.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/gv.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ha.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ha_GH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ha_Latn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ha_Latn_GH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ha_Latn_NE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ha_Latn_NG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ha_NE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ha_NG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/haw.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/he.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/he_IL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/hi.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/hr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/hu.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/hy.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/id.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/id_ID.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ig.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ii.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/in.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/in_ID.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/is.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/it.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/iw.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/iw_IL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ja.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ja_JP.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ja_JP_TRADITIONAL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/jmc.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ka.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/kab.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/kam.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/kde.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/kea.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/khq.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ki.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/kk.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/kk_Cyrl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/kk_Cyrl_KZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/kk_KZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/kl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/kln.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/km.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/kn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ko.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/kok.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/kw.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/lag.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/lg.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/lt.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/luo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/luy.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/lv.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/mas.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/mer.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/mfe.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/mg.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/mk.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ml.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/mo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/mr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ms.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/mt.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/my.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/naq.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/nb.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/nb_NO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/nd.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ne.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/nl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/nl_BE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/nn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/nn_NO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/no.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/no_NO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/no_NO_NY.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/nyn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/om.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/or.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/pa.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/pa_Arab.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/pa_Arab_PK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/pa_Guru.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/pa_Guru_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/pa_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/pa_PK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/pl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ps.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/pt.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/pt_PT.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/rm.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ro.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ro_MD.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/rof.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/root.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ru.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ru_UA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/rw.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/rwk.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/saq.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/seh.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ses.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sg.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sh.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sh_BA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sh_CS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sh_YU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/shi.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/shi_Latn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/shi_Latn_MA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/shi_MA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/shi_Tfng.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/si.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sk.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/so.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sq.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sr_BA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sr_CS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sr_Cyrl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sr_Cyrl_BA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sr_Cyrl_CS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sr_Cyrl_RS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sr_Cyrl_YU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sr_Latn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sr_Latn_BA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sr_Latn_CS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sr_Latn_ME.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sr_Latn_RS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sr_Latn_YU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sr_ME.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sr_RS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sr_YU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sv.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sv_FI.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/sw.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ta.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/te.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/teo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/th.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/th_TH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/th_TH_TRADITIONAL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ti.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/tl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/tl_PH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/to.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/tr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/tzm.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/tzm_Latn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/tzm_Latn_MA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/tzm_MA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/uk.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/ur.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/uz.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/uz_AF.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/uz_Arab.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/uz_Arab_AF.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/uz_Cyrl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/uz_Cyrl_UZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/uz_Latn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/uz_UZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/vi.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/vun.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/xog.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/yo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/zh.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/zh_CN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/zh_HK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/zh_Hans.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/zh_Hans_CN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/zh_Hans_SG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/zh_Hant.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/zh_Hant_HK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/zh_Hant_MO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/zh_Hant_TW.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/zh_MO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/zh_SG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/zh_TW.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/lang/zu.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/af.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/af_NA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/af_ZA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ak.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ak_GH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/am.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/am_ET.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ar.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ar_AE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ar_BH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ar_DZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ar_EG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ar_IQ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ar_JO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ar_KW.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ar_LB.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ar_LY.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ar_MA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ar_OM.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ar_QA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ar_SA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ar_SD.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ar_SY.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ar_TN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ar_YE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/as.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/as_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/asa.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/asa_TZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/az.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/az_AZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/az_Cyrl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/az_Cyrl_AZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/az_Latn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/az_Latn_AZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/be.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/be_BY.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/bem.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/bem_ZM.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/bez.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/bez_TZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/bg.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/bg_BG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/bm.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/bm_ML.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/bn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/bn_BD.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/bn_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/bo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/bo_CN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/bo_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/bs.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/bs_BA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ca.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ca_ES.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/cgg.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/cgg_UG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/chr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/chr_US.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/cs.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/cs_CZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/cy.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/cy_GB.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/da.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/da_DK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/dav.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/dav_KE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/de.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/de_AT.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/de_BE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/de_CH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/de_DE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/de_LI.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/de_LU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ebu.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ebu_KE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ee.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ee_GH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ee_TG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/el.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/el_CY.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/el_GR.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_AS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_AU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_BE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_BW.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_BZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_CA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_GB.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_GU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_HK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_IE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_JM.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_MH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_MP.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_MT.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_MU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_NA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_NZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_PH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_PK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_RH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_SG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_TT.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_UM.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_US.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_US_POSIX.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_VI.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_ZA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/en_ZW.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/eo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_419.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_AR.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_BO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_CL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_CO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_CR.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_DO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_EC.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_ES.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_GQ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_GT.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_HN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_MX.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_NI.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_PA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_PE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_PR.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_PY.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_SV.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_US.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_UY.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/es_VE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/et.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/et_EE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/eu.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/eu_ES.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fa.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fa_AF.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fa_IR.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ff.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ff_SN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fi.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fi_FI.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fil.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fil_PH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fo_FO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_BE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_BF.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_BI.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_BJ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_BL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_CA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_CD.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_CF.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_CG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_CH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_CI.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_CM.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_DJ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_FR.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_GA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_GN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_GP.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_GQ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_KM.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_LU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_MC.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_MF.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_MG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_ML.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_MQ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_NE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_RE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_RW.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_SN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_TD.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/fr_TG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ga.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ga_IE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/gl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/gl_ES.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/gsw.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/gsw_CH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/gu.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/gu_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/guz.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/guz_KE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/gv.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/gv_GB.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ha.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ha_GH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ha_Latn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ha_Latn_GH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ha_Latn_NE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ha_Latn_NG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ha_NE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ha_NG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/haw.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/haw_US.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/he.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/he_IL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/hi.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/hi_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/hr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/hr_HR.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/hu.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/hu_HU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/hy.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/hy_AM.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/id.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/id_ID.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ig.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ig_NG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ii.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ii_CN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/in.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/in_ID.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/is.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/is_IS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/it.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/it_CH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/it_IT.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/iw.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/iw_IL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ja.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ja_JP.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ja_JP_TRADITIONAL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/jmc.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/jmc_TZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ka.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ka_GE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kab.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kab_DZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kam.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kam_KE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kde.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kde_TZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kea.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kea_CV.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/khq.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/khq_ML.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ki.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ki_KE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kk.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kk_Cyrl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kk_Cyrl_KZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kk_KZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kl_GL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kln.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kln_KE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/km.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/km_KH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kn_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ko.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ko_KR.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kok.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kok_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kw.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/kw_GB.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/lag.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/lag_TZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/lg.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/lg_UG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/lt.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/lt_LT.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/luo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/luo_KE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/luy.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/luy_KE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/lv.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/lv_LV.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/mas.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/mas_KE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/mas_TZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/mer.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/mer_KE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/mfe.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/mfe_MU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/mg.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/mg_MG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/mk.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/mk_MK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ml.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ml_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/mo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/mr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/mr_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ms.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ms_BN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ms_MY.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/mt.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/mt_MT.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/my.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/my_MM.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/naq.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/naq_NA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/nb.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/nb_NO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/nd.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/nd_ZW.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ne.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ne_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ne_NP.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/nl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/nl_BE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/nl_NL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/nn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/nn_NO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/no.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/no_NO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/no_NO_NY.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/nyn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/nyn_UG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/om.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/om_ET.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/om_KE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/or.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/or_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/pa.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/pa_Arab.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/pa_Arab_PK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/pa_Guru.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/pa_Guru_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/pa_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/pa_PK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/pl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/pl_PL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ps.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ps_AF.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/pt.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/pt_BR.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/pt_GW.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/pt_MZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/pt_PT.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/rm.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/rm_CH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ro.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ro_MD.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ro_RO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/rof.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/rof_TZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/root.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ru.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ru_MD.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ru_RU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ru_UA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/rw.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/rw_RW.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/rwk.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/rwk_TZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/saq.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/saq_KE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/seh.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/seh_MZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ses.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ses_ML.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sg.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sg_CF.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sh.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sh_BA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sh_CS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sh_YU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/shi.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/shi_Latn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/shi_Latn_MA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/shi_MA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/shi_Tfng.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/shi_Tfng_MA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/si.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/si_LK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sk.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sk_SK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sl_SI.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sn_ZW.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/so.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/so_DJ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/so_ET.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/so_KE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/so_SO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sq.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sq_AL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sr_BA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sr_CS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sr_Cyrl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sr_Cyrl_BA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sr_Cyrl_CS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sr_Cyrl_ME.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sr_Cyrl_RS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sr_Cyrl_YU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sr_Latn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sr_Latn_BA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sr_Latn_CS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sr_Latn_ME.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sr_Latn_RS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sr_Latn_YU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sr_ME.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sr_RS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sr_YU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sv.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sv_FI.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sv_SE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sw.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sw_KE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/sw_TZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ta.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ta_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ta_LK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/te.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/te_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/teo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/teo_KE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/teo_UG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/th.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/th_TH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/th_TH_TRADITIONAL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ti.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ti_ER.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ti_ET.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/tl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/tl_PH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/to.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/to_TO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/tr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/tr_TR.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/tzm.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/tzm_Latn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/tzm_Latn_MA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/tzm_MA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/uk.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/uk_UA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ur.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ur_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/ur_PK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/uz.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/uz_AF.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/uz_Arab.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/uz_Arab_AF.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/uz_Cyrl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/uz_Cyrl_UZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/uz_Latn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/uz_Latn_UZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/uz_UZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/vi.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/vi_VN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/vun.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/vun_TZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/xog.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/xog_UG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/yo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/yo_NG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/zh.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/zh_CN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/zh_HK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/zh_Hans.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/zh_Hans_CN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/zh_Hans_HK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/zh_Hans_MO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/zh_Hans_SG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/zh_Hant.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/zh_Hant_HK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/zh_Hant_MO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/zh_Hant_TW.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/zh_MO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/zh_SG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/zh_TW.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/zu.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/locales/zu_ZA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/ar.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/bg.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/bs.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/ca.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/da.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/de.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/de_CH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/el.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/en.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/en_RH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/en_ZW.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/es.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/es_AR.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/es_CL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/et.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/fa.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/fa_AF.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/fi.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/fr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/gsw.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/gu.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/he.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/he_IL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/hi.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/hr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/hu.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/it.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/iw.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/iw_IL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/ja.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/ja_JP.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/ja_JP_TRADITIONAL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/ko.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/lt.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/lv.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/mk.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/ml.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/mo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/mr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/mt.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/my.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/nb.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/nb_NO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/ne.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/nl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/nl_BE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/nn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/nn_NO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/no.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/no_NO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/no_NO_NY.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/pl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/pt.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/pt_PT.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/rm.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/ro.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/ro_MD.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/ru.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sh.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sh_BA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sh_CS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sh_YU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sr_BA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sr_CS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sr_Cyrl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sr_Cyrl_BA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sr_Cyrl_CS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sr_Cyrl_RS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sr_Cyrl_YU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sr_Latn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sr_Latn_BA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sr_Latn_CS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sr_Latn_ME.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sr_Latn_RS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sr_Latn_YU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sr_ME.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sr_RS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sr_YU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sv.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/sv_FI.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/ta.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/te.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/th.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/th_TH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/th_TH_TRADITIONAL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/tr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/uk.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/zh.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/zh_CN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/zh_HK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/zh_Hans.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/zh_Hans_CN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/zh_Hans_SG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/zh_Hant.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/zh_Hant_HK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/zh_Hant_MO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/zh_Hant_TW.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/zh_MO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/zh_SG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/names/zh_TW.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/af.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ak.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/am.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ar.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/as.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/asa.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/az.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/az_AZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/az_Cyrl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/az_Latn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/az_Latn_AZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/be.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/bem.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/bez.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/bg.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/bm.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/bn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/bo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/bs.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ca.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/cgg.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/chr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/cs.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/cy.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/da.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/dav.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/de.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/de_CH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ebu.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ee.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/el.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/en.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/en_RH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/en_ZW.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/eo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/es.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/es_CL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/et.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/eu.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/fa.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/fa_AF.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ff.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/fi.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/fil.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/fil_PH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/fo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/fr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ga.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/gl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/gsw.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/gu.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/guz.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/gv.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ha.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ha_GH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ha_Latn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ha_Latn_GH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ha_Latn_NE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ha_Latn_NG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ha_NE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ha_NG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/haw.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/he.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/he_IL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/hi.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/hr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/hu.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/hy.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/id.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/id_ID.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ig.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ii.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/in.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/in_ID.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/is.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/it.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/iw.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/iw_IL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ja.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ja_JP.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ja_JP_TRADITIONAL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/jmc.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ka.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/kab.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/kam.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/kde.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/kea.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/khq.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ki.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/kk.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/kk_Cyrl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/kk_Cyrl_KZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/kk_KZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/kl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/kln.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/km.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/kn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ko.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/kok.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/kw.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/lag.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/lg.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/lt.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/luo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/luy.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/lv.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/mas.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/mer.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/mfe.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/mg.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/mk.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ml.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/mo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/mr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ms.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/mt.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/my.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/naq.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/nb.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/nb_NO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/nd.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ne.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/nl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/nl_BE.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/nn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/nn_NO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/no.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/no_NO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/no_NO_NY.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/nyn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/om.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/or.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/pa.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/pa_Arab.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/pa_Arab_PK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/pa_Guru.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/pa_Guru_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/pa_IN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/pa_PK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/pl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ps.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/pt.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/pt_PT.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/rm.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ro.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ro_MD.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/rof.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/root.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ru.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/rw.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/rwk.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/saq.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/seh.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ses.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sg.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sh.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sh_BA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sh_CS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sh_YU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/shi.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/shi_Latn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/shi_Latn_MA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/shi_MA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/shi_Tfng.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/si.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sk.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/so.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sq.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sr_BA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sr_CS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sr_Cyrl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sr_Cyrl_BA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sr_Cyrl_CS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sr_Cyrl_RS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sr_Cyrl_YU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sr_Latn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sr_Latn_BA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sr_Latn_CS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sr_Latn_ME.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sr_Latn_RS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sr_Latn_YU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sr_ME.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sr_RS.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sr_YU.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sv.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sv_FI.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/sw.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ta.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/te.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/teo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/th.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/th_TH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/th_TH_TRADITIONAL.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ti.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/tl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/tl_PH.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/to.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/tr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/tzm.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/tzm_Latn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/tzm_Latn_MA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/tzm_MA.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/uk.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/ur.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/uz.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/uz_AF.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/uz_Arab.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/uz_Arab_AF.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/uz_Cyrl.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/uz_Cyrl_UZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/uz_Latn.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/uz_UZ.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/vi.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/vun.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/xog.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/yo.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/zh.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/zh_CN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/zh_HK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/zh_Hans.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/zh_Hans_CN.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/zh_Hans_SG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/zh_Hant.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/zh_Hant_HK.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/zh_Hant_MO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/zh_Hant_TW.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/zh_MO.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/zh_SG.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/zh_TW.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/region/zu.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/stub/curr/en.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/stub/lang/en.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/stub/names/en.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/stub/region/en.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/data/update-data.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/stubs/Collator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/stubs/IntlDateFormatter.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/stubs/Locale.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/stubs/NumberFormatter.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/stubs/functions.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/DateFormat/AmPmTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/DateFormat/DayOfWeekTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/DateFormat/DayOfYearTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/DateFormat/DayTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/DateFormat/FullTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/DateFormat/Hour1200Transformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/DateFormat/Hour1201Transformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/DateFormat/Hour2400Transformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/DateFormat/Hour2401Transformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/DateFormat/HourTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/DateFormat/MinuteTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/DateFormat/MonthTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/DateFormat/QuarterTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/DateFormat/SecondTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/DateFormat/TimeZoneTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/DateFormat/Transformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/DateFormat/YearTransformer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/StubCollator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/StubIntl.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/StubIntlDateFormatter.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/StubLocale.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/StubNumberFormatter.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Tests/LocaleTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Tests/Stub/StubCollatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Tests/Stub/StubIntlDateFormatterTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Tests/Stub/StubIntlTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Tests/Stub/StubLocaleTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Tests/Stub/StubNumberFormatterTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Tests/TestCase.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Locale/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/OptionsResolver/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/OptionsResolver/Exception/InvalidOptionsException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/OptionsResolver/Exception/MissingOptionsException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/OptionsResolver/Exception/OptionDefinitionException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/OptionsResolver/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/OptionsResolver/LazyOption.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/OptionsResolver/Options.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/OptionsResolver/OptionsResolver.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/OptionsResolver/OptionsResolverInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/OptionsResolver/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/OptionsResolver/Tests/OptionsTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/OptionsResolver/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/OptionsResolver/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/OptionsResolver/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Process/CHANGELOG.md create mode 100755 vendor/symfony/symfony/src/Symfony/Component/Process/Exception/ExceptionInterface.php create mode 100755 vendor/symfony/symfony/src/Symfony/Component/Process/Exception/ProcessFailedException.php create mode 100755 vendor/symfony/symfony/src/Symfony/Component/Process/Exception/RuntimeException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Process/ExecutableFinder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Process/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Process/PhpExecutableFinder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Process/PhpProcess.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Process/Process.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Process/ProcessBuilder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Process/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Process/Tests/PhpExecutableFinderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Process/Tests/ProcessBuilderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Process/Tests/ProcessFailedExceptionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Process/Tests/ProcessTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Process/Tests/ProcessTestHelper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Process/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Process/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Process/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Annotation/Route.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/CompiledRoute.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Exception/InvalidParameterException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Exception/MethodNotAllowedException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Exception/MissingMandatoryParametersException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Exception/ResourceNotFoundException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Exception/RouteNotFoundException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Generator/Dumper/GeneratorDumper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Generator/Dumper/GeneratorDumperInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Generator/UrlGenerator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Generator/UrlGeneratorInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Loader/AnnotationFileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Loader/ClosureLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Loader/PhpFileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Loader/XmlFileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Loader/YamlFileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Matcher/ApacheUrlMatcher.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Matcher/Dumper/MatcherDumper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Matcher/Dumper/MatcherDumperInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Matcher/RedirectableUrlMatcherInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Matcher/RequestMatcherInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Matcher/UrlMatcher.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Matcher/UrlMatcherInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/RequestContext.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/RequestContextAwareInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Route.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/RouteCollection.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/RouteCompiler.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/RouteCompilerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Router.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/RouterInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Annotation/RouteTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/CompiledRouteTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/AnnotatedClasses/AbstractClass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/AnnotatedClasses/FooClass.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/CustomXmlFileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/RedirectableUrlMatcher.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/annotated.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher1.apache create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher1.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.apache create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher3.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/empty.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/foo.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/foo1.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/incomplete.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/nonvalid.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/nonvalid.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/nonvalidkeys.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/nonvalidnode.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/nonvalidroute.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/validpattern.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/validpattern.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/validpattern.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/validresource.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Fixtures/validresource.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Loader/AbstractAnnotationLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Loader/AnnotationDirectoryLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Loader/AnnotationFileLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Loader/ClosureLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Loader/PhpFileLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Matcher/ApacheUrlMatcherTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Matcher/Dumper/ApacheMatcherDumperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Matcher/TraceableUrlMatcherTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/RouteCollectionTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/RouteTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Routing/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Dbal/AclProvider.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Dbal/MutableAclProvider.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Dbal/Schema.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Domain/Acl.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Domain/AclCollectionCache.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Domain/AuditLogger.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Domain/DoctrineAclCache.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Domain/Entry.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Domain/FieldEntry.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Domain/ObjectIdentity.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Domain/ObjectIdentityRetrievalStrategy.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Domain/PermissionGrantingStrategy.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Domain/RoleSecurityIdentity.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Domain/SecurityIdentityRetrievalStrategy.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Domain/UserSecurityIdentity.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Exception/AclAlreadyExistsException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Exception/AclNotFoundException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Exception/ConcurrentModificationException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Exception/Exception.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Exception/InvalidDomainObjectException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Exception/NoAceFoundException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Exception/NotAllAclsFoundException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Exception/SidNotLoadedException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Model/AclCacheInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Model/AclInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Model/AclProviderInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Model/AuditLoggerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Model/AuditableAclInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Model/AuditableEntryInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Model/DomainObjectInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Model/EntryInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Model/FieldEntryInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Model/MutableAclInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Model/MutableAclProviderInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Model/ObjectIdentityInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Model/ObjectIdentityRetrievalStrategyInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Model/PermissionGrantingStrategyInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Model/SecurityIdentityInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Model/SecurityIdentityRetrievalStrategyInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Permission/BasicPermissionMap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Permission/MaskBuilder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Permission/PermissionMapInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Resources/bin/generateSql.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Resources/schema/db2.sql create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Resources/schema/drizzle.sql create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Resources/schema/mssql.sql create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Resources/schema/mysql.sql create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Resources/schema/oracle.sql create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Resources/schema/postgresql.sql create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Resources/schema/sqlite.sql create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Voter/AclVoter.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Acl/Voter/FieldVote.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/AuthenticationManagerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/AuthenticationProviderManager.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolver.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolverInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Provider/AnonymousAuthenticationProvider.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Provider/AuthenticationProviderInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Provider/DaoAuthenticationProvider.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Provider/RememberMeAuthenticationProvider.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Provider/UserAuthenticationProvider.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/RememberMe/InMemoryTokenProvider.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/RememberMe/PersistentToken.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/RememberMe/PersistentTokenInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/RememberMe/TokenProviderInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Token/AnonymousToken.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Token/RememberMeToken.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Token/TokenInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/AuthenticationEvents.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authorization/AccessDecisionManager.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authorization/AccessDecisionManagerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authorization/Voter/AuthenticatedVoter.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authorization/Voter/RoleHierarchyVoter.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authorization/Voter/RoleVoter.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authorization/Voter/VoterInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Encoder/BasePasswordEncoder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Encoder/EncoderFactory.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Encoder/EncoderFactoryInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Encoder/MessageDigestPasswordEncoder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Encoder/PasswordEncoderInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Encoder/PlaintextPasswordEncoder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Event/AuthenticationEvent.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Event/AuthenticationFailureEvent.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Exception/AccessDeniedException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Exception/AccountExpiredException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Exception/AccountStatusException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Exception/AuthenticationCredentialsNotFoundException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Exception/AuthenticationException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Exception/AuthenticationServiceException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Exception/BadCredentialsException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Exception/CookieTheftException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Exception/CredentialsExpiredException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Exception/DisabledException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Exception/InsufficientAuthenticationException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Exception/InvalidCsrfTokenException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Exception/LockedException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Exception/LogoutException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Exception/NonceExpiredException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Exception/ProviderNotFoundException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Exception/SessionUnavailableException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Exception/TokenNotFoundException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Exception/UnsupportedUserException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Exception/UsernameNotFoundException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Role/Role.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Role/RoleHierarchy.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Role/RoleHierarchyInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Role/RoleInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Role/SwitchUserRole.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/SecurityContext.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/SecurityContextInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/User/AdvancedUserInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/User/ChainUserProvider.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/User/EquatableInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/User/InMemoryUserProvider.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/User/User.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/User/UserChecker.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/User/UserCheckerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/User/UserInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/User/UserProviderInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Util/ClassUtils.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Validator/Constraint/UserPassword.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Core/Validator/Constraint/UserPasswordValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/AccessMap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/AccessMapInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Authentication/AuthenticationFailureHandlerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Authentication/AuthenticationSuccessHandlerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Authorization/AccessDeniedHandlerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/EntryPoint/AuthenticationEntryPointInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/EntryPoint/BasicAuthenticationEntryPoint.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/EntryPoint/DigestAuthenticationEntryPoint.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/EntryPoint/FormAuthenticationEntryPoint.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/EntryPoint/RetryAuthenticationEntryPoint.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Event/InteractiveLoginEvent.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Event/SwitchUserEvent.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/AbstractAuthenticationListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/AbstractPreAuthenticatedListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/AccessListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/AnonymousAuthenticationListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/BasicAuthenticationListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/ChannelListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/ContextListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/DigestAuthenticationListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/ListenerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/LogoutListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/RememberMeListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/X509AuthenticationListener.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/FirewallMap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/FirewallMapInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/HttpUtils.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Logout/CookieClearingLogoutHandler.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Logout/LogoutHandlerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Logout/LogoutSuccessHandlerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Logout/SessionLogoutHandler.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/RememberMe/AbstractRememberMeServices.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/RememberMe/PersistentTokenBasedRememberMeServices.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/RememberMe/RememberMeServicesInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeServices.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/SecurityEvents.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Session/SessionAuthenticationStrategy.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Http/Session/SessionAuthenticationStrategyInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Acl/Dbal/AclProviderBenchmarkTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Acl/Dbal/AclProviderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Acl/Dbal/MutableAclProviderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Acl/Domain/AclTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Acl/Domain/AuditLoggerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Acl/Domain/DoctrineAclCacheTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Acl/Domain/EntryTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Acl/Domain/FieldEntryTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Acl/Domain/ObjectIdentityRetrievalStrategyTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Acl/Domain/ObjectIdentityTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Acl/Domain/PermissionGrantingStrategyTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Acl/Domain/RoleSecurityIdentityTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Acl/Domain/SecurityIdentityRetrievalStrategyTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Acl/Domain/UserSecurityIdentityTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Acl/Permission/BasicPermissionMapTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Acl/Permission/MaskBuilderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Acl/Voter/AclVoterTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Authentication/AuthenticationProviderManagerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Authentication/AuthenticationTrustResolverTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Authentication/Provider/AnonymousAuthenticationProviderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Authentication/Provider/DaoAuthenticationProviderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Authentication/Provider/PreAuthenticatedAuthenticationProviderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Authentication/Provider/RememberMeAuthenticationProviderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Authentication/Provider/UserAuthenticationProviderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Authentication/RememberMe/InMemoryTokenProviderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Authentication/RememberMe/PersistentTokenTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Authentication/Token/AbstractTokenTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Authentication/Token/AnonymousTokenTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Authentication/Token/PreAuthenticatedTokenTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Authentication/Token/RememerMeTokenTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Authentication/Token/UsernamePasswordTokenTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Authorization/AccessDecisionManagerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Authorization/Voter/AuthenticatedVoterTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Authorization/Voter/RoleHierarchyVoterTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Authorization/Voter/RoleVoterTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Encoder/BasePasswordEncoderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Encoder/EncoderFactoryTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Encoder/MessageDigestPasswordEncoderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Encoder/PlaintextPasswordEncoderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Role/RoleHierarchyTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Role/RoleTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Role/SwitchUserRoleTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/SecurityContextTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/User/AccountCheckerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/User/ChainUserProviderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/User/InMemoryProviderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/User/UserTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Core/Util/ClassUtilsTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Http/EntryPoint/BasicAuthenticationEntryPointTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Http/EntryPoint/DigestAuthenticationEntryPointTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Http/EntryPoint/FormAuthenticationEntryPointTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Http/EntryPoint/RetryAuthenticationEntryPointTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Http/Firewall/AccessListenerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Http/Firewall/AnonymousAuthenticationListenerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Http/Firewall/BasicAuthenticationListenerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Http/Firewall/ChannelListenerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Http/Firewall/ContextListenerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Http/Firewall/LogoutListenerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Http/Firewall/RememberMeListenerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Http/FirewallMapTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Http/FirewallTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Http/HttpUtilsTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Http/Logout/CookieClearingLogoutHandlerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Http/Logout/SessionLogoutHandlerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Http/RememberMe/AbstractRememberMeServicesTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Http/RememberMe/PersistentTokenBasedRememberMeServicesTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/Http/RememberMe/TokenBasedRememberMeServicesTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Security/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Encoder/DecoderInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Encoder/EncoderInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Encoder/JsonDecode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Encoder/JsonEncode.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Encoder/JsonEncoder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Encoder/NormalizationAwareInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Encoder/SerializerAwareEncoder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Exception/Exception.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Exception/InvalidArgumentException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Exception/LogicException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Exception/RuntimeException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Exception/UnexpectedValueException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Exception/UnsupportedException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Normalizer/CustomNormalizer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Normalizer/DenormalizableInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Normalizer/NormalizableInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Normalizer/SerializerAwareNormalizer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Serializer.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/SerializerAwareInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/SerializerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Tests/Encoder/XmlEncoderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Tests/Fixtures/DenormalizableDummy.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Tests/Fixtures/Dummy.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Tests/Fixtures/NormalizableTraversableDummy.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Tests/Fixtures/ScalarDummy.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Tests/Fixtures/TraversableDummy.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Tests/Normalizer/CustomNormalizerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Tests/SerializerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Serializer/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Asset/Package.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Asset/PackageInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Asset/PathPackage.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Asset/UrlPackage.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/DebuggerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/DelegatingEngine.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/EngineInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Helper/AssetsHelper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Helper/CoreAssetsHelper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Helper/Helper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Helper/HelperInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Helper/SlotsHelper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Loader/CacheLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Loader/ChainLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Loader/FilesystemLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Loader/Loader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Loader/LoaderInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/PhpEngine.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Storage/FileStorage.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Storage/Storage.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Storage/StringStorage.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/StreamingEngineInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/TemplateNameParser.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/TemplateNameParserInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/TemplateReference.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/TemplateReferenceInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Tests/Fixtures/ProjectTemplateDebugger.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Tests/Fixtures/SimpleHelper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Tests/Fixtures/templates/foo.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Tests/Helper/AssetsHelperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Tests/Helper/CoreAssetsHelperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Tests/Helper/HelperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Tests/Helper/SlotsHelperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Tests/Loader/CacheLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Tests/Loader/ChainLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Tests/Loader/FilesystemLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Tests/Loader/LoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Tests/PhpEngineTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Tests/Storage/FileStorageTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Tests/Storage/StorageTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Tests/Storage/StringStorageTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Tests/TemplateNameParserTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Templating/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Dumper/CsvFileDumper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Dumper/DumperInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Dumper/FileDumper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Dumper/IcuResFileDumper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Dumper/IniFileDumper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Dumper/MoFileDumper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Dumper/PhpFileDumper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Dumper/PoFileDumper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Dumper/QtFileDumper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Dumper/XliffFileDumper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Dumper/YamlFileDumper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Extractor/ChainExtractor.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Extractor/ExtractorInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/IdentityTranslator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Interval.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Loader/ArrayLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Loader/CsvFileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Loader/IcuDatFileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Loader/IcuResFileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Loader/IniFileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Loader/LoaderInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Loader/MoFileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Loader/PhpFileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Loader/PoFileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Loader/QtTranslationsLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Loader/XliffFileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Loader/YamlFileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Loader/schema/dic/xliff-core/xliff-core-1.2-strict.xsd create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Loader/schema/dic/xliff-core/xml.xsd create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/MessageCatalogue.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/MessageCatalogueInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/MessageSelector.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/PluralizationRules.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/Dumper/CsvFileDumperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/Dumper/IcuResFileDumperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/Dumper/IniFileDumperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/Dumper/MoFileDumperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/Dumper/PhpFileDumperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/Dumper/PoFileDumperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/Dumper/QtFileDumperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/Dumper/XliffFileDumperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/Dumper/YamlFileDumperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/IdentityTranslatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/IntervalTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/Loader/CsvFileLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/Loader/IcuDatFileLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/Loader/IcuResFileLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/Loader/IniFileLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/Loader/LocalizedTestCase.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/Loader/MoFileLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/Loader/PhpFileLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/Loader/PoFileLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/Loader/QtTranslationsLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/Loader/YamlFileLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/MessageCatalogueTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/MessageSelectorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/TranslatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/empty-translation.po create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/empty.csv create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/empty.ini create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/empty.mo create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/empty.po create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/empty.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/non-valid.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/non-valid.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/plurals.mo create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/plurals.po create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/en.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/en.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/fr.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/fr.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/packagelist.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/resources.dat create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/resourcebundle/res/en.res create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/resourcebundle/res/en.txt create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/resources-clean.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/resources.csv create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/resources.ini create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/resources.mo create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/resources.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/resources.po create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/resources.ts create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/resources.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/resources.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Tests/fixtures/valid.csv create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Translator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/TranslatorInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/Writer/TranslationWriter.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Translation/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraint.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/ConstraintValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/ConstraintValidatorFactory.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/ConstraintValidatorFactoryInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/ConstraintValidatorInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/ConstraintViolation.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/ConstraintViolationList.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/All.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/AllValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Blank.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/BlankValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Callback.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/CallbackValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Choice.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/ChoiceValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Collection.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Collection/Optional.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Collection/Required.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/CollectionValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Country.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/CountryValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Date.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/DateTime.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/DateTimeValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/DateValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Email.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/EmailValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/False.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/FalseValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/File.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/FileValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/GroupSequence.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/GroupSequenceProvider.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Image.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/ImageValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Ip.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/IpValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Language.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/LanguageValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Locale.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/LocaleValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Max.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/MaxLength.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/MaxLengthValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/MaxValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Min.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/MinLength.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/MinLengthValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/MinValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/NotBlank.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/NotBlankValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/NotNull.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/NotNullValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Null.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/NullValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Range.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/RangeValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Regex.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/RegexValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Size.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/SizeValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Time.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/TimeValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/True.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/TrueValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Type.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/TypeValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Url.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/UrlValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/Valid.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Exception/ConstraintDefinitionException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Exception/GroupDefinitionException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Exception/InvalidOptionsException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Exception/MappingException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Exception/MissingOptionsException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Exception/UnexpectedTypeException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Exception/ValidatorException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/ExecutionContext.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/GlobalExecutionContext.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/GraphWalker.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/GroupSequenceProviderInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/BlackholeMetadataFactory.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/Cache/ApcCache.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/Cache/CacheInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/ClassMetadata.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/ClassMetadataFactory.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/ClassMetadataFactoryInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/ElementMetadata.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/GetterMetadata.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/Loader/FileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/Loader/FilesLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/Loader/LoaderChain.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/Loader/LoaderInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/Loader/StaticMethodLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/Loader/XmlFilesLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/Loader/YamlFilesLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/Loader/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/MemberMetadata.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Mapping/PropertyMetadata.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/ObjectInitializerInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.ca.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.cs.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.da.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.de.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.es.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.et.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.eu.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.fa.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.fi.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.fr.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.he.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.hr.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.hu.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.hy.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.id.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.it.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.ja.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.lb.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.lt.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.mn.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.nb.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.nl.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.pl.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.pt.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.pt_BR.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.ro.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.ru.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.sk.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.sl.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.sr_Cyrl.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.sr_Latn.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.sv.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.ua.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations/validators.zh_CN.xlf create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/ConstraintTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/ConstraintValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/ConstraintViolationListTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/ConstraintViolationTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/AllValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/BlankValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/CallbackValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/ChoiceValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorArrayObjectTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorArrayTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorCustomArrayObjectTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/CountryValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/DateTimeValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/DateValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/EmailValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/FalseValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/FileValidatorObjectTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/FileValidatorPathTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/Fixtures/test.gif create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/ImageValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/IpValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/LanguageValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/LocaleValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/LocalizedTestCase.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/MaxLengthValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/MaxValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/MinLengthValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/MinValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/NotBlankValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/NotNullValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/NullValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/RangeValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/RegexValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/SizeTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/SizeValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/TimeValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/TrueValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/TypeValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/ExecutionContextTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Fixtures/ClassConstraint.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Fixtures/ConstraintA.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Fixtures/ConstraintAValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Fixtures/ConstraintB.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Fixtures/ConstraintC.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Fixtures/Entity.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Fixtures/EntityInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Fixtures/EntityParent.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Fixtures/FailingConstraint.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Fixtures/FailingConstraintValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Fixtures/FakeClassMetadataFactory.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Fixtures/FilesLoader.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Fixtures/GroupSequenceProviderEntity.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Fixtures/InvalidConstraint.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Fixtures/InvalidConstraintValidator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Fixtures/PropertyConstraint.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Fixtures/Reference.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/GlobalExecutionContextTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/GraphWalkerTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Mapping/Cache/ApcCacheTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Mapping/ClassMetadataFactoryTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Mapping/ElementMetadataTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Mapping/Loader/FilesLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Mapping/Loader/LoaderChainTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Mapping/Loader/StaticMethodLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.xml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Mapping/Loader/empty-mapping.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Mapping/Loader/nonvalid-mapping.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Mapping/MemberMetadataTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/ValidatorContextTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/ValidatorFactoryTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/ValidatorTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/Validator.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/ValidatorContext.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/ValidatorContextInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/ValidatorFactory.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/ValidatorInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Validator/phpunit.xml.dist create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/CHANGELOG.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Dumper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Escaper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Exception/DumpException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Exception/ParseException.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Inline.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/LICENSE create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Parser.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/README.md create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/DumperTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/Fixtures/YtsAnchorAlias.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/Fixtures/YtsBasicTests.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/Fixtures/YtsBlockMapping.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/Fixtures/YtsDocumentSeparator.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/Fixtures/YtsErrorTests.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/Fixtures/YtsFlowCollections.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/Fixtures/YtsFoldedScalars.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/Fixtures/YtsNullsAndEmpties.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/Fixtures/YtsSpecificationExamples.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/Fixtures/YtsTypeTransfers.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/Fixtures/escapedCharacters.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/Fixtures/index.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/Fixtures/sfComments.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/Fixtures/sfCompact.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/Fixtures/sfMergeKey.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/Fixtures/sfObjects.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/Fixtures/sfQuotes.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/Fixtures/sfTests.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/Fixtures/unindentedCollections.yml create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/InlineTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/ParserTest.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Tests/bootstrap.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Unescaper.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/Yaml.php create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/composer.json create mode 100644 vendor/symfony/symfony/src/Symfony/Component/Yaml/phpunit.xml.dist create mode 100644 vendor/twig/extensions/LICENSE create mode 100644 vendor/twig/extensions/composer.json create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/Autoloader.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/Extension/Debug.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/Extension/I18n.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/Extension/Intl.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/Extension/Text.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/Grammar.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/Grammar/Arguments.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/Grammar/Array.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/Grammar/Body.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/Grammar/Boolean.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/Grammar/Constant.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/Grammar/Expression.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/Grammar/Hash.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/Grammar/Number.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/Grammar/Optional.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/Grammar/Switch.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/Grammar/Tag.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/GrammarInterface.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/Node/Debug.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/Node/Trans.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/SimpleTokenParser.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/TokenParser/Debug.php create mode 100644 vendor/twig/extensions/lib/Twig/Extensions/TokenParser/Trans.php create mode 100644 vendor/twig/twig/.travis.yml create mode 100644 vendor/twig/twig/LICENSE create mode 100644 vendor/twig/twig/composer.json create mode 100644 vendor/twig/twig/ext/twig/LICENSE create mode 100644 vendor/twig/twig/ext/twig/config.m4 create mode 100644 vendor/twig/twig/ext/twig/config.w32 create mode 100644 vendor/twig/twig/ext/twig/php_twig.h create mode 100644 vendor/twig/twig/ext/twig/twig.c create mode 100644 vendor/twig/twig/lib/Twig/Autoloader.php create mode 100644 vendor/twig/twig/lib/Twig/Compiler.php create mode 100644 vendor/twig/twig/lib/Twig/CompilerInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Environment.php create mode 100644 vendor/twig/twig/lib/Twig/Error.php create mode 100644 vendor/twig/twig/lib/Twig/Error/Loader.php create mode 100644 vendor/twig/twig/lib/Twig/Error/Runtime.php create mode 100644 vendor/twig/twig/lib/Twig/Error/Syntax.php create mode 100644 vendor/twig/twig/lib/Twig/ExpressionParser.php create mode 100644 vendor/twig/twig/lib/Twig/Extension.php create mode 100644 vendor/twig/twig/lib/Twig/Extension/Core.php create mode 100644 vendor/twig/twig/lib/Twig/Extension/Debug.php create mode 100644 vendor/twig/twig/lib/Twig/Extension/Escaper.php create mode 100644 vendor/twig/twig/lib/Twig/Extension/Optimizer.php create mode 100644 vendor/twig/twig/lib/Twig/Extension/Sandbox.php create mode 100644 vendor/twig/twig/lib/Twig/ExtensionInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Filter.php create mode 100644 vendor/twig/twig/lib/Twig/Filter/Function.php create mode 100644 vendor/twig/twig/lib/Twig/Filter/Method.php create mode 100644 vendor/twig/twig/lib/Twig/Filter/Node.php create mode 100644 vendor/twig/twig/lib/Twig/FilterInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Function.php create mode 100644 vendor/twig/twig/lib/Twig/Function/Function.php create mode 100644 vendor/twig/twig/lib/Twig/Function/Method.php create mode 100644 vendor/twig/twig/lib/Twig/Function/Node.php create mode 100644 vendor/twig/twig/lib/Twig/FunctionInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Lexer.php create mode 100644 vendor/twig/twig/lib/Twig/LexerInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Loader/Array.php create mode 100644 vendor/twig/twig/lib/Twig/Loader/Chain.php create mode 100644 vendor/twig/twig/lib/Twig/Loader/Filesystem.php create mode 100644 vendor/twig/twig/lib/Twig/Loader/String.php create mode 100644 vendor/twig/twig/lib/Twig/LoaderInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Markup.php create mode 100644 vendor/twig/twig/lib/Twig/Node.php create mode 100644 vendor/twig/twig/lib/Twig/Node/AutoEscape.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Block.php create mode 100644 vendor/twig/twig/lib/Twig/Node/BlockReference.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Body.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Do.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Embed.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Array.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Add.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/And.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Div.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Less.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Or.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Conditional.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Constant.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Filter.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Function.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/MethodCall.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Name.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Parent.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/TempName.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Test.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Test/Constant.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Test/Even.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Test/Null.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Test/Odd.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Unary.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Unary/Not.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Flush.php create mode 100644 vendor/twig/twig/lib/Twig/Node/For.php create mode 100644 vendor/twig/twig/lib/Twig/Node/ForLoop.php create mode 100644 vendor/twig/twig/lib/Twig/Node/If.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Import.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Include.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Macro.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Module.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Print.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Sandbox.php create mode 100644 vendor/twig/twig/lib/Twig/Node/SandboxedModule.php create mode 100644 vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Set.php create mode 100644 vendor/twig/twig/lib/Twig/Node/SetTemp.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Spaceless.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Text.php create mode 100644 vendor/twig/twig/lib/Twig/NodeInterface.php create mode 100644 vendor/twig/twig/lib/Twig/NodeOutputInterface.php create mode 100644 vendor/twig/twig/lib/Twig/NodeTraverser.php create mode 100644 vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php create mode 100644 vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php create mode 100644 vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php create mode 100644 vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php create mode 100644 vendor/twig/twig/lib/Twig/NodeVisitorInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Parser.php create mode 100644 vendor/twig/twig/lib/Twig/ParserInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Sandbox/SecurityError.php create mode 100644 vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php create mode 100644 vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Template.php create mode 100644 vendor/twig/twig/lib/Twig/TemplateInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Test/Function.php create mode 100644 vendor/twig/twig/lib/Twig/Test/Method.php create mode 100644 vendor/twig/twig/lib/Twig/Test/Node.php create mode 100644 vendor/twig/twig/lib/Twig/TestInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Token.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Block.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Do.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Embed.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Extends.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Filter.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Flush.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/For.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/From.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/If.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Import.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Include.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Macro.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Set.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Use.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParserBroker.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParserBrokerInterface.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParserInterface.php create mode 100644 vendor/twig/twig/lib/Twig/TokenStream.php create mode 100644 web/.htaccess create mode 100644 web/app.php create mode 100644 web/app_dev.php create mode 100644 web/apple-touch-icon.png create mode 100644 web/bundles/acmedemo/css/demo.css create mode 100644 web/bundles/acmedemo/images/blue-arrow.png create mode 100644 web/bundles/acmedemo/images/field-background.gif create mode 100644 web/bundles/acmedemo/images/logo.gif create mode 100644 web/bundles/acmedemo/images/search.png create mode 100644 web/bundles/acmedemo/images/welcome-configure.gif create mode 100644 web/bundles/acmedemo/images/welcome-demo.gif create mode 100644 web/bundles/acmedemo/images/welcome-quick-tour.gif create mode 100644 web/bundles/framework/css/exception.css create mode 100644 web/bundles/framework/css/exception_layout.css create mode 100644 web/bundles/framework/images/blue_picto_less.gif create mode 100644 web/bundles/framework/images/blue_picto_more.gif create mode 100644 web/bundles/framework/images/border_l.png create mode 100644 web/bundles/framework/images/border_r.png create mode 100644 web/bundles/framework/images/btn_bg.png create mode 100644 web/bundles/framework/images/close_quote.gif create mode 100644 web/bundles/framework/images/exception_detected.gif create mode 100644 web/bundles/framework/images/exception_detected.png create mode 100644 web/bundles/framework/images/grey_magnifier.png create mode 100644 web/bundles/framework/images/icon_log.png create mode 100644 web/bundles/framework/images/input_bg.gif create mode 100644 web/bundles/framework/images/logo_symfony.gif create mode 100644 web/bundles/framework/images/logo_symfony.png create mode 100644 web/bundles/framework/images/open_quote.gif create mode 100644 web/bundles/sensiodistribution/webconfigurator/css/configure.css create mode 100644 web/bundles/sensiodistribution/webconfigurator/css/install.css create mode 100644 web/bundles/sensiodistribution/webconfigurator/images/background-textfield.gif create mode 100644 web/bundles/sensiodistribution/webconfigurator/images/blue-arrow.png create mode 100644 web/bundles/sensiodistribution/webconfigurator/images/favicon.ico create mode 100644 web/bundles/sensiodistribution/webconfigurator/images/logo-big.gif create mode 100644 web/bundles/sensiodistribution/webconfigurator/images/logo-small.gif create mode 100644 web/bundles/sensiodistribution/webconfigurator/images/notification.gif create mode 100644 web/bundles/webprofiler/css/profiler.css create mode 100644 web/bundles/webprofiler/favicon.ico create mode 100644 web/bundles/webprofiler/images/close.png create mode 100644 web/bundles/webprofiler/images/config.png create mode 100644 web/bundles/webprofiler/images/db.png create mode 100644 web/bundles/webprofiler/images/events.png create mode 100644 web/bundles/webprofiler/images/exception.png create mode 100644 web/bundles/webprofiler/images/import.png create mode 100644 web/bundles/webprofiler/images/logger.png create mode 100644 web/bundles/webprofiler/images/mail.png create mode 100644 web/bundles/webprofiler/images/memory.png create mode 100644 web/bundles/webprofiler/images/profiler/bg_submenu.gif create mode 100644 web/bundles/webprofiler/images/profiler/bg_submenu.png create mode 100644 web/bundles/webprofiler/images/profiler/border_l.png create mode 100644 web/bundles/webprofiler/images/profiler/border_r.png create mode 100644 web/bundles/webprofiler/images/profiler/btn_bg.png create mode 100644 web/bundles/webprofiler/images/profiler/config.png create mode 100644 web/bundles/webprofiler/images/profiler/db.png create mode 100644 web/bundles/webprofiler/images/profiler/events.png create mode 100644 web/bundles/webprofiler/images/profiler/exception.png create mode 100644 web/bundles/webprofiler/images/profiler/grey_magnifier.png create mode 100644 web/bundles/webprofiler/images/profiler/input_bg.gif create mode 100644 web/bundles/webprofiler/images/profiler/logger.png create mode 100644 web/bundles/webprofiler/images/profiler/logo_symfony_profiler.gif create mode 100644 web/bundles/webprofiler/images/profiler/logo_symfony_profiler.png create mode 100644 web/bundles/webprofiler/images/profiler/mail.png create mode 100644 web/bundles/webprofiler/images/profiler/request.png create mode 100644 web/bundles/webprofiler/images/profiler/routing.png create mode 100644 web/bundles/webprofiler/images/profiler/security.png create mode 100644 web/bundles/webprofiler/images/profiler/spinner.gif create mode 100644 web/bundles/webprofiler/images/profiler/time.png create mode 100644 web/bundles/webprofiler/images/request.png create mode 100644 web/bundles/webprofiler/images/routing.png create mode 100644 web/bundles/webprofiler/images/search.png create mode 100644 web/bundles/webprofiler/images/security.png create mode 100644 web/bundles/webprofiler/images/spacer.gif create mode 100644 web/bundles/webprofiler/images/symfony.png create mode 100644 web/bundles/webprofiler/images/time.png create mode 100644 web/config.php create mode 100644 web/favicon.ico create mode 100644 web/robots.txt diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..cdffe7a --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 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/README.md b/README.md new file mode 100644 index 0000000..52ee084 --- /dev/null +++ b/README.md @@ -0,0 +1,174 @@ +Symfony Standard Edition +======================== + +Welcome to the Symfony Standard Edition - a fully-functional Symfony2 +application that you can use as the skeleton for your new applications. + +This document contains information on how to download, install, and start +using Symfony. For a more detailed explanation, see the [Installation][1] +chapter of the Symfony Documentation. + +1) Installing the Standard Edition +---------------------------------- + +When it comes to installing the Symfony Standard Edition, you have the +following options. + +### Use Composer (*recommended*) + +As Symfony uses [Composer][2] to manage its dependencies, the recommended way +to create a new project is to use it. + +If you don't have Composer yet, download it following the instructions on +http://getcomposer.org/ or just run the following command: + + curl -s http://getcomposer.org/installer | php + +Then, use the `create-project` command to generate a new Symfony application: + + composer.phar create-project symfony/framework-standard-edition path/to/install + +Composer will install Symfony and all its dependencies under the +`path/to/install` directory. + +### Download an Archive File + +To quickly test Symfony, you can also download an [archive][3] of the Standard +Edition and unpack it somewhere under your web server root directory. + +If you downloaded an archive "without vendors", you also need to install all +the necessary dependencies. Download composer (see above) and run the +following command: + + php composer.phar install + +2) Checking your System Configuration +------------------------------------- + +Before starting coding, make sure that your local system is properly +configured for Symfony. + +Execute the `check.php` script from the command line: + + php app/check.php + +Access the `config.php` script from a browser: + + http://localhost/path/to/symfony/app/web/config.php + +If you get any warnings or recommendations, fix them before moving on. + +3) Browsing the Demo Application +-------------------------------- + +Congratulations! You're now ready to use Symfony. + +From the `config.php` page, click the "Bypass configuration and go to the +Welcome page" link to load up your first Symfony page. + +You can also use a web-based configurator by clicking on the "Configure your +Symfony Application online" link of the `config.php` page. + +To see a real-live Symfony page in action, access the following page: + + web/app_dev.php/demo/hello/Fabien + +3) Getting started with Symfony +------------------------------- + +This distribution is meant to be the starting point for your Symfony +applications, but it also contains some sample code that you can learn from +and play with. + +A great way to start learning Symfony is via the [Quick Tour][4], which will +take you through all the basic features of Symfony2. + +Once you're feeling good, you can move onto reading the official +[Symfony2 book][5]. + +A default bundle, `AcmeDemoBundle`, shows you Symfony2 in action. After +playing with it, you can remove it by following these steps: + + * delete the `src/Acme` directory; + + * remove the routing entries referencing AcmeBundle in + `app/config/routing_dev.yml`; + + * remove the AcmeBundle from the registered bundles in `app/AppKernel.php`; + + * remove the `web/bundles/acmedemo` directory; + + * remove the inclusion of the security configuration in + `app/config/config.yml` (remove the `- { resource: security.yml }` line) + or tweak the security configuration to fit your needs. + +What's inside? +--------------- + +The Symfony Standard Edition is configured with the following defaults: + + * Twig is the only configured template engine; + + * Doctrine ORM/DBAL is configured; + + * Swiftmailer is configured; + + * Annotations for everything are enabled. + +It comes pre-configured with the following bundles: + + * **FrameworkBundle** - The core Symfony framework bundle + + * [**SensioFrameworkExtraBundle**][6] - Adds several enhancements, including + template and routing annotation capability + + * [**DoctrineBundle**][7] - Adds support for the Doctrine ORM + + * [**TwigBundle**][8] - Adds support for the Twig templating engine + + * [**SecurityBundle**][9] - Adds security by integrating Symfony's security + component + + * [**SwiftmailerBundle**][10] - Adds support for Swiftmailer, a library for + sending emails + + * [**MonologBundle**][11] - Adds support for Monolog, a logging library + + * [**AsseticBundle**][12] - Adds support for Assetic, an asset processing + library + + * [**JMSSecurityExtraBundle**][13] - Allows security to be added via + annotations + + * [**JMSDiExtraBundle**][14] - Adds more powerful dependency injection + features + + * **WebProfilerBundle** (in dev/test env) - Adds profiling functionality and + the web debug toolbar + + * **SensioDistributionBundle** (in dev/test env) - Adds functionality for + configuring and working with Symfony distributions + + * [**SensioGeneratorBundle**][15] (in dev/test env) - Adds code generation + capabilities + + * **AcmeDemoBundle** (in dev/test env) - A demo bundle with some example + code + +Enjoy! + +[1]: http://symfony.com/doc/2.1/book/installation.html +[2]: http://getcomposer.org/ +[3]: http://symfony.com/download +[4]: http://symfony.com/doc/2.1/quick_tour/the_big_picture.html +[5]: http://symfony.com/doc/2.1/ +[6]: http://symfony.com/doc/2.1/bundles/SensioFrameworkExtraBundle/index.html +[7]: http://symfony.com/doc/2.1/book/doctrine.html +[8]: http://symfony.com/doc/2.1/book/templating.html +[9]: http://symfony.com/doc/2.1/book/security.html +[10]: http://symfony.com/doc/2.1/cookbook/email.html +[11]: http://symfony.com/doc/2.1/cookbook/logging/monolog.html +[12]: http://symfony.com/doc/2.1/cookbook/assetic/asset_management.html +[13]: http://jmsyst.com/bundles/JMSSecurityExtraBundle/1.1 +[14]: http://jmsyst.com/bundles/JMSDiExtraBundle/1.0 +[15]: http://symfony.com/doc/2.1/bundles/SensioGeneratorBundle/index.html diff --git a/app/.htaccess b/app/.htaccess new file mode 100644 index 0000000..3418e55 --- /dev/null +++ b/app/.htaccess @@ -0,0 +1 @@ +deny from all \ No newline at end of file diff --git a/app/AppCache.php b/app/AppCache.php new file mode 100644 index 0000000..ddb51db --- /dev/null +++ b/app/AppCache.php @@ -0,0 +1,9 @@ +getEnvironment(), array('dev', 'test'))) { + $bundles[] = new Acme\DemoBundle\AcmeDemoBundle(); + $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle(); + $bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle(); + $bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle(); + } + + return $bundles; + } + + public function registerContainerConfiguration(LoaderInterface $loader) + { + $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml'); + } +} diff --git a/app/Resources/views/base.html.twig b/app/Resources/views/base.html.twig new file mode 100644 index 0000000..bafd28d --- /dev/null +++ b/app/Resources/views/base.html.twig @@ -0,0 +1,13 @@ + + + + + {% block title %}Welcome!{% endblock %} + {% block stylesheets %}{% endblock %} + + + + {% block body %}{% endblock %} + {% block javascripts %}{% endblock %} + + diff --git a/app/SymfonyRequirements.php b/app/SymfonyRequirements.php new file mode 100644 index 0000000..0399b96 --- /dev/null +++ b/app/SymfonyRequirements.php @@ -0,0 +1,580 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Represents a single PHP requirement, e.g. an installed extension. + * It can be a mandatory requirement or an optional recommendation. + * There is a special subclass, named PhpIniRequirement, to check a php.ini configuration. + * + * @author Tobias Schultze + */ +class Requirement +{ + private $fulfilled; + private $testMessage; + private $helpText; + private $helpHtml; + private $optional; + + /** + * Constructor that initializes the requirement. + * + * @param Boolean $fulfilled Whether the requirement is fulfilled + * @param string $testMessage The message for testing the requirement + * @param string $helpHtml The help text formatted in HTML for resolving the problem + * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) + * @param Boolean $optional Whether this is only an optional recommendation not a mandatory requirement + */ + public function __construct($fulfilled, $testMessage, $helpHtml, $helpText = null, $optional = false) + { + $this->fulfilled = (Boolean) $fulfilled; + $this->testMessage = (string) $testMessage; + $this->helpHtml = (string) $helpHtml; + $this->helpText = null === $helpText ? strip_tags($this->helpHtml) : (string) $helpText; + $this->optional = (Boolean) $optional; + } + + /** + * Returns whether the requirement is fulfilled. + * + * @return Boolean true if fulfilled, otherwise false + */ + public function isFulfilled() + { + return $this->fulfilled; + } + + /** + * Returns the message for testing the requirement. + * + * @return string The test message + */ + public function getTestMessage() + { + return $this->testMessage; + } + + /** + * Returns the help text for resolving the problem + * + * @return string The help text + */ + public function getHelpText() + { + return $this->helpText; + } + + /** + * Returns the help text formatted in HTML. + * + * @return string The HTML help + */ + public function getHelpHtml() + { + return $this->helpHtml; + } + + /** + * Returns whether this is only an optional recommendation and not a mandatory requirement. + * + * @return Boolean true if optional, false if mandatory + */ + public function isOptional() + { + return $this->optional; + } +} + +/** + * Represents a PHP requirement in form of a php.ini configuration. + * + * @author Tobias Schultze + */ +class PhpIniRequirement extends Requirement +{ + /** + * Constructor that initializes the requirement. + * + * @param string $cfgName The configuration name used for ini_get() + * @param Boolean|callback $evaluation Either a Boolean indicating whether the configuration should evaluate to true or false, + or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement + * @param Boolean $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false. + This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin. + Example: You require a config to be true but PHP later removes this config and defaults it to true internally. + * @param string $testMessage The message for testing the requirement (when null and $evaluation is a Boolean a default message is derived) + * @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a Boolean a default help is derived) + * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) + * @param Boolean $optional Whether this is only an optional recommendation not a mandatory requirement + */ + public function __construct($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null, $optional = false) + { + $cfgValue = ini_get($cfgName); + + if (is_callable($evaluation)) { + if (null === $testMessage || null === $helpHtml) { + throw new InvalidArgumentException('You must provide the parameters testMessage and helpHtml for a callback evaluation.'); + } + + $fulfilled = call_user_func($evaluation, $cfgValue); + } else { + if (null === $testMessage) { + $testMessage = sprintf('%s %s be %s in php.ini', + $cfgName, + $optional ? 'should' : 'must', + $evaluation ? 'enabled' : 'disabled' + ); + } + + if (null === $helpHtml) { + $helpHtml = sprintf('Set %s to %s in php.ini*.', + $cfgName, + $evaluation ? 'on' : 'off' + ); + } + + $fulfilled = $evaluation == $cfgValue; + } + + parent::__construct($fulfilled || ($approveCfgAbsence && false === $cfgValue), $testMessage, $helpHtml, $helpText, $optional); + } +} + +/** + * A RequirementCollection represents a set of Requirement instances. + * + * Users of PHP 5.2 should be able to run the requirements checks. + * This is why the class must be compatible with PHP 5.2 + * (e.g. not using namespaces and closures). + * + * @author Tobias Schultze + */ +class RequirementCollection implements IteratorAggregate +{ + private $requirements = array(); + + /** + * Gets the current RequirementCollection as an Iterator. + * + * @return Traversable A Traversable interface + */ + public function getIterator() + { + return new ArrayIterator($this->requirements); + } + + /** + * Adds a Requirement. + * + * @param Requirement $requirement A Requirement instance + */ + public function add(Requirement $requirement) + { + $this->requirements[] = $requirement; + } + + /** + * Adds a mandatory requirement. + * + * @param Boolean $fulfilled Whether the requirement is fulfilled + * @param string $testMessage The message for testing the requirement + * @param string $helpHtml The help text formatted in HTML for resolving the problem + * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) + */ + public function addRequirement($fulfilled, $testMessage, $helpHtml, $helpText = null) + { + $this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, false)); + } + + /** + * Adds an optional recommendation. + * + * @param Boolean $fulfilled Whether the recommendation is fulfilled + * @param string $testMessage The message for testing the recommendation + * @param string $helpHtml The help text formatted in HTML for resolving the problem + * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) + */ + public function addRecommendation($fulfilled, $testMessage, $helpHtml, $helpText = null) + { + $this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, true)); + } + + /** + * Adds a mandatory requirement in form of a php.ini configuration. + * + * @param string $cfgName The configuration name used for ini_get() + * @param Boolean|callback $evaluation Either a Boolean indicating whether the configuration should evaluate to true or false, + or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement + * @param Boolean $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false. + This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin. + Example: You require a config to be true but PHP later removes this config and defaults it to true internally. + * @param string $testMessage The message for testing the requirement (when null and $evaluation is a Boolean a default message is derived) + * @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a Boolean a default help is derived) + * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) + */ + public function addPhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null) + { + $this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, false)); + } + + /** + * Adds an optional recommendation in form of a php.ini configuration. + * + * @param string $cfgName The configuration name used for ini_get() + * @param Boolean|callback $evaluation Either a Boolean indicating whether the configuration should evaluate to true or false, + or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement + * @param Boolean $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false. + This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin. + Example: You require a config to be true but PHP later removes this config and defaults it to true internally. + * @param string $testMessage The message for testing the requirement (when null and $evaluation is a Boolean a default message is derived) + * @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a Boolean a default help is derived) + * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) + */ + public function addPhpIniRecommendation($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null) + { + $this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, true)); + } + + /** + * Adds a requirement collection to the current set of requirements. + * + * @param RequirementCollection $collection A RequirementCollection instance + */ + public function addCollection(RequirementCollection $collection) + { + $this->requirements = array_merge($this->requirements, $collection->all()); + } + + /** + * Returns both requirements and recommendations. + * + * @return array Array of Requirement instances + */ + public function all() + { + return $this->requirements; + } + + /** + * Returns all mandatory requirements. + * + * @return array Array of Requirement instances + */ + public function getRequirements() + { + $array = array(); + foreach ($this->requirements as $req) { + if (!$req->isOptional()) { + $array[] = $req; + } + } + + return $array; + } + + /** + * Returns the mandatory requirements that were not met. + * + * @return array Array of Requirement instances + */ + public function getFailedRequirements() + { + $array = array(); + foreach ($this->requirements as $req) { + if (!$req->isFulfilled() && !$req->isOptional()) { + $array[] = $req; + } + } + + return $array; + } + + /** + * Returns all optional recommmendations. + * + * @return array Array of Requirement instances + */ + public function getRecommendations() + { + $array = array(); + foreach ($this->requirements as $req) { + if ($req->isOptional()) { + $array[] = $req; + } + } + + return $array; + } + + /** + * Returns the recommendations that were not met. + * + * @return array Array of Requirement instances + */ + public function getFailedRecommendations() + { + $array = array(); + foreach ($this->requirements as $req) { + if (!$req->isFulfilled() && $req->isOptional()) { + $array[] = $req; + } + } + + return $array; + } + + /** + * Returns whether a php.ini configuration is not correct. + * + * @return Boolean php.ini configuration problem? + */ + public function hasPhpIniConfigIssue() + { + foreach ($this->requirements as $req) { + if (!$req->isFulfilled() && $req instanceof PhpIniRequirement) { + return true; + } + } + + return false; + } + + /** + * Returns the PHP configuration file (php.ini) path. + * + * @return string|false php.ini file path + */ + public function getPhpIniConfigPath() + { + return get_cfg_var('cfg_file_path'); + } +} + +/** + * This class specifies all requirements and optional recommendations that + * are necessary to run the Symfony Standard Edition. + * + * @author Tobias Schultze + */ +class SymfonyRequirements extends RequirementCollection +{ + const REQUIRED_PHP_VERSION = '5.3.3'; + + /** + * Constructor that initializes the requirements. + */ + public function __construct() + { + /* mandatory requirements follow */ + + $installedPhpVersion = phpversion(); + + $this->addRequirement( + version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>='), + sprintf('PHP version must be at least %s (%s installed)', self::REQUIRED_PHP_VERSION, $installedPhpVersion), + sprintf('You are running PHP version "%s", but Symfony needs at least PHP "%s" to run. + Before using Symfony, upgrade your PHP installation, preferably to the latest version.', + $installedPhpVersion, self::REQUIRED_PHP_VERSION), + sprintf('Install PHP %s or newer (installed version is %s)', self::REQUIRED_PHP_VERSION, $installedPhpVersion) + ); + + $this->addRequirement( + is_dir(__DIR__.'/../vendor/symfony'), + 'Vendor libraries must be installed', + 'Vendor libraries are missing. Install composer following instructions from http://getcomposer.org/. ' . + 'Then run "php composer.phar install" to install them.' + ); + + $baseDir = basename(__DIR__); + $this->addRequirement( + is_writable(__DIR__.'/cache'), + "$baseDir/cache/ directory must be writable", + "Change the permissions of the \"$baseDir/cache/\" directory so that the web server can write into it." + ); + + $this->addRequirement( + is_writable(__DIR__.'/logs'), + "$baseDir/logs/ directory must be writable", + "Change the permissions of the \"$baseDir/logs/\" directory so that the web server can write into it." + ); + + $this->addPhpIniRequirement( + 'date.timezone', true, false, + 'date.timezone setting must be set', + 'Set the "date.timezone" setting in php.ini* (like Europe/Paris).' + ); + + if (version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>=')) { + $this->addRequirement( + (in_array(date_default_timezone_get(), \DateTimeZone::listIdentifiers())), + sprintf('Default timezone is deprecated (%s)', date_default_timezone_get()), + 'Fix your php.ini file (list of deprecated timezones http://us.php.net/manual/en/timezones.others.php).' + ); + } + + $this->addRequirement( + function_exists('json_encode'), + 'json_encode() must be available', + 'Install and enable the JSON extension.' + ); + + $this->addRequirement( + function_exists('session_start'), + 'session_start() must be available', + 'Install and enable the session extension.' + ); + + $this->addRequirement( + function_exists('ctype_alpha'), + 'ctype_alpha() must be available', + 'Install and enable the ctype extension.' + ); + + $this->addRequirement( + function_exists('token_get_all'), + 'token_get_all() must be available', + 'Install and enable the Tokenizer extension.' + ); + + $this->addRequirement( + function_exists('simplexml_import_dom'), + 'simplexml_import_dom() must be available', + 'Install and enable the SimpleXML extension.' + ); + + $this->addRequirement( + !(function_exists('apc_store') && ini_get('apc.enabled')) || version_compare(phpversion('apc'), '3.0.17', '>='), + 'APC version must be at least 3.0.17', + 'Upgrade your APC extension (3.0.17+)' + ); + + $this->addPhpIniRequirement('detect_unicode', false); + + $this->addPhpIniRequirement( + 'suhosin.executor.include.whitelist', + create_function('$cfgValue', 'return false !== stripos($cfgValue, "phar");'), + true, + 'suhosin.executor.include.whitelist must be configured correctly in php.ini', + 'Add "phar" to suhosin.executor.include.whitelist in php.ini*.' + ); + + $pcreVersion = defined('PCRE_VERSION') ? (float) PCRE_VERSION : null; + + $this->addRequirement( + null !== $pcreVersion && $pcreVersion > 8.0, + sprintf('PCRE extension must be available and at least 8.0 (%s installed)', $pcreVersion ? $pcreVersion : 'not'), + 'Upgrade your PCRE extension (8.0+)' + ); + + /* optional recommendations follow */ + + $this->addRecommendation( + version_compare($installedPhpVersion, '5.3.8', '>='), + sprintf('Annotations might not work properly due to the PHP bug #55156 before PHP 5.3.8 (%s installed)', $installedPhpVersion), + 'Install PHP 5.3.8 or newer if your project uses annotations' + ); + + $this->addRecommendation( + class_exists('DomDocument'), + 'PHP-XML module should be installed', + 'Install and enable the PHP-XML module.' + ); + + $this->addRecommendation( + function_exists('mb_strlen'), + 'mb_strlen() should be available', + 'Install and enable the mbstring extension.' + ); + + $this->addRecommendation( + function_exists('iconv'), + 'iconv() should be available', + 'Install and enable the iconv extension.' + ); + + $this->addRecommendation( + function_exists('utf8_decode'), + 'utf8_decode() should be available', + 'Install and enable the XML extension.' + ); + + if (!defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->addRecommendation( + function_exists('posix_isatty'), + 'posix_isatty() should be available', + 'Install and enable the php_posix extension (used to colorize the CLI output).' + ); + } + + $this->addRecommendation( + class_exists('Locale'), + 'intl extension should be available', + 'Install and enable the intl extension (used for validators).' + ); + + if (class_exists('Locale')) { + if (defined('INTL_ICU_VERSION')) { + $version = INTL_ICU_VERSION; + } else { + $reflector = new ReflectionExtension('intl'); + + ob_start(); + $reflector->info(); + $output = strip_tags(ob_get_clean()); + + preg_match('/^ICU version +(?:=> )?(.*)$/m', $output, $matches); + $version = $matches[1]; + } + + $this->addRecommendation( + version_compare($version, '4.0', '>='), + 'intl ICU version should be at least 4+', + 'Upgrade your intl extension with a newer ICU version (4+).' + ); + } + + $accelerator = + (function_exists('apc_store') && ini_get('apc.enabled')) + || + function_exists('eaccelerator_put') && ini_get('eaccelerator.enable') + || + function_exists('xcache_set') + ; + + $this->addRecommendation( + $accelerator, + 'a PHP accelerator should be installed', + 'Install and enable a PHP accelerator like APC (highly recommended).' + ); + + $this->addPhpIniRecommendation('short_open_tag', false); + + $this->addPhpIniRecommendation('magic_quotes_gpc', false, true); + + $this->addPhpIniRecommendation('register_globals', false, true); + + $this->addPhpIniRecommendation('session.auto_start', false); + + $this->addRecommendation( + class_exists('PDO'), + 'PDO should be installed', + 'Install PDO (mandatory for Doctrine).' + ); + + if (class_exists('PDO')) { + $drivers = PDO::getAvailableDrivers(); + $this->addRecommendation( + count($drivers), + sprintf('PDO should have some drivers installed (currently available: %s)', count($drivers) ? implode(', ', $drivers) : 'none'), + 'Install PDO drivers (mandatory for Doctrine).' + ); + } + } +} diff --git a/app/autoload.php b/app/autoload.php new file mode 100644 index 0000000..28425dc --- /dev/null +++ b/app/autoload.php @@ -0,0 +1,32 @@ +You must set up the project dependencies by running the following commands:

+
+    curl -s http://getcomposer.org/installer | php
+    php composer.phar install
+
+ +EOF; + + if (PHP_SAPI === 'cli') { + $message = strip_tags($message); + } + + die($message); +} + +// intl +if (!function_exists('intl_get_error_code')) { + require_once __DIR__.'/../vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/stubs/functions.php'; + + $loader->add('', __DIR__.'/../vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/stubs'); +} + +AnnotationRegistry::registerLoader(array($loader, 'loadClass')); + +return $loader; diff --git a/app/bootstrap.php.cache b/app/bootstrap.php.cache new file mode 100644 index 0000000..d15c95a --- /dev/null +++ b/app/bootstrap.php.cache @@ -0,0 +1,1455 @@ +parameterBag = null === $parameterBag ? new ParameterBag() : $parameterBag; + + $this->services = array(); + $this->scopes = array(); + $this->scopeChildren = array(); + $this->scopedServices = array(); + $this->scopeStacks = array(); + + $this->set('service_container', $this); + } + + + public function compile() + { + $this->parameterBag->resolve(); + + $this->parameterBag = new FrozenParameterBag($this->parameterBag->all()); + } + + + public function isFrozen() + { + return $this->parameterBag instanceof FrozenParameterBag; + } + + + public function getParameterBag() + { + return $this->parameterBag; + } + + + public function getParameter($name) + { + return $this->parameterBag->get($name); + } + + + public function hasParameter($name) + { + return $this->parameterBag->has($name); + } + + + public function setParameter($name, $value) + { + $this->parameterBag->set($name, $value); + } + + + public function set($id, $service, $scope = self::SCOPE_CONTAINER) + { + if (self::SCOPE_PROTOTYPE === $scope) { + throw new InvalidArgumentException('You cannot set services of scope "prototype".'); + } + + $id = strtolower($id); + + if (self::SCOPE_CONTAINER !== $scope) { + if (!isset($this->scopedServices[$scope])) { + throw new RuntimeException('You cannot set services of inactive scopes.'); + } + + $this->scopedServices[$scope][$id] = $service; + } + + $this->services[$id] = $service; + } + + + public function has($id) + { + $id = strtolower($id); + + return isset($this->services[$id]) || method_exists($this, 'get'.strtr($id, array('_' => '', '.' => '_')).'Service'); + } + + + public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE) + { + $id = strtolower($id); + + if (isset($this->services[$id])) { + return $this->services[$id]; + } + + if (isset($this->loading[$id])) { + throw new ServiceCircularReferenceException($id, array_keys($this->loading)); + } + + if (method_exists($this, $method = 'get'.strtr($id, array('_' => '', '.' => '_')).'Service')) { + $this->loading[$id] = true; + + try { + $service = $this->$method(); + } catch (\Exception $e) { + unset($this->loading[$id]); + throw $e; + } + + unset($this->loading[$id]); + + return $service; + } + + if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) { + throw new ServiceNotFoundException($id); + } + } + + + public function initialized($id) + { + return isset($this->services[strtolower($id)]); + } + + + public function getServiceIds() + { + $ids = array(); + $r = new \ReflectionClass($this); + foreach ($r->getMethods() as $method) { + if (preg_match('/^get(.+)Service$/', $method->name, $match)) { + $ids[] = self::underscore($match[1]); + } + } + + return array_unique(array_merge($ids, array_keys($this->services))); + } + + + public function enterScope($name) + { + if (!isset($this->scopes[$name])) { + throw new InvalidArgumentException(sprintf('The scope "%s" does not exist.', $name)); + } + + if (self::SCOPE_CONTAINER !== $this->scopes[$name] && !isset($this->scopedServices[$this->scopes[$name]])) { + throw new RuntimeException(sprintf('The parent scope "%s" must be active when entering this scope.', $this->scopes[$name])); + } + + if (isset($this->scopedServices[$name])) { + $services = array($this->services, $name => $this->scopedServices[$name]); + unset($this->scopedServices[$name]); + + foreach ($this->scopeChildren[$name] as $child) { + $services[$child] = $this->scopedServices[$child]; + unset($this->scopedServices[$child]); + } + + $this->services = call_user_func_array('array_diff_key', $services); + array_shift($services); + + if (!isset($this->scopeStacks[$name])) { + $this->scopeStacks[$name] = new \SplStack(); + } + $this->scopeStacks[$name]->push($services); + } + + $this->scopedServices[$name] = array(); + } + + + public function leaveScope($name) + { + if (!isset($this->scopedServices[$name])) { + throw new InvalidArgumentException(sprintf('The scope "%s" is not active.', $name)); + } + + $services = array($this->services, $this->scopedServices[$name]); + unset($this->scopedServices[$name]); + foreach ($this->scopeChildren[$name] as $child) { + if (!isset($this->scopedServices[$child])) { + continue; + } + + $services[] = $this->scopedServices[$child]; + unset($this->scopedServices[$child]); + } + $this->services = call_user_func_array('array_diff_key', $services); + + if (isset($this->scopeStacks[$name]) && count($this->scopeStacks[$name]) > 0) { + $services = $this->scopeStacks[$name]->pop(); + $this->scopedServices += $services; + + array_unshift($services, $this->services); + $this->services = call_user_func_array('array_merge', $services); + } + } + + + public function addScope(ScopeInterface $scope) + { + $name = $scope->getName(); + $parentScope = $scope->getParentName(); + + if (self::SCOPE_CONTAINER === $name || self::SCOPE_PROTOTYPE === $name) { + throw new InvalidArgumentException(sprintf('The scope "%s" is reserved.', $name)); + } + if (isset($this->scopes[$name])) { + throw new InvalidArgumentException(sprintf('A scope with name "%s" already exists.', $name)); + } + if (self::SCOPE_CONTAINER !== $parentScope && !isset($this->scopes[$parentScope])) { + throw new InvalidArgumentException(sprintf('The parent scope "%s" does not exist, or is invalid.', $parentScope)); + } + + $this->scopes[$name] = $parentScope; + $this->scopeChildren[$name] = array(); + + while ($parentScope !== self::SCOPE_CONTAINER) { + $this->scopeChildren[$parentScope][] = $name; + $parentScope = $this->scopes[$parentScope]; + } + } + + + public function hasScope($name) + { + return isset($this->scopes[$name]); + } + + + public function isScopeActive($name) + { + return isset($this->scopedServices[$name]); + } + + + static public function camelize($id) + { + return preg_replace_callback('/(^|_|\.)+(.)/', function ($match) { return ('.' === $match[1] ? '_' : '').strtoupper($match[2]); }, $id); + } + + + static public function underscore($id) + { + return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), strtr($id, '_', '.'))); + } +} +} + + + + +namespace Symfony\Component\HttpKernel +{ + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + + +interface HttpKernelInterface +{ + const MASTER_REQUEST = 1; + const SUB_REQUEST = 2; + + + function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true); +} +} + + + + +namespace Symfony\Component\HttpKernel +{ + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\Bundle\BundleInterface; +use Symfony\Component\Config\Loader\LoaderInterface; + + +interface KernelInterface extends HttpKernelInterface, \Serializable +{ + + function registerBundles(); + + + function registerContainerConfiguration(LoaderInterface $loader); + + + function boot(); + + + function shutdown(); + + + function getBundles(); + + + function isClassInActiveBundle($class); + + + function getBundle($name, $first = true); + + + function locateResource($name, $dir = null, $first = true); + + + function getName(); + + + function getEnvironment(); + + + function isDebug(); + + + function getRootDir(); + + + function getContainer(); + + + function getStartTime(); + + + function getCacheDir(); + + + function getLogDir(); +} +} + + + + +namespace Symfony\Component\HttpKernel +{ + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Dumper\PhpDumper; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\DependencyInjection\Loader\IniFileLoader; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use Symfony\Component\DependencyInjection\Loader\ClosureLoader; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\Bundle\BundleInterface; +use Symfony\Component\HttpKernel\Config\FileLocator; +use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass; +use Symfony\Component\HttpKernel\DependencyInjection\AddClassesToCachePass; +use Symfony\Component\HttpKernel\Debug\ErrorHandler; +use Symfony\Component\HttpKernel\Debug\ExceptionHandler; +use Symfony\Component\Config\Loader\LoaderResolver; +use Symfony\Component\Config\Loader\DelegatingLoader; +use Symfony\Component\Config\ConfigCache; +use Symfony\Component\ClassLoader\ClassCollectionLoader; +use Symfony\Component\ClassLoader\DebugClassLoader; + + +abstract class Kernel implements KernelInterface, TerminableInterface +{ + protected $bundles; + protected $bundleMap; + protected $container; + protected $rootDir; + protected $environment; + protected $debug; + protected $booted; + protected $name; + protected $startTime; + protected $classes; + protected $errorReportingLevel; + + const VERSION = '2.1.0-BETA1'; + const VERSION_ID = '20100'; + const MAJOR_VERSION = '2'; + const MINOR_VERSION = '1'; + const RELEASE_VERSION = '0'; + const EXTRA_VERSION = 'BETA'; + + + public function __construct($environment, $debug) + { + $this->environment = $environment; + $this->debug = (Boolean) $debug; + $this->booted = false; + $this->rootDir = $this->getRootDir(); + $this->name = preg_replace('/[^a-zA-Z0-9_]+/', '', basename($this->rootDir)); + $this->classes = array(); + + if ($this->debug) { + $this->startTime = microtime(true); + } + + $this->init(); + } + + public function init() + { + if ($this->debug) { + ini_set('display_errors', 1); + error_reporting(-1); + + DebugClassLoader::enable(); + ErrorHandler::register($this->errorReportingLevel); + if ('cli' !== php_sapi_name()) { + ExceptionHandler::register(); + } + } else { + ini_set('display_errors', 0); + } + } + + public function __clone() + { + if ($this->debug) { + $this->startTime = microtime(true); + } + + $this->booted = false; + $this->container = null; + } + + + public function boot() + { + if (true === $this->booted) { + return; + } + + $this->initializeBundles(); + + $this->initializeContainer(); + + foreach ($this->getBundles() as $bundle) { + $bundle->setContainer($this->container); + $bundle->boot(); + } + + $this->booted = true; + } + + + public function terminate(Request $request, Response $response) + { + if (false === $this->booted) { + return; + } + + if ($this->getHttpKernel() instanceof TerminableInterface) { + $this->getHttpKernel()->terminate($request, $response); + } + } + + + public function shutdown() + { + if (false === $this->booted) { + return; + } + + $this->booted = false; + + foreach ($this->getBundles() as $bundle) { + $bundle->shutdown(); + $bundle->setContainer(null); + } + + $this->container = null; + } + + + public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) + { + if (false === $this->booted) { + $this->boot(); + } + + return $this->getHttpKernel()->handle($request, $type, $catch); + } + + + protected function getHttpKernel() + { + return $this->container->get('http_kernel'); + } + + + public function getBundles() + { + return $this->bundles; + } + + + public function isClassInActiveBundle($class) + { + foreach ($this->getBundles() as $bundle) { + if (0 === strpos($class, $bundle->getNamespace())) { + return true; + } + } + + return false; + } + + + public function getBundle($name, $first = true) + { + if (!isset($this->bundleMap[$name])) { + throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled. Maybe you forgot to add it in the registerBundles() function of your %s.php file?', $name, get_class($this))); + } + + if (true === $first) { + return $this->bundleMap[$name][0]; + } + + return $this->bundleMap[$name]; + } + + + public function locateResource($name, $dir = null, $first = true) + { + if ('@' !== $name[0]) { + throw new \InvalidArgumentException(sprintf('A resource name must start with @ ("%s" given).', $name)); + } + + if (false !== strpos($name, '..')) { + throw new \RuntimeException(sprintf('File name "%s" contains invalid characters (..).', $name)); + } + + $bundleName = substr($name, 1); + $path = ''; + if (false !== strpos($bundleName, '/')) { + list($bundleName, $path) = explode('/', $bundleName, 2); + } + + $isResource = 0 === strpos($path, 'Resources') && null !== $dir; + $overridePath = substr($path, 9); + $resourceBundle = null; + $bundles = $this->getBundle($bundleName, false); + $files = array(); + + foreach ($bundles as $bundle) { + if ($isResource && file_exists($file = $dir.'/'.$bundle->getName().$overridePath)) { + if (null !== $resourceBundle) { + throw new \RuntimeException(sprintf('"%s" resource is hidden by a resource from the "%s" derived bundle. Create a "%s" file to override the bundle resource.', + $file, + $resourceBundle, + $dir.'/'.$bundles[0]->getName().$overridePath + )); + } + + if ($first) { + return $file; + } + $files[] = $file; + } + + if (file_exists($file = $bundle->getPath().'/'.$path)) { + if ($first && !$isResource) { + return $file; + } + $files[] = $file; + $resourceBundle = $bundle->getName(); + } + } + + if (count($files) > 0) { + return $first && $isResource ? $files[0] : $files; + } + + throw new \InvalidArgumentException(sprintf('Unable to find file "%s".', $name)); + } + + + public function getName() + { + return $this->name; + } + + + public function getEnvironment() + { + return $this->environment; + } + + + public function isDebug() + { + return $this->debug; + } + + + public function getRootDir() + { + if (null === $this->rootDir) { + $r = new \ReflectionObject($this); + $this->rootDir = str_replace('\\', '/', dirname($r->getFileName())); + } + + return $this->rootDir; + } + + + public function getContainer() + { + return $this->container; + } + + + public function loadClassCache($name = 'classes', $extension = '.php') + { + if (!$this->booted && is_file($this->getCacheDir().'/classes.map')) { + ClassCollectionLoader::load(include($this->getCacheDir().'/classes.map'), $this->getCacheDir(), $name, $this->debug, false, $extension); + } + } + + + public function setClassCache(array $classes) + { + file_put_contents($this->getCacheDir().'/classes.map', sprintf('debug ? $this->startTime : -INF; + } + + + public function getCacheDir() + { + return $this->rootDir.'/cache/'.$this->environment; + } + + + public function getLogDir() + { + return $this->rootDir.'/logs'; + } + + + protected function initializeBundles() + { + $this->bundles = array(); + $topMostBundles = array(); + $directChildren = array(); + + foreach ($this->registerBundles() as $bundle) { + $name = $bundle->getName(); + if (isset($this->bundles[$name])) { + throw new \LogicException(sprintf('Trying to register two bundles with the same name "%s"', $name)); + } + $this->bundles[$name] = $bundle; + + if ($parentName = $bundle->getParent()) { + if (isset($directChildren[$parentName])) { + throw new \LogicException(sprintf('Bundle "%s" is directly extended by two bundles "%s" and "%s".', $parentName, $name, $directChildren[$parentName])); + } + if ($parentName == $name) { + throw new \LogicException(sprintf('Bundle "%s" can not extend itself.', $name)); + } + $directChildren[$parentName] = $name; + } else { + $topMostBundles[$name] = $bundle; + } + } + + if (count($diff = array_values(array_diff(array_keys($directChildren), array_keys($this->bundles))))) { + throw new \LogicException(sprintf('Bundle "%s" extends bundle "%s", which is not registered.', $directChildren[$diff[0]], $diff[0])); + } + + $this->bundleMap = array(); + foreach ($topMostBundles as $name => $bundle) { + $bundleMap = array($bundle); + $hierarchy = array($name); + + while (isset($directChildren[$name])) { + $name = $directChildren[$name]; + array_unshift($bundleMap, $this->bundles[$name]); + $hierarchy[] = $name; + } + + foreach ($hierarchy as $bundle) { + $this->bundleMap[$bundle] = $bundleMap; + array_pop($bundleMap); + } + } + + } + + + protected function getContainerClass() + { + return $this->name.ucfirst($this->environment).($this->debug ? 'Debug' : '').'ProjectContainer'; + } + + + protected function getContainerBaseClass() + { + return 'Container'; + } + + + protected function initializeContainer() + { + $class = $this->getContainerClass(); + $cache = new ConfigCache($this->getCacheDir().'/'.$class.'.php', $this->debug); + $fresh = true; + if (!$cache->isFresh()) { + $container = $this->buildContainer(); + $this->dumpContainer($cache, $container, $class, $this->getContainerBaseClass()); + + $fresh = false; + } + + require_once $cache; + + $this->container = new $class(); + $this->container->set('kernel', $this); + + if (!$fresh && $this->container->has('cache_warmer')) { + $this->container->get('cache_warmer')->warmUp($this->container->getParameter('kernel.cache_dir')); + } + } + + + protected function getKernelParameters() + { + $bundles = array(); + foreach ($this->bundles as $name => $bundle) { + $bundles[$name] = get_class($bundle); + } + + return array_merge( + array( + 'kernel.root_dir' => $this->rootDir, + 'kernel.environment' => $this->environment, + 'kernel.debug' => $this->debug, + 'kernel.name' => $this->name, + 'kernel.cache_dir' => $this->getCacheDir(), + 'kernel.logs_dir' => $this->getLogDir(), + 'kernel.bundles' => $bundles, + 'kernel.charset' => 'UTF-8', + 'kernel.container_class' => $this->getContainerClass(), + ), + $this->getEnvParameters() + ); + } + + + protected function getEnvParameters() + { + $parameters = array(); + foreach ($_SERVER as $key => $value) { + if (0 === strpos($key, 'SYMFONY__')) { + $parameters[strtolower(str_replace('__', '.', substr($key, 9)))] = $value; + } + } + + return $parameters; + } + + + protected function buildContainer() + { + foreach (array('cache' => $this->getCacheDir(), 'logs' => $this->getLogDir()) as $name => $dir) { + if (!is_dir($dir)) { + if (false === @mkdir($dir, 0777, true)) { + throw new \RuntimeException(sprintf("Unable to create the %s directory (%s)\n", $name, $dir)); + } + } elseif (!is_writable($dir)) { + throw new \RuntimeException(sprintf("Unable to write in the %s directory (%s)\n", $name, $dir)); + } + } + + $container = $this->getContainerBuilder(); + $extensions = array(); + foreach ($this->bundles as $bundle) { + if ($extension = $bundle->getContainerExtension()) { + $container->registerExtension($extension); + $extensions[] = $extension->getAlias(); + } + + if ($this->debug) { + $container->addObjectResource($bundle); + } + } + foreach ($this->bundles as $bundle) { + $bundle->build($container); + } + + $container->addObjectResource($this); + + $container->getCompilerPassConfig()->setMergePass(new MergeExtensionConfigurationPass($extensions)); + + if (null !== $cont = $this->registerContainerConfiguration($this->getContainerLoader($container))) { + $container->merge($cont); + } + + $container->addCompilerPass(new AddClassesToCachePass($this)); + $container->compile(); + + return $container; + } + + + protected function getContainerBuilder() + { + return new ContainerBuilder(new ParameterBag($this->getKernelParameters())); + } + + + protected function dumpContainer(ConfigCache $cache, ContainerBuilder $container, $class, $baseClass) + { + $dumper = new PhpDumper($container); + $content = $dumper->dump(array('class' => $class, 'base_class' => $baseClass)); + if (!$this->debug) { + $content = self::stripComments($content); + } + + $cache->write($content, $container->getResources()); + } + + + protected function getContainerLoader(ContainerInterface $container) + { + $locator = new FileLocator($this); + $resolver = new LoaderResolver(array( + new XmlFileLoader($container, $locator), + new YamlFileLoader($container, $locator), + new IniFileLoader($container, $locator), + new PhpFileLoader($container, $locator), + new ClosureLoader($container), + )); + + return new DelegatingLoader($resolver); + } + + + static public function stripComments($source) + { + if (!function_exists('token_get_all')) { + return $source; + } + + $output = ''; + foreach (token_get_all($source) as $token) { + if (is_string($token)) { + $output .= $token; + } elseif (!in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) { + $output .= $token[1]; + } + } + + $output = preg_replace(array('/\s+$/Sm', '/\n+/S'), "\n", $output); + + return $output; + } + + public function serialize() + { + return serialize(array($this->environment, $this->debug)); + } + + public function unserialize($data) + { + list($environment, $debug) = unserialize($data); + + $this->__construct($environment, $debug); + } +} +} + + + + +namespace Symfony\Component\ClassLoader +{ + + +class ClassCollectionLoader +{ + static private $loaded; + + + static public function load($classes, $cacheDir, $name, $autoReload, $adaptive = false, $extension = '.php') + { + if (isset(self::$loaded[$name])) { + return; + } + + self::$loaded[$name] = true; + + if ($adaptive) { + $classes = array_diff($classes, get_declared_classes(), get_declared_interfaces()); + + $name = $name.'-'.substr(md5(implode('|', $classes)), 0, 5); + } + + $cache = $cacheDir.'/'.$name.$extension; + + $reload = false; + if ($autoReload) { + $metadata = $cacheDir.'/'.$name.$extension.'.meta'; + if (!is_file($metadata) || !is_file($cache)) { + $reload = true; + } else { + $time = filemtime($cache); + $meta = unserialize(file_get_contents($metadata)); + + if ($meta[1] != $classes) { + $reload = true; + } else { + foreach ($meta[0] as $resource) { + if (!is_file($resource) || filemtime($resource) > $time) { + $reload = true; + + break; + } + } + } + } + } + + if (!$reload && is_file($cache)) { + require_once $cache; + + return; + } + + $files = array(); + $content = ''; + foreach ($classes as $class) { + if (!class_exists($class) && !interface_exists($class) && (!function_exists('trait_exists') || !trait_exists($class))) { + throw new \InvalidArgumentException(sprintf('Unable to load class "%s"', $class)); + } + + $r = new \ReflectionClass($class); + $files[] = $r->getFileName(); + + $c = preg_replace(array('/^\s*<\?php/', '/\?>\s*$/'), '', file_get_contents($r->getFileName())); + + if (!$r->inNamespace()) { + $c = "\nnamespace\n{\n".self::stripComments($c)."\n}\n"; + } else { + $c = self::fixNamespaceDeclarations('prefix = $prefix; + $this->classFinder = $classFinder; + } + + + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + require $file; + + return true; + } + } + + + public function findFile($class) + { + if (false === $file = apc_fetch($this->prefix.$class)) { + apc_store($this->prefix.$class, $file = $this->classFinder->findFile($class)); + } + + return $file; + } +} +} + + + + +namespace Symfony\Component\HttpKernel\Bundle +{ + +use Symfony\Component\DependencyInjection\ContainerAwareInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; + + +interface BundleInterface extends ContainerAwareInterface +{ + + function boot(); + + + function shutdown(); + + + function build(ContainerBuilder $container); + + + function getContainerExtension(); + + + function getParent(); + + + function getName(); + + + function getNamespace(); + + + function getPath(); +} +} + + + + +namespace Symfony\Component\HttpKernel\Bundle +{ + +use Symfony\Component\DependencyInjection\ContainerAware; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\Console\Application; +use Symfony\Component\Finder\Finder; + + +abstract class Bundle extends ContainerAware implements BundleInterface +{ + protected $name; + protected $reflected; + protected $extension; + + + public function boot() + { + } + + + public function shutdown() + { + } + + + public function build(ContainerBuilder $container) + { + } + + + public function getContainerExtension() + { + if (null === $this->extension) { + $basename = preg_replace('/Bundle$/', '', $this->getName()); + + $class = $this->getNamespace().'\\DependencyInjection\\'.$basename.'Extension'; + if (class_exists($class)) { + $extension = new $class(); + + $expectedAlias = Container::underscore($basename); + if ($expectedAlias != $extension->getAlias()) { + throw new \LogicException(sprintf( + 'The extension alias for the default extension of a '. + 'bundle must be the underscored version of the '. + 'bundle name ("%s" instead of "%s")', + $expectedAlias, $extension->getAlias() + )); + } + + $this->extension = $extension; + } else { + $this->extension = false; + } + } + + if ($this->extension) { + return $this->extension; + } + } + + + public function getNamespace() + { + if (null === $this->reflected) { + $this->reflected = new \ReflectionObject($this); + } + + return $this->reflected->getNamespaceName(); + } + + + public function getPath() + { + if (null === $this->reflected) { + $this->reflected = new \ReflectionObject($this); + } + + return dirname($this->reflected->getFileName()); + } + + + public function getParent() + { + return null; + } + + + final public function getName() + { + if (null !== $this->name) { + return $this->name; + } + + $name = get_class($this); + $pos = strrpos($name, '\\'); + + return $this->name = false === $pos ? $name : substr($name, $pos + 1); + } + + + public function registerCommands(Application $application) + { + if (!$dir = realpath($this->getPath().'/Command')) { + return; + } + + $finder = new Finder(); + $finder->files()->name('*Command.php')->in($dir); + + $prefix = $this->getNamespace().'\\Command'; + foreach ($finder as $file) { + $ns = $prefix; + if ($relativePath = $file->getRelativePath()) { + $ns .= '\\'.strtr($relativePath, '/', '\\'); + } + $r = new \ReflectionClass($ns.'\\'.$file->getBasename('.php')); + if ($r->isSubclassOf('Symfony\\Component\\Console\\Command\\Command') && !$r->isAbstract()) { + $application->add($r->newInstance()); + } + } + } +} +} + + + + +namespace Symfony\Component\Config +{ + + +class ConfigCache +{ + private $debug; + private $file; + + + public function __construct($file, $debug) + { + $this->file = $file; + $this->debug = (Boolean) $debug; + } + + + public function __toString() + { + return $this->file; + } + + + public function isFresh() + { + if (!is_file($this->file)) { + return false; + } + + if (!$this->debug) { + return true; + } + + $metadata = $this->file.'.meta'; + 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; + } + + + public function write($content, array $metadata = null) + { + $dir = dirname($this->file); + if (!is_dir($dir)) { + if (false === @mkdir($dir, 0777, true)) { + throw new \RuntimeException(sprintf('Unable to create the %s directory', $dir)); + } + } elseif (!is_writable($dir)) { + throw new \RuntimeException(sprintf('Unable to write in the %s directory', $dir)); + } + + $tmpFile = tempnam(dirname($this->file), basename($this->file)); + if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $this->file)) { + @chmod($this->file, 0666 & ~umask()); + } else { + throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $this->file)); + } + + if (null !== $metadata && true === $this->debug) { + $file = $this->file.'.meta'; + $tmpFile = tempnam(dirname($file), basename($file)); + if (false !== @file_put_contents($tmpFile, serialize($metadata)) && @rename($tmpFile, $file)) { + @chmod($file, 0666 & ~umask()); + } + } + } +} +} + + +namespace { return $loader; } + \ No newline at end of file diff --git a/app/cache/.gitkeep b/app/cache/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/app/check.php b/app/check.php new file mode 100644 index 0000000..daa6d0a --- /dev/null +++ b/app/check.php @@ -0,0 +1,55 @@ +getPhpIniConfigPath(); + +echo "********************************\n"; +echo "* *\n"; +echo "* Symfony requirements check *\n"; +echo "* *\n"; +echo "********************************\n\n"; + +echo $iniPath ? sprintf("* Configuration file used by PHP: %s\n\n", $iniPath) : "* WARNING: No configuration file (php.ini) used by PHP!\n\n"; + +echo "** ATTENTION **\n"; +echo "* The PHP CLI can use a different php.ini file\n"; +echo "* than the one used with your web server.\n"; +if ('\\' == DIRECTORY_SEPARATOR) { + echo "* (especially on the Windows platform)\n"; +} +echo "* To be on the safe side, please also launch the requirements check\n"; +echo "* from your web server using the web/config.php script.\n"; + +echo_title('Mandatory requirements'); + +foreach ($symfonyRequirements->getRequirements() as $req) { + echo_requirement($req); +} + +echo_title('Optional recommendations'); + +foreach ($symfonyRequirements->getRecommendations() as $req) { + echo_requirement($req); +} + +/** + * Prints a Requirement instance + */ +function echo_requirement(Requirement $requirement) +{ + $result = $requirement->isFulfilled() ? 'OK' : ($requirement->isOptional() ? 'WARNING' : 'ERROR'); + echo ' ' . str_pad($result, 9); + echo $requirement->getTestMessage() . "\n"; + + if (!$requirement->isFulfilled()) { + echo sprintf(" %s\n\n", $requirement->getHelpText()); + } +} + +function echo_title($title) +{ + echo "\n** $title **\n\n"; +} diff --git a/app/config/config.yml b/app/config/config.yml new file mode 100644 index 0000000..ff16149 --- /dev/null +++ b/app/config/config.yml @@ -0,0 +1,60 @@ +imports: + - { resource: parameters.yml } + - { resource: security.yml } + +framework: + #esi: ~ + #translator: { fallback: %locale% } + secret: %secret% + charset: UTF-8 + router: + resource: "%kernel.root_dir%/config/routing.yml" + strict_parameters: %kernel.debug% + form: true + csrf_protection: true + validation: { enable_annotations: true } + templating: { engines: ['twig'] } #assets_version: SomeVersionScheme + default_locale: %locale% + session: + auto_start: true + +# Twig Configuration +twig: + debug: %kernel.debug% + strict_variables: %kernel.debug% + +# Assetic Configuration +assetic: + debug: %kernel.debug% + use_controller: false + bundles: [ ] + #java: /usr/bin/java + filters: + cssrewrite: ~ + #closure: + # jar: %kernel.root_dir%/Resources/java/compiler.jar + #yui_css: + # jar: %kernel.root_dir%/Resources/java/yuicompressor-2.4.7.jar + +# Doctrine Configuration +doctrine: + dbal: + driver: %database_driver% + host: %database_host% + port: %database_port% + dbname: %database_name% + user: %database_user% + password: %database_password% + charset: UTF8 + + orm: + auto_generate_proxy_classes: %kernel.debug% + auto_mapping: true + +# Swiftmailer Configuration +swiftmailer: + transport: %mailer_transport% + host: %mailer_host% + username: %mailer_user% + password: %mailer_password% + spool: { type: memory } diff --git a/app/config/config_dev.yml b/app/config/config_dev.yml new file mode 100644 index 0000000..b7e675d --- /dev/null +++ b/app/config/config_dev.yml @@ -0,0 +1,26 @@ +imports: + - { resource: config.yml } + +framework: + router: { resource: "%kernel.root_dir%/config/routing_dev.yml" } + profiler: { only_exceptions: false } + +web_profiler: + toolbar: true + intercept_redirects: false + +monolog: + handlers: + main: + type: stream + path: %kernel.logs_dir%/%kernel.environment%.log + level: debug + firephp: + type: firephp + level: info + +assetic: + use_controller: true + +#swiftmailer: +# delivery_address: me@example.com diff --git a/app/config/config_prod.yml b/app/config/config_prod.yml new file mode 100644 index 0000000..0b91d4d --- /dev/null +++ b/app/config/config_prod.yml @@ -0,0 +1,19 @@ +imports: + - { resource: config.yml } + +#doctrine: +# orm: +# metadata_cache_driver: apc +# result_cache_driver: apc +# query_cache_driver: apc + +monolog: + handlers: + main: + type: fingers_crossed + action_level: error + handler: nested + nested: + type: stream + path: %kernel.logs_dir%/%kernel.environment%.log + level: debug diff --git a/app/config/config_test.yml b/app/config/config_test.yml new file mode 100644 index 0000000..e7f44e5 --- /dev/null +++ b/app/config/config_test.yml @@ -0,0 +1,14 @@ +imports: + - { resource: config_dev.yml } + +framework: + test: ~ + session: + storage_id: session.storage.mock_file + +web_profiler: + toolbar: false + intercept_redirects: false + +swiftmailer: + disable_delivery: true diff --git a/app/config/parameters.yml b/app/config/parameters.yml new file mode 100644 index 0000000..6f0c6ee --- /dev/null +++ b/app/config/parameters.yml @@ -0,0 +1,15 @@ +parameters: + database_driver: pdo_mysql + database_host: localhost + database_port: ~ + database_name: symfony + database_user: root + database_password: ~ + + mailer_transport: smtp + mailer_host: localhost + mailer_user: ~ + mailer_password: ~ + + locale: en + secret: ThisTokenIsNotSoSecretChangeIt diff --git a/app/config/routing.yml b/app/config/routing.yml new file mode 100644 index 0000000..684d364 --- /dev/null +++ b/app/config/routing.yml @@ -0,0 +1,4 @@ +# Internal routing configuration to handle ESI +#_internal: +# resource: "@FrameworkBundle/Resources/config/routing/internal.xml" +# prefix: /_internal diff --git a/app/config/routing_dev.yml b/app/config/routing_dev.yml new file mode 100644 index 0000000..22a48ae --- /dev/null +++ b/app/config/routing_dev.yml @@ -0,0 +1,27 @@ +_welcome: + pattern: / + defaults: { _controller: AcmeDemoBundle:Welcome:index } + +_demo_secured: + resource: "@AcmeDemoBundle/Controller/SecuredController.php" + type: annotation + +_demo: + resource: "@AcmeDemoBundle/Controller/DemoController.php" + type: annotation + prefix: /demo + +_wdt: + resource: "@WebProfilerBundle/Resources/config/routing/wdt.xml" + prefix: /_wdt + +_profiler: + resource: "@WebProfilerBundle/Resources/config/routing/profiler.xml" + prefix: /_profiler + +_configurator: + resource: "@SensioDistributionBundle/Resources/config/routing/webconfigurator.xml" + prefix: /_configurator + +_main: + resource: routing.yml diff --git a/app/config/security.yml b/app/config/security.yml new file mode 100644 index 0000000..e01c1c2 --- /dev/null +++ b/app/config/security.yml @@ -0,0 +1,43 @@ +jms_security_extra: + secure_all_services: false + expressions: true + +security: + encoders: + Symfony\Component\Security\Core\User\User: plaintext + + role_hierarchy: + ROLE_ADMIN: ROLE_USER + ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH] + + providers: + in_memory: + memory: + users: + user: { password: userpass, roles: [ 'ROLE_USER' ] } + admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] } + + firewalls: + dev: + pattern: ^/(_(profiler|wdt)|css|images|js)/ + security: false + + login: + pattern: ^/demo/secured/login$ + security: false + + secured_area: + pattern: ^/demo/secured/ + form_login: + check_path: /demo/secured/login_check + login_path: /demo/secured/login + logout: + path: /demo/secured/logout + target: /demo/ + #anonymous: ~ + #http_basic: + # realm: "Secured Demo Area" + + access_control: + #- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https } + #- { path: ^/_internal/secure, roles: IS_AUTHENTICATED_ANONYMOUSLY, ip: 127.0.0.1 } diff --git a/app/console b/app/console new file mode 100755 index 0000000..1de6db4 --- /dev/null +++ b/app/console @@ -0,0 +1,22 @@ +#!/usr/bin/env php +getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev'); +$debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(array('--no-debug', '')) && $env !== 'prod'; + +$kernel = new AppKernel($env, $debug); +$application = new Application($kernel); +$application->run($input); diff --git a/app/logs/.gitkeep b/app/logs/.gitkeep new file mode 100755 index 0000000..e69de29 diff --git a/app/phpunit.xml.dist b/app/phpunit.xml.dist new file mode 100644 index 0000000..1e31086 --- /dev/null +++ b/app/phpunit.xml.dist @@ -0,0 +1,41 @@ + + + + + + + + ../src/*/*Bundle/Tests + ../src/*/Bundle/*Bundle/Tests + + + + + + + + ../src + + ../src/*/*Bundle/Resources + ../src/*/*Bundle/Tests + ../src/*/Bundle/*Bundle/Resources + ../src/*/Bundle/*Bundle/Tests + + + + + diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..e101250 --- /dev/null +++ b/composer.json @@ -0,0 +1,41 @@ +{ + "name": "symfony/framework-standard-edition", + "description": "The \"Symfony Standard Edition\" distribution", + "autoload": { + "psr-0": { "": "src/" } + }, + "require": { + "php": ">=5.3.3", + "symfony/symfony": "2.1.*", + "doctrine/orm": "2.2.*", + "doctrine/doctrine-bundle": "dev-master", + "twig/extensions": "dev-master", + "symfony/assetic-bundle": "dev-master", + "symfony/swiftmailer-bundle": "dev-master", + "symfony/monolog-bundle": "dev-master", + "sensio/distribution-bundle": "dev-master", + "sensio/framework-extra-bundle": "dev-master", + "sensio/generator-bundle": "dev-master", + "jms/security-extra-bundle": "1.1.*", + "jms/di-extra-bundle": "1.0.*" + }, + "scripts": { + "post-install-cmd": [ + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets" + ], + "post-update-cmd": [ + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets" + ] + }, + "config": { + "bin-dir": "bin" + }, + "extra": { + "symfony-app-dir": "app", + "symfony-web-dir": "web" + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..3bb6230 --- /dev/null +++ b/composer.lock @@ -0,0 +1,144 @@ +{ + "hash": "60f09c83d9f0891b51ac51941970dcd5", + "packages": [ + { + "package": "doctrine/common", + "version": "2.2.2" + }, + { + "package": "doctrine/dbal", + "version": "2.2.x-dev", + "source-reference": "8cc129aa64a8de6447056bce20f0a274fe2a340b" + }, + { + "package": "doctrine/doctrine-bundle", + "version": "dev-master", + "source-reference": "94951737d6c692500d6b13bb92871935568a4ba5" + }, + { + "package": "doctrine/orm", + "version": "2.2.x-dev", + "source-reference": "5f66c65c9a8d984899903b54215d0249a45b92d6" + }, + { + "package": "jms/aop-bundle", + "version": "1.0.0" + }, + { + "package": "jms/cg", + "version": "1.0.0" + }, + { + "package": "jms/di-extra-bundle", + "version": "1.0.1" + }, + { + "package": "jms/metadata", + "version": "1.1.1" + }, + { + "package": "jms/security-extra-bundle", + "version": "1.1.0" + }, + { + "package": "kriswallsmith/assetic", + "version": "dev-master", + "alias-pretty-version": "1.1.x-dev", + "alias-version": "1.1.9999999.9999999-dev" + }, + { + "package": "kriswallsmith/assetic", + "version": "dev-master", + "source-reference": "d6f89a3170c5280ad554347dc113eb25fdf00ad7" + }, + { + "package": "monolog/monolog", + "version": "1.1.0" + }, + { + "package": "sensio/distribution-bundle", + "version": "dev-master", + "source-reference": "a360ad61fe34206a7295c1ef00b5455b2b2e1071" + }, + { + "package": "sensio/framework-extra-bundle", + "version": "dev-master", + "source-reference": "62e41b85947034b0f1dfe31bb8e76920e1488571" + }, + { + "package": "sensio/generator-bundle", + "version": "dev-master", + "source-reference": "43ed45c48db18e4a0e48aec0c098f42e56e22d36" + }, + { + "package": "swiftmailer/swiftmailer", + "version": "dev-master", + "alias-pretty-version": "4.1.x-dev", + "alias-version": "4.1.9999999.9999999-dev" + }, + { + "package": "swiftmailer/swiftmailer", + "version": "dev-master", + "source-reference": "d57ffdeed664d6061cef0047e1f5d3fc3ee3fb99" + }, + { + "package": "symfony/assetic-bundle", + "version": "dev-master", + "source-reference": "8fe7b898b08103c1d6fce64c3e279a7afd61adfc" + }, + { + "package": "symfony/monolog-bundle", + "version": "dev-master", + "source-reference": "0b5046d3d1ef93cd59ceabfa37de2665f5118c7f" + }, + { + "package": "symfony/swiftmailer-bundle", + "version": "dev-master", + "source-reference": "d05c9c514a631ee688c53c4cc5505da757bd50d3" + }, + { + "package": "symfony/symfony", + "version": "dev-master", + "alias-pretty-version": "2.1.x-dev", + "alias-version": "2.1.9999999.9999999-dev" + }, + { + "package": "symfony/symfony", + "version": "dev-master", + "source-reference": "v2.1.0-BETA1" + }, + { + "package": "twig/extensions", + "version": "dev-master", + "source-reference": "feb6d3f10c411e2631997c0a905aa581c80305c1" + }, + { + "package": "twig/twig", + "version": "dev-master", + "alias-pretty-version": "1.8.x-dev", + "alias-version": "1.8.9999999.9999999-dev" + }, + { + "package": "twig/twig", + "version": "dev-master", + "source-reference": "4679ad51c5390648b7ea4c8f0ecd2c0c344145ba" + } + ], + "packages-dev": [ + + ], + "aliases": [ + + ], + "minimum-stability": "dev", + "stability-flags": { + "doctrine/doctrine-bundle": 20, + "twig/extensions": 20, + "symfony/assetic-bundle": 20, + "symfony/swiftmailer-bundle": 20, + "symfony/monolog-bundle": 20, + "sensio/distribution-bundle": 20, + "sensio/framework-extra-bundle": 20, + "sensio/generator-bundle": 20 + } +} diff --git a/src/.htaccess b/src/.htaccess new file mode 100644 index 0000000..3418e55 --- /dev/null +++ b/src/.htaccess @@ -0,0 +1 @@ +deny from all \ No newline at end of file diff --git a/src/Acme/DemoBundle/AcmeDemoBundle.php b/src/Acme/DemoBundle/AcmeDemoBundle.php new file mode 100644 index 0000000..269fc1e --- /dev/null +++ b/src/Acme/DemoBundle/AcmeDemoBundle.php @@ -0,0 +1,9 @@ + $name); + } + + /** + * @Route("/contact", name="_demo_contact") + * @Template() + */ + public function contactAction() + { + $form = $this->get('form.factory')->create(new ContactType()); + + $request = $this->get('request'); + if ('POST' == $request->getMethod()) { + $form->bindRequest($request); + if ($form->isValid()) { + $mailer = $this->get('mailer'); + // .. setup a message and send it + // http://symfony.com/doc/current/cookbook/email.html + + $this->get('session')->setFlash('notice', 'Message sent!'); + + return new RedirectResponse($this->generateUrl('_demo')); + } + } + + return array('form' => $form->createView()); + } +} diff --git a/src/Acme/DemoBundle/Controller/SecuredController.php b/src/Acme/DemoBundle/Controller/SecuredController.php new file mode 100644 index 0000000..9848e42 --- /dev/null +++ b/src/Acme/DemoBundle/Controller/SecuredController.php @@ -0,0 +1,69 @@ +get('request')->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) { + $error = $this->get('request')->attributes->get(SecurityContext::AUTHENTICATION_ERROR); + } else { + $error = $this->get('request')->getSession()->get(SecurityContext::AUTHENTICATION_ERROR); + } + + return array( + 'last_username' => $this->get('request')->getSession()->get(SecurityContext::LAST_USERNAME), + 'error' => $error, + ); + } + + /** + * @Route("/login_check", name="_security_check") + */ + public function securityCheckAction() + { + // The security layer will intercept this request + } + + /** + * @Route("/logout", name="_demo_logout") + */ + public function logoutAction() + { + // The security layer will intercept this request + } + + /** + * @Route("/hello", defaults={"name"="World"}), + * @Route("/hello/{name}", name="_demo_secured_hello") + * @Template() + */ + public function helloAction($name) + { + return array('name' => $name); + } + + /** + * @Route("/hello/admin/{name}", name="_demo_secured_hello_admin") + * @Secure(roles="ROLE_ADMIN") + * @Template() + */ + public function helloadminAction($name) + { + return array('name' => $name); + } +} diff --git a/src/Acme/DemoBundle/Controller/WelcomeController.php b/src/Acme/DemoBundle/Controller/WelcomeController.php new file mode 100644 index 0000000..acceedf --- /dev/null +++ b/src/Acme/DemoBundle/Controller/WelcomeController.php @@ -0,0 +1,18 @@ +render('AcmeDemoBundle:Welcome:index.html.twig'); + } +} diff --git a/src/Acme/DemoBundle/DependencyInjection/AcmeDemoExtension.php b/src/Acme/DemoBundle/DependencyInjection/AcmeDemoExtension.php new file mode 100644 index 0000000..6dfcc82 --- /dev/null +++ b/src/Acme/DemoBundle/DependencyInjection/AcmeDemoExtension.php @@ -0,0 +1,22 @@ +load('services.xml'); + } + + public function getAlias() + { + return 'acme_demo'; + } +} diff --git a/src/Acme/DemoBundle/EventListener/ControllerListener.php b/src/Acme/DemoBundle/EventListener/ControllerListener.php new file mode 100644 index 0000000..5274f71 --- /dev/null +++ b/src/Acme/DemoBundle/EventListener/ControllerListener.php @@ -0,0 +1,25 @@ +extension = $extension; + } + + public function onKernelController(FilterControllerEvent $event) + { + if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) { + $this->extension->setController($event->getController()); + } + } +} diff --git a/src/Acme/DemoBundle/Form/ContactType.php b/src/Acme/DemoBundle/Form/ContactType.php new file mode 100644 index 0000000..2c76cdb --- /dev/null +++ b/src/Acme/DemoBundle/Form/ContactType.php @@ -0,0 +1,20 @@ +add('email', 'email'); + $builder->add('message', 'textarea'); + } + + public function getName() + { + return 'contact'; + } +} diff --git a/src/Acme/DemoBundle/Resources/config/services.xml b/src/Acme/DemoBundle/Resources/config/services.xml new file mode 100644 index 0000000..d6274ce --- /dev/null +++ b/src/Acme/DemoBundle/Resources/config/services.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + diff --git a/src/Acme/DemoBundle/Resources/public/css/demo.css b/src/Acme/DemoBundle/Resources/public/css/demo.css new file mode 100644 index 0000000..0a9d8e2 --- /dev/null +++ b/src/Acme/DemoBundle/Resources/public/css/demo.css @@ -0,0 +1,294 @@ +/* +Copyright (c) 2010, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.com/yui/license.html +version: 2.8.2r1 + +Reset +*/ + +html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var,optgroup{font-style:inherit;font-weight:inherit;}del,ins{text-decoration:none;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:baseline;}sub{vertical-align:baseline;}legend{color:#000;}input,button,textarea,select,optgroup,option{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;}input,button,textarea,select{*font-size:100%;} + +html, body +{ + background-color: #EFEFEF; +} + +body +{ + font-size: 14px; + font-family: "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif; + color: #313131; +} + +a +{ + color: #08C; + text-decoration: none; +} + +a:hover +{ + text-decoration: underline; +} + +strong +{ + font-weight: bold; +} + +em +{ + font-style: italic; +} + +h1, h2, h3 +{ + font-family: Georgia, "Times New Roman", Times, serif; + color: #404040; +} + +h1 +{ + font-size: 45px; + padding-bottom: 30px; +} + +h2 +{ + font-weight: bold; + color: #FFFFFF; + /* Font is duplicated of body (sans-serif) */ + font-family: "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif; + + margin-bottom: 10px; + background-color: #aacd4e; + padding: 2px 4px; + display: inline-block; + text-transform: uppercase; + +} + +p +{ + line-height: 20px; + padding-bottom: 20px; +} + +ul#demo-list a +{ + background: url(../images/blue-arrow.png) no-repeat right 6px; + padding-right: 10px; + margin-right: 30px; +} + +ul, ol +{ + padding-left: 20px; +} + +li +{ + padding-bottom: 18px; +} + +ol li +{ + list-style-type: decimal; +} + +ul li +{ + list-style-type: none; +} + +#symfony-header +{ + position: relative; + padding: 30px 30px 20px 30px; +} + +#symfony-wrapper +{ + width: 970px; + margin: 0 auto; +} + +.symfony-content +{ + background-color: white; + border: 1px solid #DFDFDF; + padding: 50px; + -moz-border-radius: 16px; + -webkit-border-radius: 16px; + border-radius: 16px; + margin-bottom: 20px; + word-wrap: break-word; +} + +#symfony-search +{ + position: absolute; + top: 50px; + right: 30px; +} + +#symfony-search input[type="search"] +{ + -webkit-appearance: textfield; +} + +#symfony-search-field +{ + width: 190px; +} + +#symfony-search label +{ + display: block; + float: left; + width: 20px; + height: 25px; + background: url(../images/search.png) no-repeat left 5px; +} + +#symfony-search label span +{ + display: none; +} + +input[type=text], input[type=password] +{ + border: 1px solid #DADADA; + background: white url(../images/field-background.gif) repeat-x left top; + padding: 5px 6px; + color: #565656; + font-family: 'Lucida Sans Unicode', 'Lucida Grande', Verdana, Arial, Helvetica, sans-serif; + font-size: 12px; +} + +.symfony-button-grey, +.symfony-button-green +{ + font-size: 0.85em; + font-weight: bold; + + cursor: pointer; + + display: inline-block; + outline: none; + + text-align: center; + text-transform: uppercase; + + padding: 3px 10px; + + text-shadow: 0 1px 1px rgba(0,0,0,.3); + + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.symfony-button-grey +{ + color: #868686; + font-weight: normal; + + padding: 5px 10px; + border: solid 1px #d7d7d7; + background: #ffffff; + background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#d7d7d7)); + background: -moz-linear-gradient(top, #ffffff, #d7d7d7); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#d7d7d7'); +} + +.symfony-button-green +{ + padding: 5px 12px; + + color: white; + + border: solid 1px #a7da39; + background: #a7da39; + background: -webkit-gradient(linear, left top, left bottom, from(#a7da39), to(#6a9211)); + background: -moz-linear-gradient(top, #a7da39, #6a9211); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#a7da39', endColorstr='#6a9211'); +} + +.symfony-blocks-welcome +{ + overflow: hidden; +} + +.symfony-blocks-welcome > div +{ + background-color: whitesmoke; + float: left; + width: 240px; + margin-right: 14px; + text-align: center; + padding: 26px 20px; +} + +.symfony-blocks-welcome > div.block-demo +{ + margin-right: 0; +} + +.symfony-blocks-welcome .illustration +{ + padding-bottom: 20px; +} + +.symfony-blocks-help +{ + overflow: hidden; +} + +.symfony-blocks-help +{ + margin-top: 30px; + padding: 18px; + border: 1px solid #E6E6E6; +} + +.symfony-blocks-help > div +{ + width: 254px; + float: left; +} + +.flash-message +{ + padding: 10px; + margin: 5px; + margin-top: 15px; + background-color: #ffe; +} + +.error +{ + color: red; +} + +#login label, #contact_form label +{ + display: block; + float: left; + width: 90px; +} + +ul#menu +{ + float: right; + margin-bottom: 20px; + padding-left: 0; +} + +#menu li +{ + padding-left: 0; + margin-right: 10px; + display: inline; +} diff --git a/src/Acme/DemoBundle/Resources/public/images/blue-arrow.png b/src/Acme/DemoBundle/Resources/public/images/blue-arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..fa82d4b4fff6414062efb2a02049cfeb9e8e7cb1 GIT binary patch literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c!3HD^Kbl$tDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9Md6+I= zhqi>4PnzMOuO)K~*(RkoSoCn7)R^#~T4CSujwM;<0=t>E&QEnQ(&y3G(9U?$#xX^m ckwt=G)hqGzYlDe*q4@=v9Pj!eSesj znO9X=ad2|Jy}yf!jHIKbv9Yp#e1F*3*>P`jS5;V~q@}*Tzl({C|Ns9mE;9fB{{R30 z000000000000000A^8LW000^QEC2ui0JZ==06+!*peBxFX^z0-1i_MJ3+p_pEh_&5dM^QH^o`2q?YC;|Y#eo6?SBFL~IkO9*W zUWrg(6a+6t1e9~gkzoUD0u)q?cL8IkHxMNMW_YDz4U&xn4G;-%fMrJwrreB*aD?3_ z1wa){Fo|t|jsdNTB$!ozNI7K6ROJ$p6pPVgF9`4wMB>|mt0D|wjG70m21m-KH6S4q zhKOfKG;JyM!j7010!F!0IkQPpts|OdaKxZQty_Z;XW06P@mIDOfgM&{!i#`0fD`e3 zQEdyS&0Nj2C9?Kr8lnz-R4p>0a~KE_K`S#&yS5Dk42ZH}fWWNn-@r{EpxZBi&EUv6 z8aN0#2?2n~qoYCA9N}^4*n51eZlv`Vo}$7KN0+^P4l3M z2>3zos9Q+@lo%19fEJ&v_eMl=Ver}i6~3L26fm|Wb=^(lB>@IXO1OprcmzanA$V+L zb^~<*z@))9>6GxyTD2hYPk$N-mINXQ^p_PtcqCwBVHzYQp9trqhK*03$jI3zp=`EL z4gk;<4l+DyFhEu)P)UL+z8NDzFH^jr%?TK>h?fa6iXfN(BusNv6&G%ik!z~7xy6*t zIl-j}Y9eFPWF!!y%L|M_g5H-VU{nL2eF8edifzfKN)iT20F<12yZv3FsjK z;Rr5efTm$DL^*<=i7qz6og;{q#A5}anraE7fn!1!py{+pbtXdbOp509;L?wY*qD(5 z06@@Q5uSu`O>_G}VTmEZ{vb*JgE&xUL1w2rpe-Fev@4h-90G~<(Y|8JzQl6785e#5UFuM(io2~!?FPxpW2UiiX#KE~* z@e34008|A3Hij{FaHUIu9SUF;&k<9N3>-uiQxHZ4U%WA%01CV85UvN?MKf#F{QQ#6 zwS{a20W27sMHohcl(Pv9{JSJU??&s;yP0%mi5&wxi^V4(W-tK+3tD074XPv%P67Jn zgWlPu)oR5^7&M*1$rz+WHy1@*`e+rU;lOHbgVTm}65KMKgaFOHA#`1H_0h5o&rIGb zE)5zmMj3GkP)KY67-azeT>((?w-JLB@U8#{nAQ0qC1>EkRbD)Is|#A0lK2~y79sN} zNG@y24sdXt_r~;iTHpx_=E*BaSP{$|$EWviZgdX{vBSluA zfC7ZqxHo|4cW)@0O6rG$hWUwSS3w4Z5G8{2&1zKz6h<&!@COo>P*Ep(L223&B{pG- z2y^&^Ds~qJqs^mjH~7XN@K6{!CC`PjdZDVeRKRC^iZLxrq7p~2JUof2D@uqT9E_kv z39)c17fSdz2oVk(|*9gP26mT@rLI(4sh?6#MCjsXOoCcz2gl2{9QVN>M zDBh=%)a0N50dPS1QV22^6&KcVi9jlXAybu*3hZqF zu;Jn-Qqr8K6@)kfNWj!GMXb&_vW`!zqp1P`D-sM~lX-ZeEsNm?6HFs{LTHX2-e5P0 zkjo5$5s}2!XM@Adqk=r!%(|SQh-ZjzVV3BW)ka{=J|u_>4l{-2o)9YhVN4aQ+W{Xl zVi%ZY#c|acCDCl7u_MR{1AEbx1k!1WaqiPJ^IWEzLb9vsZ1bQIlEVaoGL-Z@6r#YP s-o}b>F^nP~2bk%~rANzE00$7X3b6#@NZAEF2Ha}_46x5i%M$_sJDrx#NB{r; literal 0 HcmV?d00001 diff --git a/src/Acme/DemoBundle/Resources/public/images/search.png b/src/Acme/DemoBundle/Resources/public/images/search.png new file mode 100644 index 0000000000000000000000000000000000000000..3c88b6a4234ef5bb048bcecdc210c603c629339d GIT binary patch literal 737 zcmV<70v`Q|P)gsCw z?(Xh4xV&O-EF1{%v$Hc}p-`|-CXOKadE^5EYyTmDC?Y##GKKABNo`~s zLF(c`qtW1~>;;02jSb|4JwHFws4L4|dU$xyR;yJpOS9ShvMeIucDqsPSgls04i67^ zudlCF^5t+iY`DL_|1z7+aDpH(kH^D-eYOw*djIL-;^K2ImlLBXmCC7Ft?t1k1=OrV zbAs&K+uPHdo134KPSg28(u0uZL?W^N`1ttdAju2Ftl!?=rk4qjs%Q?Fd_K=)G8uKb zTo#2g8jZr%)|L>D$5ow9N4&r=Od}GBJXx*QsZ4-L%BlhHkl28gxh{~|Y<4Xa3hBGu zu2>GdkJj<=@lzlWc##P(sRN|cXSr3Vr388oK=SeO^3nk1iX?iyzH@SN@`IQwQIH~z zr6EEXNki4N+wE*L8s+4vY`5DqkeV=*!G8c{N&(F2bov`SHs96N)ps~Ee+3u-E3-EG TZ0Qdg@&dtu!(bC4n#!gC6v$3?Nrl_Q&rEYC-z`wzoGFfKFn^z_}_-9SD=NJUGMkd*WC^1{Kx=H}*CR#`$nMLaq` zgMoxyT3|msLFwq|sHdq+NKa~MYfej1goA}eLP$$UPHbv#S5#U$H#~H5cCW3lE-f%Y zK0`)CNk&6SK0HB%goZ*uMR<03LqJA8J3vH2M`>qkKRrTVUSdp1PpPP?HZwSKaCA~n zRGOHZkdKi^L`q3UOo@n!etdpPMop2Bl6G`>Jvu+Zz`=lifr5a9u&=R*hKXESUaqaL zjf;&uIX>6c)>Kkgt*oxAs;n_DGsecpV_;>9iHjm2BdV#ZXJl&2%F4sS!-j>3p`W4K z+S}RK+11q4tgEeLVrIp}##&fhEGjNaM@_%J!E0!3qM@U4aC2>IaC~}xDJUx>BPJ^; zEn;9}C?+bsy}nFKPI`EIB_tn0QpCf>=;!Cu)74E%P%|+#G%_}UfP%ljzdATQJ2^f%Haj;pIXgH#H8VF) zOjAutQS0mLHZ(XmHaj>qIyW^sHZ(amG&%3@?=&$sH8M9iHaapeHSzKBG%`2D!^AT& zHZw3aIX62XA0i_mC8wsR?d|RE?(X2<-|+D8#l*$%@9*sF?Ck67IygM#<>uz)g%truv%AJ*45VO>FGB%IcsTd^6~MerKZcv%sV$U0~49&!eKGGBGrjl$P=E@apO6 zM@C40eSt(mMNdsqo0^=Qo1ITiQMk9c*Vow7($nAH-*t3%?(OaD?CsFc&^kFgP)t)W zE;8if`03oqv!~CWK!XY$ zI+P2?qYaxtih`s@4HzEoA)R{k5KyXE3zERZNz$fJnNabfiinGlX_pcnS;d&lr|8Xe9chMqKjNBmdN4T)z!-Q?!@)SX$1RphWXmCoI#2XtA8B-4s5-V{_?F%I-f2{?u+W`EmcVCI=Z z;+2uQ_##oLrmE_yL7@-~rxgwVfgzwA&H!tB>+N)_L|+go;gKqAR0|iD6l;km4jEu< zu^`};t4_N{#KD0HF38CNs43t}E9r6MKnDx#(M& z*>@cVm&DT8KQTz+@4u3;1I<4d#3Ku6?!x;Jf274{uWDd?Bge!P%b`mWsX;L@82Ypz z2QRLaA%_UK5QfMw>{gVp!VNKuoN^DF!-p0$*W8B$58t81J`J#-g%S@Vh98V9FXVDR z4hOCD()A7f8Ot+_DfQF>!p2u2egRf3gF&X~=;wwV3L0goCR&*ymNw;tDwmZC zGxgjwGLe-m2S^yUQ)37J3gru+rc^;K2r0vXO{emcGN#c0u*@KkM=tr~lvi%~<(Ov< z`6`?j;CTTcgf2P=JCwe|7O1CQ#p-0V-Z~YqQ}M*?E3Dwm?M&p(L>=`M?fdV*2QU2Z z78KAy+9rf>WtNGv>iqN2@3e+Da1U=#FG4H;BH&W0R791^ug#*VZbxta`9uL@eL-1h z$f1V|*t-5jE6@K=6Jj%Yg#8xPKmQjgI8u^=#gSU9VF`<42sGYslbaYIIQg+33GC!G zJUyZZ9AQNaeDD%CRPP|sK*391at?!d;tuerO9bb~fgjPS6Lw-oRuq5*7wqAK0#Sks zcF02)w80rS=;0gxR7f-y@@NqU`Vk;th8RT1LLC?}Mh04NgI)-P08PrG7PUACr1)=r zOVCk)ioryCorf9>*}?`M!A3T+Ax2-c9)GG;-|AZ9UvP#+?wVi5u$ z1|8zS0U4-*81}-zEcEpcU|9A&!_tAi+=*q43p&_Qbag(W*mGD#=NvguF-1gn8wA7t0s` z(2m+jpanuABYs2)u6QM(7Nk&;l=LUEnJr2btrChLh0&qlusvY%s7`HEH7gLvKnPNh zNx!1dBk^fgE{!PnP$H_Agil2^?a57v6SbYvEeM9p3N|7%p`{#kNe_kJ_FgazhIC+j zH>pGxG-ZH7SoN(q>gi8KS}m?P2rMbx8;0ChHtn4)rlZnL zN`8_ph&O>Z1eVeYzyTh}fPdG7mHJ642`0#beb)p5UMRU6iADk)f(&e|fB?YQa7HFv zv@fJ|PZ-8XEpAYg7(j#xK4{Sh9tgoAt}h060viT35)C&zY6Q_}h#DRhlLDAf8AN=V z1iOMzU$p@#qlm^D(r|*Q3S$5Y~&R9v%m*HqgJ2@nPD0MWz`N1|dY@+0g#MK*At}L)uu5axH`?j?GAI<)T{! z0Y@apO>QW3iNq{>k8J9=Pr@KW1w4qiyvu9aJ8$2 zq7;i!0$=>Fj&u~FkXb>u!s027|%EhfJT^du;312*ai#Afq^Bk;0D0|8D+48 ziO*9i?Fr~WgUn}+26v3%Fh-F159;9pH0;3@dqBet6oBcCNE}`iUm6hL!1Sg!oeisj z0vym#jV=fR4l{6t6W{=d!@L?F;Eu@Aqm}fBDS;1YPkY+);0oq^fe+tk00MNuhargJ z9ehy1a+1Algp7SxWv`Dp;1CBsT)`jWh=bzcfQ|WZAP)VwKm*VahaV*38gV$re7qg@ zZm#^BEgxph{y+j<&}Tnfo6JN8Y1fPdEf=UJ~2pz?scCBoCR$LyUzkU z`w6Xo!pG(9PJVfauTlHmUir{x4f6~8{ODW%Fw-}FY4Umf?qk39zdKt09vKE%pEaD!76y2mozB zfi;qCtF~uDg;&4gRZf9a@ADyl)l|u|JjAsV6)=QEScF4}ESB1%gV|Jw8Y(Q6&^smKWu)ggYgJKvh>=@fBPpKsh)zJLp#;CLf8X~l(? zVh3ROR!xY3Pk2x$^(#~8C$z#`zco=K7+AwaK0ncgcp*1;7$$kAU<8`OIjitFqcb|D zb2>y|16{>Xd*xC**oGBVf^8#Jm(mA~cq8SI7gCT{E2V?m^;;rB7YgACQxJr9b}7qn ziZ^lwbwCx_pa&C>V;06zd?kp0GY<;k4bhb)+>j{`po?HAh9X5$HCR+QXkbY-D8N;S z!Zj1`a0r}Y4F>>?OPGgxw1*prC&NgEO=5-36*$~z0!u&-5mt}(c#rs)kNUWe77-8t EJ3feF)c^nh literal 0 HcmV?d00001 diff --git a/src/Acme/DemoBundle/Resources/public/images/welcome-demo.gif b/src/Acme/DemoBundle/Resources/public/images/welcome-demo.gif new file mode 100644 index 0000000000000000000000000000000000000000..0623de54c9501be250cd0907bd09f6b452c53fe6 GIT binary patch literal 4053 zcmV;`4=V6SNk%w1VX^>Z0Qdg@<>cf~Oj15OLCVR>IygOCSzhVr=u}Wwot&P7f`q}q z!aX`bsHUjl;NW?8dptTnjEattkdkk0adB>Qw6nF&&CW3{GfhfRLO?~9l$cIRQ9wRJ z*45Uls;rNWkb!@KrlqIa+S^c0QGb4bmX(*Wu(C!(NN8qhrKF}`U0_T|Prbdqu&=RW zVP$l4c71z(h=z&gw>L_j@4tgEe*la=V^=07|^l8}@|LP)Q!v5AO^Oi53; zxVbhnI7dWE-QC?%PE}f0U1?@)&d$%w%gjqjO-o2lNk&Z4(b92nb75a%oSB_5FEev+ zb(eSe3Ah|9{%j*XAT#>a|@jGmpJW@Kl!wYS*U*j7_mJUKqb#m7iTN_Ta5 zOiE7G)YWQfYtYZpPE1f>U1GVoxmj3Svaz$Tt*=c?PitvyN=HpHFf=nUH8nFgG%_~x z^Yb?~IW{ynJ2^f$H99ypIyg2v@$vCDG&wmoJ2y2t@9*#R_4PC{HZ?Lg=jP@!F*fV! z>NYevGB7ncH#_O+>iYWnGcYyu^z<|`H}382;NRfl;o|D)>G1IJ?Cb33=jXt`!1(z1 zG z=I7(%lq$*eL;(9X}dwz#^vyHHG1;+-i!kaXEGMu-qLkRYuA z1Lnd7BTzUPj0I(%)2C3QN_9Gb! zZA!(10Hz077B&d*Gw7NrdW;$|5@1Rthi9Y~07bFGhlHR=b)8JPvJbH?2^1;2Y)^s& z!DfYmz_LWyvLsxxE4u=7%Q62dHH#F9l_XJ=HvAe1N}rsm!1oOqNM}m$r$j0%UtSrH zYnFUYOOJKLWf7&MXJ4m|w?loAP5A`THzRpC%8oVfGKHl}DH8IO~FBf^nK zMv@mrN#OZhcyZ7s$&}`aaY|gCq(T4zfIJ{TeDoc0!~|AVYH32ubN~Vc71VO+r=W%^ z>ZqiaYU-(|rmE_ythVavLY&C|!Vd!}M1p4*c0{x4Jyqc7R0f>9+TxsC(U6UwVu?_K zXk`&Yfh91pkkA_sz$f1Z^?9jNn0*OFluD!M32aOODppl>=2>~D^1Of)u&Q~7>OgQ968H5Qv)c{4u zi-^@Mogm#FbSt8e17Yd^aS#`Aq;1d#>Lp6ZVGbeCpHM^5IM@_7CWuemaSstzAEzZ_ zLeru66M@xTGysts+qJ+%J{8zP!W%Ae?KPq2ol>}>j9M$-*M5} zd}Pr}M>Wum86gFXfCmHhpwavE)K_o)_1I^x{r22<@BR1ShcEs^t!x9#K89N9fX* z!nC*xe#;0`P{u(20s)*q;K3Zh`bR7nP=Me7fmD&9D0G6Y_^GwzGnN z?4e4tgF!=*Aq4&aWeOP7z!V;WCaIi(3&?Lhgr;m4@aT^I9^93F-WT+eNaFfl1Pyo`0AGgVL`;Ef`C#w2pP{Y z0e1W`fIYT^1lZx5)nJnbu0>){l(0cWD$#~|G=c!KXA$ak~v_f0CXb+K^W0OZ-UbmlQ0ybyyz%MZ9r1F15;0U_N{jUO`gHYK|Prx zgRlVLGzoCY7NqlsmZ(BHWKdoq4RR;&s7w-)paen{nu#@}ARdfr=(Ql4pDyep4GP(X z1J;PqrxakLJ;IC$lwb=EaG)L$IOR*EDIG`9O-TpgMOZ8l9)&Ta4|jQ#d>-?Vb{yrR zAY=eim(zf`SuLMsF$Uf8v5+x@r3MFC2Oh9m5I4}pE)+Nj0E~fYenfrN4M(kcd1mg zw{`C&&%e;~3Fq470f~477v{iUQGE_XU64Ty>;Qr#R6rLE&aj3z%;64u_`@I$v4}@Z z;u4$q#3)X&idW3y7Q6VxFphDVOo59iIRY1W?2mIKTlN7|{maIiv!KaGM+q_^KvXgE9?hL3@3$iZm$t52tC(OC}+( zg}fsdFLET~D*7Ky9>fV{C~6y1m1SHk=LYQ!28A}qk}H;F6)l8G3lh?UCg4|R1`~?U zjxq%f5@Zm^Ilu&53!F1}R#ew8z>Zd_JOa?7EZT8NHnQLb9lsnt~66`3)O9 z;wMkgby1{H2`40WAAd+ULR8U2sXWmtmDq);icoibiaKJvKV31JgLf%M?HfAD$bbrKx zLoIm#32xzxKTNGG4`zupZ^6Llgd+`>z=2iVq6Dl4ksfS79`m3l4-Rp_mk@D=7vKR4`M?3c z9RdR!wc#L{2M!BB-xUTtCk5ESg0)%lfo#%E25AsfOc6?^N_8OAI6?;hL6UzQ2r!>3 zS=dh9rLzo^yQBlyk$b)3@sDwchnHX2NC@Uo0vl8T1`==rXr)+OKm=0YD<^P%ThVdP zVFUUkS1qv_(!o#q(ggxx2wa6+FhvP`Kn@2{4TsPNJzxh8&;n{8UE30Fj~90ER8$J$ z2MWj!EPxp)PzP1h4Qu<6b${SwdsdPt{}vxOq(i#nb&=G9 zE;toB5Q9;031M+kW$^(n;Re!?ek>74uQq*nLIMR*0dtdqv|$@EwOq|bU(j_eD5xJk zfm(+pg;V$xTo8l&@B(3h49((xEb#`X(FZP33DPl0Ruc(?Mi4Up(N05TGCdpD0gcz=sroKah4Bu|PL(kPr;`5?m7x zKb8>2fB}xO1-C;8_V5r8fQKNY2zISs;AZt=iwMDxFyS`_F%Oadz;*@!0|o{G5J3e8!-63h z9Ay9tB*_n#5f=V*8qwGfbx;;~qc4cihzj8WVc`Z5aR!Q)D8b+m25g71B@;mB0z0@Cv423ZwvcYsCOm6cd)P2oZTChLCL#p$nK{lMA5)-?V)RrFff= z0wo|s|6l+tFbF&FP~X-CbodjLvJi(CG2~_up}+~l@Cv_R3bjBA8^;_C00FSrKn0*= z6R`-c!3TFa5WT=Ukcb;dSU5EUaA%WWJ75AmK}-#@;cJ)j44j|~k||pQPy?BXECs*| z^f(dBW;JSfnr#?ba41&A$Wykt1A*W@m0%3WFak0_XT=}`GT;p)P-z~a2>*4RRC0Cf zv4l5+J3nxISB4O^&}H?xfrP!BwLn5dk>b4}Z`CBR~QmkOtE!q)z&zP#UFDI;B)vrB-Sw H0RaFzT>Bsn literal 0 HcmV?d00001 diff --git a/src/Acme/DemoBundle/Resources/public/images/welcome-quick-tour.gif b/src/Acme/DemoBundle/Resources/public/images/welcome-quick-tour.gif new file mode 100644 index 0000000000000000000000000000000000000000..b9018b11dd21302f850984fe9b49e49828101a00 GIT binary patch literal 4770 zcmWmDhd;>NTP8@B}G;x z4R2>=zW(%XH@m8@)s z4Nms98+Y&8^W(?QN7av!)r@<^C3|Xky z?BmBztj!(+10QUx?Ck9v*4x;3babR7r;Lt{T3Og;q-Tzde9pa==k4LUiRrS@o_QeX z(ADf~H?H66dDA1fncvjdtj*B*Hzl>Lt^MYWTiI8x_V)Ji)6&yY`H`p3HaE905bgf{ z_wU}m+qvEU<;$0Ib8|_F$s&Bnw zg}1+a`BGN;upqza;`x74lK)+!qlaPj!G}XG$0zO$2yA=RrlYmyY~;C!u*lZdSNVd1 z=g(gp3qIlL=JTxfxtojU$>X7i4+dwXXE-~$&d<*`HZ<~h(MN+rPDey?FY$`+-g9zr zPEAd#t$oJ!@qO~RW^r+`y}cuh6Vcw*{_@4k#>S@dhZPsjUBv3@pFewEQ}guho#M?- ztk<2d`TTTYeZ%Y5UFrOc)|S@FimDgSUtIc!*C1?kuyLP%g4*Z$HU#z!_6b%a-yy6 zdKYI`N2b#T`;8{X>#QuS%}{eMcecB$*IHxLWs@7a*35(DZDO>}be*}8fr+7kv6mZr zor$TwuA#fDx3S?`BSRBIePaVXBLh7{Gt|NywKO-iv@o->G`F@ev$is~S#P`1+S1O} z+J0zgXl7>S>(_~?sj11yNr^-YpcJ$nU|4`+_KmhNV@(0-geqj z^@%r!r9)f<>|`q5{S>>(`_F2XeXW^BJ6;}n90Ins+v<59d^$Tu$NSra7Tm%9Y5%Sy zUELMgRys4@bAQLagKfX+=bU4A`P6MZuLhc82%w#VF(%e9KXNr0pK+)Ghu^BsVQguO zfnD^6W0kfC563C`Yw=A{6ar1bDI|!1&+hL=g*!Ph76A`NMw0J~v_7X;^ag+a*XB#k z0X0xQTu4P?5fR1mW#CBqDndh&qNml@(M)z*Lo*y=FL5zj$q;v}O2$uvRC|l57^>MH zk&qtJDsagS49IL{((M;W84-~Y@wBtv5<0;8BZ(oO^DLms4MY_AX!1PK*cI&J88?Hi zVuP!<^L6m!%ZUR3)+WPJBl8F-8bo0%Kp0gC^jMsh}GFe*l zrDU?KCfAX)^#Sn$j20^$`&QAad;eQyhgF`jIj9^HEprb0MK^DCLLQU|1H|8-h~tfZ z)Qn~yE30v)#)2!>0r#D1OpZU>Zfa1LldzIACQEay4}hEN0FrSzW{aP?8Qx+X)P_+> zDfH`#0`8bY68U=Ba{@uT!&a4L-lVz^KgiN@Oo39+ri-y|4C5!?D%(A5R9@pPQ27Ma zWqn~7Z8_GDtowRFGA%MbW-0=;Joyt2C!Tvk%?L$ddUqlRp`kyJ9=4oD#P`|0J!itG zK_`y$<29BMelziie(z}e;&g?`;2(hkxe=&-{Eb zH%e9_n_u))FwyV75dFu$)54hoNm|xP|NQDZCH*_qPQFAuo>SkT-B#Y)9fd+`s5(m1 zeoc#>)g(POPASfvh3*%FD+M^vt2lbij|$4FYNl7zbk8+^rjr6#LgQjQ(~ToM>tC-( zTNCoB_r$SZO+?Oz*<3kgF=hKV$z>+B0G3|1arXZ8lTPP2Dx7R}PK`J~{j3ebs8f@n ze|nNR*+cQkm6Qmb3G&|7dZ3xrY?eEf66{&1-Zfthu!d7M+6eO=+aS2(!>MOG3RnGZ zZP~aum3AQ@mKhsV8Yp6rE(G9KCi>xb+DxbOQ;Kx-++Ml+n`P`%O;E@dL~9^xGF)~a z35dWFn{s+1mg^h>V7FvVSeToKpS_s%}lAG=@Ojz(R4#J$C&IWfM@T*@eJ5D z@UR+q&4rn+*7>+G{N^lGZLd;BG???NNZ;!y?pq+co>~B$v)Q?Ft9uU!GZ8u1@s0js znpe?V>-sR4NqjolK@6ylsTu?mw?yBuo4x0Kn>$L@CPrmp@-gxdl_h$+DTPON7RQIz z0PiZTENT8rEm{bQbNoRmQ5r9HN-(7dsyaHBX1X|LbSJ-DoP8K&851sW#MOBVS363K zfRQf%X4m`h2;7PySnrzU7=ZgOGvIDzBK7QCmEi9;P^JoysSZ+O3IG+nBDrgOy?{h6 zJ?^Lh@uUyLco-HrMCao~C%Jd?Iw{~r=HQ6>@0tTSUg%9m&H?f;WSX#BIn`s&#Cb<# z5XMox193d#;Ti{W*;a3U@^tR+=i??1mF&@+z(EGkkg!|Zo&Rxh;7qEe4Gu@u=dTr5 zmyY};n+@WqN1rpG5>|P%N{5(eo12cQO_dEA zT6ozqRz=c|j*%75=9|#e&}3-K7BW|G9h|}?-;fU=?QAH!z-qj3)%vmx3sPqQ*-U+Y zlJ5G2SM1cvth=6LhMR25z%4lQWvt^88Eo_Uuz$&E6KQ+SLPxN7Rc>F$7prHxq@8@2 zr4@)koy&#fqrLmN@(P#7hI=$uV2wsZuW=`hMNxuxb%Dx>U^nb2(X1w#Sr9bt`C~yh z61#QB+QdOyE}xLL(*?g$AzEFBs}==jJc3Of4h1ag`sM^tm*jbd5(fR0gz1_zTw*NX zsoASG>Nan^qoBUj|Drxdw%OD)R^r%Oc;S&(EQ7wHTpZL6@Te|lb@`}`g#7t(nsUq*y_+q5|Ncel1*<`R0@qZ3()et>RuyM zN!9ZiummmHkOsQ_MA@P)Fn} zt`@d~UivTV<#hc0;*|j{Kb1FL?A5GLL7HfjLfJ%Gg zb1@=;ezDJsi9|E7^ARsI3T~xE3A^8D;3;JtFMgc)*=9p-l)wJ=yMxxnwzVH_A_g{B zr>}PX2|v05=<(%!DS*qqY1Sd~=$*MIU4QrQ-GQ($P%2Zql!gbYWct>T*XWivKA7+Q6v}5AWFob78}3(g!`01J6OL@Dk1b$%ezR6igIm!$Rk1_XY+zv)b|N;u0^j*s`Nv1_j)ZaaX-1TmChz;d%6 z3Ef75fTL_6LrkYM_?D#0-Olknh{B3|iy84AgLinLFBJf&rXna2AuLyKupMY$#i_wHr}g5?NJsgPr7UEi?4Xe2a^jAUiJhJ_!6Hpmu$x z3W0!8N8m}2#%5H5%T(85s$5f10jtu(M>CC@)CwKvcg8(wkxHK`hH>4`s1ZOORS$q*W~dYZ2Vt`7 z#Pl7QtT}9*iC%wWdt)P@_ow?%0D3*BH}7=0?8k*0Vzrykq=6t~oIX@3Ybb_LZc-J4 zwg$N=q1>88;AoNU^#wW^zIjxX2j=5zB)0%{0VpH5B_cYF)9W!jR4bq^-g@+l9tGg~ zxCCem9vp!FsDY2m^EC(ZS1sm0W>Z#*X-Vd)3^s0?L>8$nFs{u%EK*X7q&=Od>xuIt z<>I9+h44rQi(QUaa0CMTLqc5YpX;AsqAWjo@d_n zuf6>|CSQsG*ro&El10oy{$|ooY zmEOc_ttc$V+%n zUq7kyi9=ztN&Ir+1+hFPg8qTY%3Q)F5jfn7!&^XF&Q1)x&Q1ZDCnCF=!W47DCENNH4#o+7}EL=wuI@Ghl?2N@x75it~Rwx zOb!!;;W5ZTLMmD!l`oRaP{>>ae$sXF0&xFjJB19(8}JD`F+3Xyo{v0L_&(2$c`8dn z#}M#=>`Afi$qouu{H~7$D1muaq1#W$=7G(l3yanS9W7H%u Pcp^k-X1orE1J?f^bf!^p literal 0 HcmV?d00001 diff --git a/src/Acme/DemoBundle/Resources/views/Demo/contact.html.twig b/src/Acme/DemoBundle/Resources/views/Demo/contact.html.twig new file mode 100644 index 0000000..e5b7523 --- /dev/null +++ b/src/Acme/DemoBundle/Resources/views/Demo/contact.html.twig @@ -0,0 +1,15 @@ +{% extends "AcmeDemoBundle::layout.html.twig" %} + +{% block title "Symfony - Contact form" %} + +{% block content %} +
+ {{ form_errors(form) }} + + {{ form_row(form.email) }} + {{ form_row(form.message) }} + + {{ form_rest(form) }} + +
+{% endblock %} diff --git a/src/Acme/DemoBundle/Resources/views/Demo/hello.html.twig b/src/Acme/DemoBundle/Resources/views/Demo/hello.html.twig new file mode 100644 index 0000000..3997ff6 --- /dev/null +++ b/src/Acme/DemoBundle/Resources/views/Demo/hello.html.twig @@ -0,0 +1,9 @@ +{% extends "AcmeDemoBundle::layout.html.twig" %} + +{% block title "Hello " ~ name %} + +{% block content %} +

Hello {{ name }}!

+{% endblock %} + +{% set code = code(_self) %} diff --git a/src/Acme/DemoBundle/Resources/views/Demo/index.html.twig b/src/Acme/DemoBundle/Resources/views/Demo/index.html.twig new file mode 100644 index 0000000..75f118d --- /dev/null +++ b/src/Acme/DemoBundle/Resources/views/Demo/index.html.twig @@ -0,0 +1,14 @@ +{% extends "AcmeDemoBundle::layout.html.twig" %} + +{% block title "Symfony - Demos" %} + +{% block content_header '' %} + +{% block content %} +

Available demos

+ +{% endblock %} diff --git a/src/Acme/DemoBundle/Resources/views/Secured/hello.html.twig b/src/Acme/DemoBundle/Resources/views/Secured/hello.html.twig new file mode 100644 index 0000000..c8da283 --- /dev/null +++ b/src/Acme/DemoBundle/Resources/views/Secured/hello.html.twig @@ -0,0 +1,11 @@ +{% extends "AcmeDemoBundle:Secured:layout.html.twig" %} + +{% block title "Hello " ~ name %} + +{% block content %} +

Hello {{ name }}!

+ + Hello resource secured for admin only. +{% endblock %} + +{% set code = code(_self) %} diff --git a/src/Acme/DemoBundle/Resources/views/Secured/helloadmin.html.twig b/src/Acme/DemoBundle/Resources/views/Secured/helloadmin.html.twig new file mode 100644 index 0000000..425213e --- /dev/null +++ b/src/Acme/DemoBundle/Resources/views/Secured/helloadmin.html.twig @@ -0,0 +1,9 @@ +{% extends "AcmeDemoBundle:Secured:layout.html.twig" %} + +{% block title "Hello " ~ name %} + +{% block content %} +

Hello {{ name }} secured for Admins only!

+{% endblock %} + +{% set code = code(_self) %} diff --git a/src/Acme/DemoBundle/Resources/views/Secured/layout.html.twig b/src/Acme/DemoBundle/Resources/views/Secured/layout.html.twig new file mode 100644 index 0000000..aeea55c --- /dev/null +++ b/src/Acme/DemoBundle/Resources/views/Secured/layout.html.twig @@ -0,0 +1,6 @@ +{% extends "AcmeDemoBundle::layout.html.twig" %} + +{% block content_header_more %} + {{ parent() }} +
  • logged in as {{ app.user ? app.user.username : 'Anonymous' }} - Logout
  • +{% endblock %} diff --git a/src/Acme/DemoBundle/Resources/views/Secured/login.html.twig b/src/Acme/DemoBundle/Resources/views/Secured/login.html.twig new file mode 100644 index 0000000..005175d --- /dev/null +++ b/src/Acme/DemoBundle/Resources/views/Secured/login.html.twig @@ -0,0 +1,29 @@ +{% extends 'AcmeDemoBundle::layout.html.twig' %} + +{% block content %} +

    Login

    + +

    + Choose between two default users: user/userpass (ROLE_USER) or admin/adminpass (ROLE_ADMIN) +

    + + {% if error %} +
    {{ error.message }}
    + {% endif %} + +
    +
    + + +
    + +
    + + +
    + + +
    +{% endblock %} + +{% set code = code(_self) %} diff --git a/src/Acme/DemoBundle/Resources/views/Welcome/index.html.twig b/src/Acme/DemoBundle/Resources/views/Welcome/index.html.twig new file mode 100644 index 0000000..cbad2ab --- /dev/null +++ b/src/Acme/DemoBundle/Resources/views/Welcome/index.html.twig @@ -0,0 +1,63 @@ +{% extends 'AcmeDemoBundle::layout.html.twig' %} + +{% block title %}Symfony - Welcome{% endblock %} + +{% block content_header '' %} + +{% block content %} +

    Welcome!

    + +

    Congratulations! You have successfully installed a new Symfony application.

    + +
    + + {% if app.environment == 'dev' %} +
    +
    + Configure your application +
    + Configure +
    + {% endif %} +
    +
    + Demo +
    + Run The Demo +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +{% endblock %} diff --git a/src/Acme/DemoBundle/Resources/views/layout.html.twig b/src/Acme/DemoBundle/Resources/views/layout.html.twig new file mode 100644 index 0000000..3dd3936 --- /dev/null +++ b/src/Acme/DemoBundle/Resources/views/layout.html.twig @@ -0,0 +1,49 @@ + + + + + {% block title %}Demo Bundle{% endblock %} + + + + +
    +
    + + Symfony logo + + +
    + + {% for flashMessage in app.session.flashbag.get('notice') %} +
    + Notice: {{ flashMessage }} +
    + {% endfor %} + + {% block content_header %} + + +
    + {% endblock %} + +
    + {% block content %} + {% endblock %} +
    + + {% if code is defined %} +

    Code behind this page

    +
    {{ code|raw }}
    + {% endif %} +
    + + diff --git a/src/Acme/DemoBundle/Tests/Controller/DemoControllerTest.php b/src/Acme/DemoBundle/Tests/Controller/DemoControllerTest.php new file mode 100644 index 0000000..2941af9 --- /dev/null +++ b/src/Acme/DemoBundle/Tests/Controller/DemoControllerTest.php @@ -0,0 +1,17 @@ +request('GET', '/demo/hello/Fabien'); + + $this->assertTrue($crawler->filter('html:contains("Hello Fabien")')->count() > 0); + } +} diff --git a/src/Acme/DemoBundle/Twig/Extension/DemoExtension.php b/src/Acme/DemoBundle/Twig/Extension/DemoExtension.php new file mode 100644 index 0000000..8f6533a --- /dev/null +++ b/src/Acme/DemoBundle/Twig/Extension/DemoExtension.php @@ -0,0 +1,80 @@ +loader = $loader; + } + + public function setController($controller) + { + $this->controller = $controller; + } + + /** + * {@inheritdoc} + */ + public function getFunctions() + { + return array( + 'code' => new \Twig_Function_Method($this, 'getCode', array('is_safe' => array('html'))), + ); + } + + public function getCode($template) + { + $controller = htmlspecialchars($this->getControllerCode(), ENT_QUOTES, 'UTF-8'); + $template = htmlspecialchars($this->getTemplateCode($template), ENT_QUOTES, 'UTF-8'); + + // remove the code block + $template = str_replace('{% set code = code(_self) %}', '', $template); + + return <<Controller Code

    +
    $controller
    + +

    Template Code

    +
    $template
    +EOF; + } + + protected function getControllerCode() + { + $class = get_class($this->controller[0]); + if (class_exists('CG\Core\ClassUtils')) { + $class = ClassUtils::getUserClass($class); + } + + $r = new \ReflectionClass($class); + $m = $r->getMethod($this->controller[1]); + + $code = file($r->getFilename()); + + return ' '.$m->getDocComment()."\n".implode('', array_slice($code, $m->getStartline() - 1, $m->getEndLine() - $m->getStartline() + 1)); + } + + protected function getTemplateCode($template) + { + return $this->loader->getSource($template->getTemplateName()); + } + + /** + * Returns the name of the extension. + * + * @return string The extension name + */ + public function getName() + { + return 'demo'; + } +} diff --git a/vendor/ClassLoader.php b/vendor/ClassLoader.php new file mode 100644 index 0000000..d07cb31 --- /dev/null +++ b/vendor/ClassLoader.php @@ -0,0 +1,203 @@ + + * 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 an PSR-0 class loader + * + * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md + * + * $loader = new ComposerClassLoader(); + * + * // 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 +{ + private $prefixes = array(); + private $fallbackDirs = array(); + private $useIncludePath = false; + private $classMap = array(); + + public function getPrefixes() + { + return $this->prefixes; + } + + public function getFallbackDirs() + { + return $this->fallbackDirs; + } + + 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 classes + * + * @param string $prefix The classes prefix + * @param array|string $paths The location(s) of the classes + */ + public function add($prefix, $paths) + { + if (!$prefix) { + foreach ((array) $paths as $path) { + $this->fallbackDirs[] = $path; + } + return; + } + if (isset($this->prefixes[$prefix])) { + $this->prefixes[$prefix] = array_merge( + $this->prefixes[$prefix], + (array) $paths + ); + } else { + $this->prefixes[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include for class files. + * + * @param Boolean $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 Boolean + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Registers this instance as an autoloader. + * + * @param Boolean $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 Boolean|null True, if loaded + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + require $file; + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|null The path, if found + */ + public function findFile($class) + { + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + + if ('\\' == $class[0]) { + $class = substr($class, 1); + } + + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $classPath = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 0, $pos)) . DIRECTORY_SEPARATOR; + $className = substr($class, $pos + 1); + } else { + // PEAR-like class name + $classPath = null; + $className = $class; + } + + $classPath .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; + + foreach ($this->prefixes as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) { + return $dir . DIRECTORY_SEPARATOR . $classPath; + } + } + } + } + + foreach ($this->fallbackDirs as $dir) { + if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) { + return $dir . DIRECTORY_SEPARATOR . $classPath; + } + } + + if ($this->useIncludePath && $file = stream_resolve_include_path($classPath)) { + return $file; + } + } +} diff --git a/vendor/autoload.php b/vendor/autoload.php new file mode 100644 index 0000000..d979957 --- /dev/null +++ b/vendor/autoload.php @@ -0,0 +1,27 @@ + $path) { + $loader->add($namespace, $path); + } + + $classMap = require $composerDir . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + + $loader->register(); + + return $loader; +}); diff --git a/vendor/autoload_classmap.php b/vendor/autoload_classmap.php new file mode 100644 index 0000000..b382d27 --- /dev/null +++ b/vendor/autoload_classmap.php @@ -0,0 +1,9 @@ + $vendorDir . '/twig/extensions/lib/', + 'Twig_' => $vendorDir . '/twig/twig/lib/', + 'Symfony\\Bundle\\SwiftmailerBundle' => $vendorDir . '/symfony/swiftmailer-bundle/', + 'Symfony\\Bundle\\MonologBundle' => $vendorDir . '/symfony/monolog-bundle/', + 'Symfony\\Bundle\\AsseticBundle' => $vendorDir . '/symfony/assetic-bundle/', + 'Symfony\\Bridge\\Swiftmailer' => $vendorDir . '/symfony/swiftmailer-bridge/', + 'Symfony' => $vendorDir . '/symfony/symfony/src/', + 'SessionHandlerInterface' => $vendorDir . '/symfony/symfony/src/Symfony/Component/HttpFoundation/Resources/stubs', + 'Sensio\\Bundle\\GeneratorBundle' => $vendorDir . '/sensio/generator-bundle/', + 'Sensio\\Bundle\\FrameworkExtraBundle' => $vendorDir . '/sensio/framework-extra-bundle/', + 'Sensio\\Bundle\\DistributionBundle' => $vendorDir . '/sensio/distribution-bundle/', + 'Monolog' => $vendorDir . '/monolog/monolog/src/', + 'Metadata\\' => $vendorDir . '/jms/metadata/src/', + 'JMS\\SecurityExtraBundle' => $vendorDir . '/jms/security-extra-bundle/', + 'JMS\\DiExtraBundle' => $vendorDir . '/jms/di-extra-bundle/', + 'JMS\\AopBundle' => $vendorDir . '/jms/aop-bundle/', + 'Doctrine\\ORM' => $vendorDir . '/doctrine/orm/lib/', + 'Doctrine\\DBAL' => $vendorDir . '/doctrine/dbal/lib/', + 'Doctrine\\Common' => $vendorDir . '/doctrine/common/lib/', + 'Doctrine\\Bundle\\DoctrineBundle' => $vendorDir . '/doctrine/doctrine-bundle/', + 'CG\\' => $vendorDir . '/jms/cg/src/', + 'Assetic' => $vendorDir . '/kriswallsmith/assetic/src/', + '' => $baseDir . '/src/', +); diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php new file mode 100644 index 0000000..5b9574e --- /dev/null +++ b/vendor/composer/ClassLoader.php @@ -0,0 +1,205 @@ + + * 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 +{ + private $prefixes = array(); + private $fallbackDirs = array(); + private $useIncludePath = false; + private $classMap = array(); + + public function getPrefixes() + { + return $this->prefixes; + } + + public function getFallbackDirs() + { + return $this->fallbackDirs; + } + + 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 classes + * + * @param string $prefix The classes prefix + * @param array|string $paths The location(s) of the classes + */ + public function add($prefix, $paths) + { + if (!$prefix) { + foreach ((array) $paths as $path) { + $this->fallbackDirs[] = $path; + } + + return; + } + if (isset($this->prefixes[$prefix])) { + $this->prefixes[$prefix] = array_merge( + $this->prefixes[$prefix], + (array) $paths + ); + } else { + $this->prefixes[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param Boolean $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 Boolean + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Registers this instance as an autoloader. + * + * @param Boolean $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 Boolean|null True, if loaded + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + include $file; + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|null The path, if found + */ + public function findFile($class) + { + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + + if ('\\' == $class[0]) { + $class = substr($class, 1); + } + + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $classPath = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 0, $pos)) . DIRECTORY_SEPARATOR; + $className = substr($class, $pos + 1); + } else { + // PEAR-like class name + $classPath = null; + $className = $class; + } + + $classPath .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; + + foreach ($this->prefixes as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) { + return $dir . DIRECTORY_SEPARATOR . $classPath; + } + } + } + } + + foreach ($this->fallbackDirs as $dir) { + if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) { + return $dir . DIRECTORY_SEPARATOR . $classPath; + } + } + + if ($this->useIncludePath && $file = stream_resolve_include_path($classPath)) { + return $file; + } + } +} diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php new file mode 100644 index 0000000..4a9177d --- /dev/null +++ b/vendor/composer/autoload_classmap.php @@ -0,0 +1,9 @@ + $vendorDir . '/twig/extensions/lib/', + 'Twig_' => $vendorDir . '/twig/twig/lib/', + 'Symfony\\Bundle\\SwiftmailerBundle' => $vendorDir . '/symfony/swiftmailer-bundle/', + 'Symfony\\Bundle\\MonologBundle' => $vendorDir . '/symfony/monolog-bundle/', + 'Symfony\\Bundle\\AsseticBundle' => $vendorDir . '/symfony/assetic-bundle/', + 'Symfony' => $vendorDir . '/symfony/symfony/src/', + 'SessionHandlerInterface' => $vendorDir . '/symfony/symfony/src/Symfony/Component/HttpFoundation/Resources/stubs', + 'Sensio\\Bundle\\GeneratorBundle' => $vendorDir . '/sensio/generator-bundle/', + 'Sensio\\Bundle\\FrameworkExtraBundle' => $vendorDir . '/sensio/framework-extra-bundle/', + 'Sensio\\Bundle\\DistributionBundle' => $vendorDir . '/sensio/distribution-bundle/', + 'Monolog' => $vendorDir . '/monolog/monolog/src/', + 'Metadata\\' => $vendorDir . '/jms/metadata/src/', + 'JMS\\SecurityExtraBundle' => $vendorDir . '/jms/security-extra-bundle/', + 'JMS\\DiExtraBundle' => $vendorDir . '/jms/di-extra-bundle/', + 'JMS\\AopBundle' => $vendorDir . '/jms/aop-bundle/', + 'Doctrine\\ORM' => $vendorDir . '/doctrine/orm/lib/', + 'Doctrine\\DBAL' => $vendorDir . '/doctrine/dbal/lib/', + 'Doctrine\\Common' => $vendorDir . '/doctrine/common/lib/', + 'Doctrine\\Bundle\\DoctrineBundle' => $vendorDir . '/doctrine/doctrine-bundle/', + 'CG\\' => $vendorDir . '/jms/cg/src/', + 'Assetic' => $vendorDir . '/kriswallsmith/assetic/src/', + '' => $baseDir . '/src/', +); diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json new file mode 100644 index 0000000..51ab6ef --- /dev/null +++ b/vendor/composer/installed.json @@ -0,0 +1,1171 @@ +[ + { + "name": "jms/metadata", + "version": "1.1.1", + "version_normalized": "1.1.1.0", + "time": "2011-12-31 21:32:49", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/metadata", + "reference": "1.1.1" + }, + "dist": { + "type": "zip", + "url": "https://github.com/schmittjoh/metadata/zipball/1.1.1", + "reference": "1.1.1", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "installation-source": "dist", + "license": [ + "Apache" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + } + ], + "description": "Class/method/property metadata management in PHP", + "keywords": [ + "annotations", + "yaml", + "xml", + "metadata" + ], + "autoload": { + "psr-0": { + "Metadata\\": "src/" + } + } + }, + { + "name": "jms/cg", + "version": "1.0.0", + "version_normalized": "1.0.0.0", + "time": "2011-12-31 20:40:52", + "source": { + "type": "git", + "url": "git://github.com/schmittjoh/cg-library.git", + "reference": "1.0.0" + }, + "dist": { + "type": "zip", + "url": "https://github.com/schmittjoh/cg-library/zipball/1.0.0", + "reference": "1.0.0", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "installation-source": "dist", + "license": [ + "Apache" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + } + ], + "description": "Toolset for generating PHP code", + "keywords": [ + "code generation" + ], + "autoload": { + "psr-0": { + "CG\\": "src/" + } + } + }, + { + "name": "jms/aop-bundle", + "version": "1.0.0", + "version_normalized": "1.0.0.0", + "target-dir": "JMS/AopBundle", + "time": "2011-12-31 20:50:26", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/JMSAopBundle", + "reference": "1.0.0" + }, + "dist": { + "type": "zip", + "url": "https://github.com/schmittjoh/JMSAopBundle/zipball/1.0.0", + "reference": "1.0.0", + "shasum": "" + }, + "require": { + "symfony/framework-bundle": "2.*", + "jms/cg": "1.0.0" + }, + "type": "symfony-bundle", + "installation-source": "dist", + "license": [ + "Apache" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + } + ], + "description": "Adds AOP capabilities to Symfony2", + "keywords": [ + "annotations", + "aop" + ], + "autoload": { + "psr-0": { + "JMS\\AopBundle": "" + } + } + }, + { + "name": "jms/security-extra-bundle", + "version": "1.1.0", + "version_normalized": "1.1.0.0", + "target-dir": "JMS/SecurityExtraBundle", + "time": "2012-01-01 00:38:12", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/JMSSecurityExtraBundle", + "reference": "1.1.0" + }, + "dist": { + "type": "zip", + "url": "https://github.com/schmittjoh/JMSSecurityExtraBundle/zipball/1.1.0", + "reference": "1.1.0", + "shasum": "" + }, + "require": { + "symfony/framework-bundle": "2.*", + "jms/metadata": "1.1.*", + "jms/aop-bundle": "1.0.*" + }, + "type": "symfony-bundle", + "installation-source": "source", + "license": [ + "Apache" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + } + ], + "description": "Enhances the Symfony2 Security Component by adding several new features", + "keywords": [ + "annotations", + "authorization" + ], + "autoload": { + "psr-0": { + "JMS\\SecurityExtraBundle": "" + } + } + }, + { + "name": "jms/di-extra-bundle", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "target-dir": "JMS/DiExtraBundle", + "time": "2012-02-26 16:01:54", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/JMSDiExtraBundle", + "reference": "1.0.1" + }, + "dist": { + "type": "zip", + "url": "https://github.com/schmittjoh/JMSDiExtraBundle/zipball/1.0.1", + "reference": "1.0.1", + "shasum": "" + }, + "require": { + "symfony/framework-bundle": "2.*", + "jms/metadata": "1.1.*" + }, + "type": "symfony-bundle", + "installation-source": "dist", + "license": [ + "Apache" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + } + ], + "description": "Allows to configure dependency injection using annotations", + "keywords": [ + "dependency injection", + "annotations" + ], + "autoload": { + "psr-0": { + "JMS\\DiExtraBundle": "" + } + } + }, + { + "name": "doctrine/common", + "version": "2.2.2", + "version_normalized": "2.2.2.0", + "time": "2012-04-11 01:46:44", + "source": { + "type": "git", + "url": "https://github.com/doctrine/common", + "reference": "2.2.2" + }, + "dist": { + "type": "zip", + "url": "https://github.com/doctrine/common/zipball/2.2.2", + "reference": "2.2.2", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "installation-source": "dist", + "license": [ + "LGPL" + ], + "authors": [ + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com", + "homepage": "http://www.jwage.com/" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com", + "homepage": null + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org", + "homepage": null + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de", + "homepage": null + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + } + ], + "description": "Common Library for Doctrine projects", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "collections", + "spl", + "eventmanager", + "annotations", + "persistence" + ], + "autoload": { + "psr-0": { + "Doctrine\\Common": "lib/" + } + } + }, + { + "name": "monolog/monolog", + "version": "1.1.0", + "version_normalized": "1.1.0.0", + "time": "2012-04-21 12:27:40", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "1.1.0" + }, + "dist": { + "type": "zip", + "url": "https://github.com/Seldaek/monolog/zipball/1.1.0", + "reference": "1.1.0", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "mlehner/gelf-php": "1.0.*" + }, + "suggest": { + "mlehner/gelf-php": "Allow sending log messages to a GrayLog2 server" + }, + "type": "library", + "installation-source": "dist", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be", + "role": null + } + ], + "description": "Logging for PHP 5.3", + "homepage": "http://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging" + ], + "autoload": { + "psr-0": { + "Monolog": "src/" + } + } + }, + { + "name": "twig/extensions", + "version": "dev-master", + "version_normalized": "9999999-dev", + "time": "2012-05-19 19:28:19", + "source": { + "type": "git", + "url": "https://github.com/fabpot/Twig-extensions", + "reference": "feb6d3f10c411e2631997c0a905aa581c80305c1" + }, + "dist": { + "type": "zip", + "url": "https://github.com/fabpot/Twig-extensions/zipball/feb6d3f10c411e2631997c0a905aa581c80305c1", + "reference": "feb6d3f10c411e2631997c0a905aa581c80305c1", + "shasum": "" + }, + "require": { + "twig/twig": "1.*" + }, + "type": "library", + "installation-source": "source", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": null, + "role": null + } + ], + "description": "Common additional features for Twig that do not directly belong in core", + "homepage": "https://github.com/fabpot/Twig-extensions", + "keywords": [ + "debug", + "i18n", + "text" + ], + "autoload": { + "psr-0": { + "Twig_Extensions_": "lib/" + } + } + }, + { + "name": "symfony/monolog-bundle", + "version": "dev-master", + "version_normalized": "9999999-dev", + "target-dir": "Symfony/Bundle/MonologBundle", + "time": "2012-06-13 05:14:37", + "source": { + "type": "git", + "url": "https://github.com/symfony/MonologBundle", + "reference": "0b5046d3d1ef93cd59ceabfa37de2665f5118c7f" + }, + "dist": { + "type": "zip", + "url": "https://github.com/symfony/MonologBundle/zipball/0b5046d3d1ef93cd59ceabfa37de2665f5118c7f", + "reference": "0b5046d3d1ef93cd59ceabfa37de2665f5118c7f", + "shasum": "" + }, + "require": { + "php": ">=5.3.2", + "monolog/monolog": "1.*", + "symfony/monolog-bridge": "2.1.*", + "symfony/dependency-injection": "2.1.*", + "symfony/config": "2.1.*" + }, + "require-dev": { + "symfony/yaml": "2.1.*" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "installation-source": "source", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": null, + "role": null + }, + { + "name": "Symfony Community", + "email": null, + "homepage": "http://symfony.com/contributors", + "role": null + } + ], + "description": "Symfony MonologBundle", + "homepage": "http://symfony.com", + "autoload": { + "psr-0": { + "Symfony\\Bundle\\MonologBundle": "" + } + } + }, + { + "name": "kriswallsmith/assetic", + "version": "dev-master", + "version_normalized": "9999999-dev", + "time": "2012-06-10 23:41:54", + "source": { + "type": "git", + "url": "http://github.com/kriswallsmith/assetic.git", + "reference": "d6f89a3170c5280ad554347dc113eb25fdf00ad7" + }, + "dist": { + "type": "zip", + "url": "https://github.com/kriswallsmith/assetic/zipball/d6f89a3170c5280ad554347dc113eb25fdf00ad7", + "reference": "d6f89a3170c5280ad554347dc113eb25fdf00ad7", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "symfony/process": "2.1.*" + }, + "require-dev": { + "twig/twig": ">=1.6.0,<2.0", + "leafo/lessphp": "*" + }, + "suggest": { + "twig/twig": "Assetic provides the integration with the Twig templating engine", + "leafo/lessphp": "Assetic provides the integration with the lessphp LESS compiler" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "installation-source": "source", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kris Wallsmith", + "email": "kris.wallsmith@gmail.com", + "homepage": "http://kriswallsmith.net/", + "role": null + } + ], + "description": "Asset Management for PHP", + "homepage": "https://github.com/kriswallsmith/assetic", + "keywords": [ + "assets", + "compression", + "minification" + ], + "autoload": { + "psr-0": { + "Assetic": "src/" + } + } + }, + { + "name": "doctrine/orm", + "version": "2.2.x-dev", + "version_normalized": "2.2.9999999.9999999-dev", + "time": "2012-05-26 01:13:46", + "source": { + "type": "git", + "url": "git://github.com/doctrine/doctrine2.git", + "reference": "5f66c65c9a8d984899903b54215d0249a45b92d6" + }, + "dist": { + "type": "zip", + "url": "https://github.com/doctrine/doctrine2/zipball/5f66c65c9a8d984899903b54215d0249a45b92d6", + "reference": "5f66c65c9a8d984899903b54215d0249a45b92d6", + "shasum": "" + }, + "require": { + "php": ">=5.3.2", + "ext-pdo": "*", + "doctrine/common": "2.2.*", + "doctrine/dbal": "2.2.*" + }, + "type": "library", + "installation-source": "source", + "license": [ + "LGPL" + ], + "authors": [ + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com", + "homepage": "http://www.jwage.com/", + "role": null + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com", + "homepage": null, + "role": null + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org", + "homepage": null, + "role": null + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de", + "homepage": null, + "role": null + } + ], + "description": "Object-Relational-Mapper for PHP", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "database", + "orm" + ], + "autoload": { + "psr-0": { + "Doctrine\\ORM": "lib/" + } + } + }, + { + "name": "doctrine/dbal", + "version": "2.2.x-dev", + "version_normalized": "2.2.9999999.9999999-dev", + "time": "2012-05-25 20:08:36", + "source": { + "type": "git", + "url": "https://github.com/doctrine/dbal", + "reference": "8cc129aa64a8de6447056bce20f0a274fe2a340b" + }, + "dist": { + "type": "zip", + "url": "https://github.com/doctrine/dbal/zipball/8cc129aa64a8de6447056bce20f0a274fe2a340b", + "reference": "8cc129aa64a8de6447056bce20f0a274fe2a340b", + "shasum": "" + }, + "require": { + "php": ">=5.3.2", + "doctrine/common": ">=2.2.0,<=2.2.99" + }, + "type": "library", + "installation-source": "source", + "license": [ + "LGPL" + ], + "authors": [ + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com", + "homepage": "http://www.jwage.com/", + "role": null + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com", + "homepage": null, + "role": null + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org", + "homepage": null, + "role": null + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de", + "homepage": null, + "role": null + } + ], + "description": "Database Abstraction Layer", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "database", + "persistence", + "dbal", + "queryobject" + ], + "autoload": { + "psr-0": { + "Doctrine\\DBAL": "lib/" + } + } + }, + { + "name": "twig/twig", + "version": "dev-master", + "version_normalized": "9999999-dev", + "time": "2012-06-16 08:52:23", + "source": { + "type": "git", + "url": "git://github.com/fabpot/Twig.git", + "reference": "4679ad51c5390648b7ea4c8f0ecd2c0c344145ba" + }, + "dist": { + "type": "zip", + "url": "https://github.com/fabpot/Twig/zipball/4679ad51c5390648b7ea4c8f0ecd2c0c344145ba", + "reference": "4679ad51c5390648b7ea4c8f0ecd2c0c344145ba", + "shasum": "" + }, + "require": { + "php": ">=5.2.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "installation-source": "source", + "license": [ + "BSD-3" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": null, + "role": null + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "homepage": null, + "role": null + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "http://twig.sensiolabs.org", + "keywords": [ + "templating" + ], + "autoload": { + "psr-0": { + "Twig_": "lib/" + } + } + }, + { + "name": "doctrine/doctrine-bundle", + "version": "dev-master", + "version_normalized": "9999999-dev", + "target-dir": "Doctrine/Bundle/DoctrineBundle", + "time": "2012-06-18 06:36:07", + "source": { + "type": "git", + "url": "git://github.com/doctrine/DoctrineBundle.git", + "reference": "94951737d6c692500d6b13bb92871935568a4ba5" + }, + "dist": { + "type": "zip", + "url": "https://github.com/doctrine/DoctrineBundle/zipball/94951737d6c692500d6b13bb92871935568a4ba5", + "reference": "94951737d6c692500d6b13bb92871935568a4ba5", + "shasum": "" + }, + "require": { + "php": ">=5.3.2", + "doctrine/dbal": ">=2.2,<2.4-dev", + "symfony/framework-bundle": "2.1.*", + "symfony/doctrine-bridge": "2.1.*" + }, + "require-dev": { + "doctrine/orm": ">=2.2,<2.4-dev", + "symfony/validator": "2.1.*", + "symfony/yaml": "2.1.*" + }, + "suggest": { + "doctrine/orm": "The Doctrine ORM integration is optional in the bundle." + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "source", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": null, + "role": null + }, + { + "name": "Symfony Community", + "email": null, + "homepage": "http://symfony.com/contributors", + "role": null + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de", + "homepage": null, + "role": null + } + ], + "description": "Symfony DoctrineBundle", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "database", + "orm", + "persistence", + "dbal" + ], + "autoload": { + "psr-0": { + "Doctrine\\Bundle\\DoctrineBundle": "" + } + } + }, + { + "name": "sensio/generator-bundle", + "version": "dev-master", + "version_normalized": "9999999-dev", + "target-dir": "Sensio/Bundle/GeneratorBundle", + "time": "2012-06-18 16:40:45", + "source": { + "type": "git", + "url": "https://github.com/sensio/SensioGeneratorBundle", + "reference": "43ed45c48db18e4a0e48aec0c098f42e56e22d36" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sensio/SensioGeneratorBundle/zipball/43ed45c48db18e4a0e48aec0c098f42e56e22d36", + "reference": "43ed45c48db18e4a0e48aec0c098f42e56e22d36", + "shasum": "" + }, + "require": { + "symfony/framework-bundle": "2.1.*" + }, + "require-dev": { + "symfony/doctrine-bridge": "2.1.*", + "doctrine/orm": ">=2.1,<2.4-dev", + "twig/twig": ">=1.8,<2.0-dev" + }, + "suggest": { + "doctrine/doctrine-bundle": "to generate entities and their crud controller" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "installation-source": "source", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": null, + "role": null + } + ], + "description": "This bundle generates code for you", + "autoload": { + "psr-0": { + "Sensio\\Bundle\\GeneratorBundle": "" + } + } + }, + { + "name": "sensio/framework-extra-bundle", + "version": "dev-master", + "version_normalized": "9999999-dev", + "target-dir": "Sensio/Bundle/FrameworkExtraBundle", + "time": "2012-06-18 10:41:18", + "source": { + "type": "git", + "url": "https://github.com/sensio/SensioFrameworkExtraBundle", + "reference": "62e41b85947034b0f1dfe31bb8e76920e1488571" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sensio/SensioFrameworkExtraBundle/zipball/62e41b85947034b0f1dfe31bb8e76920e1488571", + "reference": "62e41b85947034b0f1dfe31bb8e76920e1488571", + "shasum": "" + }, + "require": { + "doctrine/common": ">=2.1,<2.4-dev", + "symfony/framework-bundle": "2.1.*" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "installation-source": "source", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": null, + "role": null + } + ], + "description": "This bundle provides a way to configure your controllers with annotations", + "keywords": [ + "annotations", + "controllers" + ], + "autoload": { + "psr-0": { + "Sensio\\Bundle\\FrameworkExtraBundle": "" + } + } + }, + { + "name": "symfony/assetic-bundle", + "version": "dev-master", + "version_normalized": "9999999-dev", + "target-dir": "Symfony/Bundle/AsseticBundle", + "time": "2012-06-19 21:29:31", + "source": { + "type": "git", + "url": "https://github.com/symfony/AsseticBundle", + "reference": "8fe7b898b08103c1d6fce64c3e279a7afd61adfc" + }, + "dist": { + "type": "zip", + "url": "https://github.com/symfony/AsseticBundle/zipball/8fe7b898b08103c1d6fce64c3e279a7afd61adfc", + "reference": "8fe7b898b08103c1d6fce64c3e279a7afd61adfc", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "symfony/framework-bundle": "2.1.*", + "kriswallsmith/assetic": "1.1.*" + }, + "suggest": { + "symfony/twig-bundle": "2.1.*" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "installation-source": "source", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kris Wallsmith", + "email": "kris.wallsmith@gmail.com", + "homepage": "http://kriswallsmith.net/", + "role": null + } + ], + "description": "Integrates Assetic into Symfony2", + "homepage": "https://github.com/symfony/AsseticBundle", + "keywords": [ + "assets", + "compression", + "minification" + ], + "autoload": { + "psr-0": { + "Symfony\\Bundle\\AsseticBundle": "" + } + } + }, + { + "name": "symfony/swiftmailer-bundle", + "version": "dev-master", + "version_normalized": "9999999-dev", + "target-dir": "Symfony/Bundle/SwiftmailerBundle", + "time": "2012-06-18 20:25:44", + "source": { + "type": "git", + "url": "https://github.com/symfony/SwiftmailerBundle", + "reference": "d05c9c514a631ee688c53c4cc5505da757bd50d3" + }, + "dist": { + "type": "zip", + "url": "https://github.com/symfony/SwiftmailerBundle/zipball/d05c9c514a631ee688c53c4cc5505da757bd50d3", + "reference": "d05c9c514a631ee688c53c4cc5505da757bd50d3", + "shasum": "" + }, + "require": { + "php": ">=5.3.2", + "symfony/swiftmailer-bridge": "self.version", + "swiftmailer/swiftmailer": ">=4.1.8,<4.2-dev" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "installation-source": "source", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": null, + "role": null + }, + { + "name": "Symfony Community", + "email": null, + "homepage": "http://symfony.com/contributors", + "role": null + } + ], + "description": "Symfony SwiftmailerBundle", + "homepage": "http://symfony.com", + "autoload": { + "psr-0": { + "Symfony\\Bundle\\SwiftmailerBundle": "" + } + } + }, + { + "name": "swiftmailer/swiftmailer", + "version": "dev-master", + "version_normalized": "9999999-dev", + "time": "2012-06-20 14:46:20", + "source": { + "type": "git", + "url": "git://github.com/swiftmailer/swiftmailer.git", + "reference": "d57ffdeed664d6061cef0047e1f5d3fc3ee3fb99" + }, + "dist": { + "type": "zip", + "url": "https://github.com/swiftmailer/swiftmailer/zipball/d57ffdeed664d6061cef0047e1f5d3fc3ee3fb99", + "reference": "d57ffdeed664d6061cef0047e1f5d3fc3ee3fb99", + "shasum": "" + }, + "require": { + "php": ">=5.2.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "installation-source": "source", + "license": [ + "LGPL" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": null, + "role": null + }, + { + "name": "Chris Corbyn", + "email": "", + "homepage": null, + "role": null + } + ], + "description": "Swiftmailer, free feature-rich PHP mailer", + "homepage": "http://swiftmailer.org", + "keywords": [ + "mail", + "mailer" + ], + "autoload": { + "files": [ + "lib/swift_required.php" + ] + } + }, + { + "name": "symfony/symfony", + "version": "dev-master", + "version_normalized": "9999999-dev", + "time": "2012-06-21 09:42:20", + "source": { + "type": "git", + "url": "git://github.com/symfony/symfony.git", + "reference": "v2.1.0-BETA1" + }, + "dist": { + "type": "zip", + "url": "https://github.com/symfony/symfony/zipball/v2.1.0-BETA1", + "reference": "v2.1.0-BETA1", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "twig/twig": ">=1.8,<2.0-dev", + "doctrine/common": ">2.2,<2.4-dev" + }, + "replace": { + "symfony/doctrine-bridge": "self.version", + "symfony/monolog-bridge": "self.version", + "symfony/twig-bridge": "self.version", + "symfony/framework-bundle": "self.version", + "symfony/security-bundle": "self.version", + "symfony/twig-bundle": "self.version", + "symfony/web-profiler-bundle": "self.version", + "symfony/browser-kit": "self.version", + "symfony/class-loader": "self.version", + "symfony/config": "self.version", + "symfony/console": "self.version", + "symfony/css-selector": "self.version", + "symfony/dependency-injection": "self.version", + "symfony/dom-crawler": "self.version", + "symfony/event-dispatcher": "self.version", + "symfony/filesystem": "self.version", + "symfony/finder": "self.version", + "symfony/form": "self.version", + "symfony/http-foundation": "self.version", + "symfony/http-kernel": "self.version", + "symfony/locale": "self.version", + "symfony/process": "self.version", + "symfony/routing": "self.version", + "symfony/security": "self.version", + "symfony/serializer": "self.version", + "symfony/templating": "self.version", + "symfony/translation": "self.version", + "symfony/validator": "self.version", + "symfony/yaml": "self.version", + "symfony/propel1-bridge": "self.version", + "symfony/options-resolver": "self.version", + "symfony/swiftmailer-bridge": "self.version" + }, + "require-dev": { + "doctrine/data-fixtures": "1.0.*", + "propel/propel1": "dev-master", + "monolog/monolog": "dev-master", + "doctrine/dbal": ">=2.2,<2.4-dev", + "doctrine/orm": ">=2.2,<2.4-dev" + }, + "suggest": { + "doctrine/data-fixtures": "1.0.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "installation-source": "source", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": null, + "role": null + }, + { + "name": "Symfony Community", + "email": null, + "homepage": "http://symfony.com/contributors", + "role": null + } + ], + "description": "The Symfony PHP framework", + "homepage": "http://symfony.com", + "keywords": [ + "framework" + ], + "autoload": { + "psr-0": { + "Symfony": "src/", + "SessionHandlerInterface": "src/Symfony/Component/HttpFoundation/Resources/stubs" + } + } + }, + { + "name": "sensio/distribution-bundle", + "version": "dev-master", + "version_normalized": "9999999-dev", + "target-dir": "Sensio/Bundle/DistributionBundle", + "time": "2012-06-21 15:12:48", + "source": { + "type": "git", + "url": "https://github.com/sensio/SensioDistributionBundle", + "reference": "a360ad61fe34206a7295c1ef00b5455b2b2e1071" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sensio/SensioDistributionBundle/zipball/a360ad61fe34206a7295c1ef00b5455b2b2e1071", + "reference": "a360ad61fe34206a7295c1ef00b5455b2b2e1071", + "shasum": "" + }, + "require": { + "symfony/framework-bundle": "2.1.*" + }, + "type": "symfony-bundle", + "installation-source": "source", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": null, + "role": null + } + ], + "description": "The base bundle for the Symfony Distributions", + "keywords": [ + "distribution", + "configuration" + ], + "autoload": { + "psr-0": { + "Sensio\\Bundle\\DistributionBundle": "" + } + } + } +] diff --git a/vendor/composer/installed_dev.json b/vendor/composer/installed_dev.json new file mode 100644 index 0000000..3be7d3e --- /dev/null +++ b/vendor/composer/installed_dev.json @@ -0,0 +1,3 @@ +[ + + ] diff --git a/vendor/doctrine/common/.travis.yml b/vendor/doctrine/common/.travis.yml new file mode 100644 index 0000000..4464d4f --- /dev/null +++ b/vendor/doctrine/common/.travis.yml @@ -0,0 +1,5 @@ +language: php + +php: + - 5.3 + - 5.4 diff --git a/vendor/doctrine/common/LICENSE b/vendor/doctrine/common/LICENSE new file mode 100644 index 0000000..1c03f74 --- /dev/null +++ b/vendor/doctrine/common/LICENSE @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/vendor/doctrine/common/README.md b/vendor/doctrine/common/README.md new file mode 100644 index 0000000..c63f762 --- /dev/null +++ b/vendor/doctrine/common/README.md @@ -0,0 +1,12 @@ +# Doctrine Common + +[![Build Status](https://secure.travis-ci.org/doctrine/common.png)](http://travis-ci.org/doctrine/common) + +The Doctrine Common project is a library that provides extensions to core PHP functionality. + +## More resources: + +* [Website](http://www.doctrine-project.org) +* [Documentation](http://www.doctrine-project.org/projects/common/current/docs/en) +* [Issue Tracker](http://www.doctrine-project.org/jira/browse/DCOM) +* [Downloads](http://github.com/doctrine/common/downloads) diff --git a/vendor/doctrine/common/UPGRADE_TO_2_1 b/vendor/doctrine/common/UPGRADE_TO_2_1 new file mode 100644 index 0000000..891a2e5 --- /dev/null +++ b/vendor/doctrine/common/UPGRADE_TO_2_1 @@ -0,0 +1,39 @@ +This document details all the possible changes that you should investigate when updating +your project from Doctrine Common 2.0.x to 2.1 + +## AnnotationReader changes + +The annotation reader was heavily refactored between 2.0 and 2.1-RC1. In theory the operation of the new reader should be backwards compatible, but it has to be setup differently to work that way: + + $reader = new \Doctrine\Common\Annotations\AnnotationReader(); + $reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\'); + // new code necessary starting here + $reader->setIgnoreNotImportedAnnotations(true); + $reader->setEnableParsePhpImports(false); + $reader = new \Doctrine\Common\Annotations\CachedReader( + new \Doctrine\Common\Annotations\IndexedReader($reader), new ArrayCache() + ); + +## Annotation Base class or @Annotation + +Beginning after 2.1-RC2 you have to either extend ``Doctrine\Common\Annotations\Annotation`` or add @Annotation to your annotations class-level docblock, otherwise the class will simply be ignored. + +## Removed methods on AnnotationReader + +* AnnotationReader::setAutoloadAnnotations() +* AnnotationReader::getAutoloadAnnotations() +* AnnotationReader::isAutoloadAnnotations() + +## AnnotationRegistry + +Autoloading through the PHP autoloader is removed from the 2.1 AnnotationReader. Instead you have to use the global AnnotationRegistry for loading purposes: + + \Doctrine\Common\Annotations\AnnotationRegistry::registerFile($fileWithAnnotations); + \Doctrine\Common\Annotations\AnnotationRegistry::registerAutoloadNamespace($namespace, $dirs = null); + \Doctrine\Common\Annotations\AnnotationRegistry::registerAutoloadNamespaces($namespaces); + \Doctrine\Common\Annotations\AnnotationRegistry::registerLoader($callable); + +The $callable for registering a loader accepts a class as first and only parameter and must try to silently autoload it. On success true has to be returned. +The registerAutoloadNamespace function registers a PSR-0 compatible silent autoloader for all classes with the given namespace in the given directories. +If null is passed as directory the include path will be used. + diff --git a/vendor/doctrine/common/UPGRADE_TO_2_2 b/vendor/doctrine/common/UPGRADE_TO_2_2 new file mode 100644 index 0000000..1d93a13 --- /dev/null +++ b/vendor/doctrine/common/UPGRADE_TO_2_2 @@ -0,0 +1,61 @@ +This document details all the possible changes that you should investigate when +updating your project from Doctrine Common 2.1 to 2.2: + +## Annotation Changes + +- AnnotationReader::setIgnoreNotImportedAnnotations has been removed, you need to + add ignore annotation names which are supposed to be ignored via + AnnotationReader::addGlobalIgnoredName + +- AnnotationReader::setAutoloadAnnotations was deprecated by the AnnotationRegistry + in 2.1 and has been removed in 2.2 + +- AnnotationReader::setEnableParsePhpImports was added to ease transition to the new + annotation mechanism in 2.1 and is removed in 2.2 + +- AnnotationReader::isParsePhpImportsEnabled is removed (see above) + +- AnnotationReader::setDefaultAnnotationNamespace was deprecated in favor of explicit + configuration in 2.1 and will be removed in 2.2 (for isolated projects where you + have full-control over _all_ available annotations, we offer a dedicated reader + class ``SimpleAnnotationReader``) + +- AnnotationReader::setAnnotationCreationFunction was deprecated in 2.1 and will be + removed in 2.2. We only offer two creation mechanisms which cannot be changed + anymore to allow the same reader instance to work with all annotations regardless + of which library they are coming from. + +- AnnotationReader::setAnnotationNamespaceAlias was deprecated in 2.1 and will be + removed in 2.2 (see setDefaultAnnotationNamespace) + +- If you use a class as annotation which has not the @Annotation marker in it's + class block, we will now throw an exception instead of silently ignoring it. You + can however still achieve the previous behavior using the @IgnoreAnnotation, or + AnnotationReader::addGlobalIgnoredName (the exception message will contain detailed + instructions when you run into this problem). + +## Cache Changes + +- Renamed old AbstractCache to CacheProvider + +- Dropped the support to the following functions of all cache providers: + + - CacheProvider::deleteByWildcard + + - CacheProvider::deleteByRegEx + + - CacheProvider::deleteByPrefix + + - CacheProvider::deleteBySuffix + +- CacheProvider::deleteAll will not remove ALL entries, it will only mark them as invalid + +- CacheProvider::flushAll will remove ALL entries, namespaced or not + +- Added support to MemcachedCache + +- Added support to WincacheCache + +## ClassLoader Changes + +- ClassLoader::fileExistsInIncludePath() no longer exists. Use the native stream_resolve_include_path() PHP function \ No newline at end of file diff --git a/vendor/doctrine/common/composer.json b/vendor/doctrine/common/composer.json new file mode 100644 index 0000000..7780d93 --- /dev/null +++ b/vendor/doctrine/common/composer.json @@ -0,0 +1,21 @@ +{ + "name": "doctrine/common", + "type": "library","version":"2.2.2", + "description": "Common Library for Doctrine projects", + "keywords": ["collections", "spl", "eventmanager", "annotations", "persistence"], + "homepage": "http://www.doctrine-project.org", + "license": "LGPL", + "authors": [ + {"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"}, + {"name": "Roman Borschel", "email": "roman@code-factory.org"}, + {"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"}, + {"name": "Jonathan Wage", "email": "jonwage@gmail.com"}, + {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"} + ], + "require": { + "php": ">=5.3.2" + }, + "autoload": { + "psr-0": { "Doctrine\\Common": "lib/" } + } +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation.php b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation.php new file mode 100644 index 0000000..6251252 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation.php @@ -0,0 +1,75 @@ +. + */ + +namespace Doctrine\Common\Annotations; + +/** + * Annotations class + * + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class Annotation +{ + /** + * Value property. Common among all derived classes. + * + * @var string + */ + public $value; + + /** + * Constructor + * + * @param array $data Key-value for properties to be defined in this class + */ + public final function __construct(array $data) + { + foreach ($data as $key => $value) { + $this->$key = $value; + } + } + + /** + * Error handler for unknown property accessor in Annotation class. + * + * @param string $name Unknown property name + */ + public function __get($name) + { + throw new \BadMethodCallException( + sprintf("Unknown property '%s' on annotation '%s'.", $name, get_class($this)) + ); + } + + /** + * Error handler for unknown property mutator in Annotation class. + * + * @param string $name Unkown property name + * @param mixed $value Property value + */ + public function __set($name, $value) + { + throw new \BadMethodCallException( + sprintf("Unknown property '%s' on annotation '%s'.", $name, get_class($this)) + ); + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation/Attribute.php b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation/Attribute.php new file mode 100644 index 0000000..21597b1 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation/Attribute.php @@ -0,0 +1,47 @@ +. + */ + +namespace Doctrine\Common\Annotations\Annotation; + +/** + * Annotation that can be used to signal to the parser + * to check the attribute type during the parsing process. + * + * @author Fabio B. Silva + * + * @Annotation + */ +final class Attribute +{ + /** + * @var string + */ + public $name; + + /** + * @var string + */ + public $type; + + /** + * @var boolean + */ + public $required = false; +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation/Attributes.php b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation/Attributes.php new file mode 100644 index 0000000..6e314be --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation/Attributes.php @@ -0,0 +1,37 @@ +. + */ + +namespace Doctrine\Common\Annotations\Annotation; + +/** + * Annotation that can be used to signal to the parser + * to check the types of all declared attributes during the parsing process. + * + * @author Fabio B. Silva + * + * @Annotation + */ +final class Attributes +{ + /** + * @var array + */ + public $value; +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php new file mode 100644 index 0000000..1b2b20a --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php @@ -0,0 +1,44 @@ +. + */ + +namespace Doctrine\Common\Annotations\Annotation; + +/** + * Annotation that can be used to signal to the parser to ignore specific + * annotations during the parsing process. + * + * @Annotation + * @author Johannes M. Schmitt + */ +final class IgnoreAnnotation +{ + public $names; + + public function __construct(array $values) + { + if (is_string($values['value'])) { + $values['value'] = array($values['value']); + } + if (!is_array($values['value'])) { + throw new \RuntimeException(sprintf('@IgnoreAnnotation expects either a string name, or an array of strings, but got %s.', json_encode($values['value']))); + } + + $this->names = $values['value']; + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation/Required.php b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation/Required.php new file mode 100644 index 0000000..7b89a02 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation/Required.php @@ -0,0 +1,33 @@ +. + */ + +namespace Doctrine\Common\Annotations\Annotation; + +/** + * Annotation that can be used to signal to the parser + * to check if that attribute is required during the parsing process. + * + * @author Fabio B. Silva + * + * @Annotation + */ +final class Required +{ +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation/Target.php b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation/Target.php new file mode 100644 index 0000000..c41896a --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/Annotation/Target.php @@ -0,0 +1,105 @@ +. + */ + +namespace Doctrine\Common\Annotations\Annotation; + +/** + * Annotation that can be used to signal to the parser + * to check the annotation target during the parsing process. + * + * @author Fabio B. Silva + * + * @Annotation + */ +final class Target +{ + const TARGET_CLASS = 1; + const TARGET_METHOD = 2; + const TARGET_PROPERTY = 4; + const TARGET_ANNOTATION = 8; + const TARGET_ALL = 15; + + /** + * @var array + */ + private static $map = array( + 'ALL' => self::TARGET_ALL, + 'CLASS' => self::TARGET_CLASS, + 'METHOD' => self::TARGET_METHOD, + 'PROPERTY' => self::TARGET_PROPERTY, + 'ANNOTATION' => self::TARGET_ANNOTATION, + ); + + /** + * @var array + */ + public $value; + + /** + * Targets as bitmask. + * + * @var integer + */ + public $targets; + + /** + * Literal target declaration. + * + * @var integer + */ + public $literal; + + /** + * Annotation construct + * + * @param array $values + */ + public function __construct(array $values) + { + if (!isset($values['value'])){ + $values['value'] = null; + } + if (is_string($values['value'])){ + $values['value'] = array($values['value']); + } + if (!is_array($values['value'])){ + throw new \InvalidArgumentException( + sprintf('@Target expects either a string value, or an array of strings, "%s" given.', + is_object($values['value']) ? get_class($values['value']) : gettype($values['value']) + ) + ); + } + + $bitmask = 0; + foreach ($values['value'] as $literal) { + if(!isset(self::$map[$literal])){ + throw new \InvalidArgumentException( + sprintf('Invalid Target "%s". Available targets: [%s]', + $literal, implode(', ', array_keys(self::$map))) + ); + } + $bitmask += self::$map[$literal]; + } + + $this->targets = $bitmask; + $this->value = $values['value']; + $this->literal = implode(', ', $this->value); + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Annotations/AnnotationException.php b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/AnnotationException.php new file mode 100644 index 0000000..fdc1913 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/AnnotationException.php @@ -0,0 +1,111 @@ +. + */ + +namespace Doctrine\Common\Annotations; + +/** + * Description of AnnotationException + * + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class AnnotationException extends \Exception +{ + /** + * Creates a new AnnotationException describing a Syntax error. + * + * @param string $message Exception message + * @return AnnotationException + */ + public static function syntaxError($message) + { + return new self('[Syntax Error] ' . $message); + } + + /** + * Creates a new AnnotationException describing a Semantical error. + * + * @param string $message Exception message + * @return AnnotationException + */ + public static function semanticalError($message) + { + return new self('[Semantical Error] ' . $message); + } + + /** + * Creates a new AnnotationException describing an error which occurred during + * the creation of the annotation. + * + * @since 2.2 + * @param string $message + * @return AnnotationException + */ + public static function creationError($message) + { + return new self('[Creation Error] ' . $message); + } + + /** + * Creates a new AnnotationException describing an type error of an attribute. + * + * @since 2.2 + * @param string $attributeName + * @param string $annotationName + * @param string $context + * @param string $expected + * @param mixed $actual + * @return AnnotationException + */ + public static function typeError($attributeName, $annotationName, $context, $expected, $actual) + { + return new self(sprintf( + '[Type Error] Attribute "%s" of @%s declared on %s expects %s, but got %s.', + $attributeName, + $annotationName, + $context, + $expected, + is_object($actual) ? 'an instance of '.get_class($actual) : gettype($actual) + )); + } + + /** + * Creates a new AnnotationException describing an required error of an attribute. + * + * @since 2.2 + * @param string $attributeName + * @param string $annotationName + * @param string $context + * @param string $expected + * @return AnnotationException + */ + public static function requiredError($attributeName, $annotationName, $context, $expected) + { + return new self(sprintf( + '[Type Error] Attribute "%s" of @%s declared on %s expects %s. This value should not be null.', + $attributeName, + $annotationName, + $context, + $expected + )); + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Annotations/AnnotationReader.php b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/AnnotationReader.php new file mode 100644 index 0000000..dda8b23 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/AnnotationReader.php @@ -0,0 +1,301 @@ +. + */ + +namespace Doctrine\Common\Annotations; + +use Doctrine\Common\Annotations\Annotation\IgnoreAnnotation; +use Doctrine\Common\Annotations\Annotation\Target; +use Closure; +use ReflectionClass; +use ReflectionMethod; +use ReflectionProperty; + +/** + * A reader for docblock annotations. + * + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Johannes M. Schmitt + */ +final class AnnotationReader implements Reader +{ + /** + * Global map for imports. + * + * @var array + */ + private static $globalImports = array( + 'ignoreannotation' => 'Doctrine\Common\Annotations\Annotation\IgnoreAnnotation', + ); + + /** + * A list with annotations that are not causing exceptions when not resolved to an annotation class. + * + * The names are case sensitive. + * + * @var array + */ + private static $globalIgnoredNames = array( + 'access'=> true, 'author'=> true, 'copyright'=> true, 'deprecated'=> true, + 'example'=> true, 'ignore'=> true, 'internal'=> true, 'link'=> true, 'see'=> true, + 'since'=> true, 'tutorial'=> true, 'version'=> true, 'package'=> true, + 'subpackage'=> true, 'name'=> true, 'global'=> true, 'param'=> true, + 'return'=> true, 'staticvar'=> true, 'category'=> true, 'staticVar'=> true, + 'static'=> true, 'var'=> true, 'throws'=> true, 'inheritdoc'=> true, + 'inheritDoc'=> true, 'license'=> true, 'todo'=> true, 'deprecated'=> true, + 'deprec'=> true, 'author'=> true, 'property' => true, 'method' => true, + 'abstract'=> true, 'exception'=> true, 'magic' => true, 'api' => true, + 'final'=> true, 'filesource'=> true, 'throw' => true, 'uses' => true, + 'usedby'=> true, 'private' => true, 'Annotation' => true, 'override' => true, + 'codeCoverageIgnore' => true, 'codeCoverageIgnoreStart' => true, 'codeCoverageIgnoreEnd' => true, + 'Required' => true, 'Attribute' => true, 'Attributes' => true, + 'Target' => true, 'SuppressWarnings' => true, + ); + + /** + * Add a new annotation to the globally ignored annotation names with regard to exception handling. + * + * @param string $name + */ + static public function addGlobalIgnoredName($name) + { + self::$globalIgnoredNames[$name] = true; + } + + /** + * Annotations Parser + * + * @var Doctrine\Common\Annotations\DocParser + */ + private $parser; + + /** + * Annotations Parser used to collect parsing metadata + * + * @var Doctrine\Common\Annotations\DocParser + */ + private $preParser; + + /** + * PHP Parser used to collect imports. + * + * @var Doctrine\Common\Annotations\PhpParser + */ + private $phpParser; + + /** + * In-memory cache mechanism to store imported annotations per class. + * + * @var array + */ + private $imports = array(); + + /** + * In-memory cache mechanism to store ignored annotations per class. + * + * @var array + */ + private $ignoredAnnotationNames = array(); + + /** + * Constructor. + * + * Initializes a new AnnotationReader. + */ + public function __construct() + { + AnnotationRegistry::registerFile(__DIR__ . '/Annotation/IgnoreAnnotation.php'); + + $this->parser = new DocParser; + + $this->preParser = new DocParser; + $this->preParser->setImports(self::$globalImports); + $this->preParser->setIgnoreNotImportedAnnotations(true); + + $this->phpParser = new PhpParser; + } + + /** + * Gets the annotations applied to a class. + * + * @param ReflectionClass $class The ReflectionClass of the class from which + * the class annotations should be read. + * @return array An array of Annotations. + */ + public function getClassAnnotations(ReflectionClass $class) + { + $this->parser->setTarget(Target::TARGET_CLASS); + $this->parser->setImports($this->getImports($class)); + $this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class)); + + return $this->parser->parse($class->getDocComment(), 'class ' . $class->getName()); + } + + /** + * Gets a class annotation. + * + * @param ReflectionClass $class The ReflectionClass of the class from which + * the class annotations should be read. + * @param string $annotationName The name of the annotation. + * @return The Annotation or NULL, if the requested annotation does not exist. + */ + public function getClassAnnotation(ReflectionClass $class, $annotationName) + { + $annotations = $this->getClassAnnotations($class); + + foreach ($annotations as $annotation) { + if ($annotation instanceof $annotationName) { + return $annotation; + } + } + + return null; + } + + /** + * Gets the annotations applied to a property. + * + * @param ReflectionProperty $property The ReflectionProperty of the property + * from which the annotations should be read. + * @return array An array of Annotations. + */ + public function getPropertyAnnotations(ReflectionProperty $property) + { + $class = $property->getDeclaringClass(); + $context = 'property ' . $class->getName() . "::\$" . $property->getName(); + $this->parser->setTarget(Target::TARGET_PROPERTY); + $this->parser->setImports($this->getImports($class)); + $this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class)); + + return $this->parser->parse($property->getDocComment(), $context); + } + + /** + * Gets a property annotation. + * + * @param ReflectionProperty $property + * @param string $annotationName The name of the annotation. + * @return The Annotation or NULL, if the requested annotation does not exist. + */ + public function getPropertyAnnotation(ReflectionProperty $property, $annotationName) + { + $annotations = $this->getPropertyAnnotations($property); + + foreach ($annotations as $annotation) { + if ($annotation instanceof $annotationName) { + return $annotation; + } + } + + return null; + } + + /** + * Gets the annotations applied to a method. + * + * @param ReflectionMethod $property The ReflectionMethod of the method from which + * the annotations should be read. + * @return array An array of Annotations. + */ + public function getMethodAnnotations(ReflectionMethod $method) + { + $class = $method->getDeclaringClass(); + $context = 'method ' . $class->getName() . '::' . $method->getName() . '()'; + $this->parser->setTarget(Target::TARGET_METHOD); + $this->parser->setImports($this->getImports($class)); + $this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class)); + + return $this->parser->parse($method->getDocComment(), $context); + } + + /** + * Gets a method annotation. + * + * @param ReflectionMethod $method + * @param string $annotationName The name of the annotation. + * @return The Annotation or NULL, if the requested annotation does not exist. + */ + public function getMethodAnnotation(ReflectionMethod $method, $annotationName) + { + $annotations = $this->getMethodAnnotations($method); + + foreach ($annotations as $annotation) { + if ($annotation instanceof $annotationName) { + return $annotation; + } + } + + return null; + } + + /** + * Returns the ignored annotations for the given class. + * + * @param ReflectionClass $class + * @return array + */ + private function getIgnoredAnnotationNames(ReflectionClass $class) + { + if (isset($this->ignoredAnnotationNames[$name = $class->getName()])) { + return $this->ignoredAnnotationNames[$name]; + } + $this->collectParsingMetadata($class); + + return $this->ignoredAnnotationNames[$name]; + } + + private function getImports(ReflectionClass $class) + { + if (isset($this->imports[$name = $class->getName()])) { + return $this->imports[$name]; + } + $this->collectParsingMetadata($class); + + return $this->imports[$name]; + } + + /** + * Collects parsing metadata for a given class + * + * @param ReflectionClass $class + */ + private function collectParsingMetadata(ReflectionClass $class) + { + $ignoredAnnotationNames = self::$globalIgnoredNames; + + $annotations = $this->preParser->parse($class->getDocComment(), 'class '.$class->name); + foreach ($annotations as $annotation) { + if ($annotation instanceof IgnoreAnnotation) { + foreach ($annotation->names AS $annot) { + $ignoredAnnotationNames[$annot] = true; + } + } + } + + $name = $class->getName(); + $this->imports[$name] = array_merge( + self::$globalImports, + $this->phpParser->parseClass($class), + array('__NAMESPACE__' => $class->getNamespaceName()) + ); + $this->ignoredAnnotationNames[$name] = $ignoredAnnotationNames; + } +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Annotations/AnnotationRegistry.php b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/AnnotationRegistry.php new file mode 100644 index 0000000..60b00f5 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/AnnotationRegistry.php @@ -0,0 +1,129 @@ +. + */ + +namespace Doctrine\Common\Annotations; + +final class AnnotationRegistry +{ + /** + * A map of namespaces to use for autoloading purposes based on a PSR-0 convention. + * + * Contains the namespace as key and an array of directories as value. If the value is NULL + * the include path is used for checking for the corresponding file. + * + * This autoloading mechanism does not utilize the PHP autoloading but implements autoloading on its own. + * + * @var array + */ + static private $autoloadNamespaces = array(); + + /** + * A map of autoloader callables. + * + * @var array + */ + static private $loaders = array(); + + static public function reset() + { + self::$autoloadNamespaces = array(); + self::$loaders = array(); + } + + static public function registerFile($file) + { + require_once $file; + } + + /** + * Add a namespace with one or many directories to look for files or null for the include path. + * + * Loading of this namespaces will be done with a PSR-0 namespace loading algorithm. + * + * @param string $namespace + * @param string|array|null $dirs + */ + static public function registerAutoloadNamespace($namespace, $dirs = null) + { + self::$autoloadNamespaces[$namespace] = $dirs; + } + + /** + * Register multiple namespaces + * + * Loading of this namespaces will be done with a PSR-0 namespace loading algorithm. + * + * @param array $namespaces + */ + static public function registerAutoloadNamespaces(array $namespaces) + { + self::$autoloadNamespaces = array_merge(self::$autoloadNamespaces, $namespaces); + } + + /** + * Register an autoloading callabale for annotations, much like spl_autoload_register(). + * + * NOTE: These class loaders HAVE to be silent when a class was not found! + * IMPORTANT: Loaders have to return true if they loaded a class that could contain the searched annotation class. + * + * @param callabale $callabale + */ + static public function registerLoader($callabale) + { + if (!is_callable($callabale)) { + throw new \InvalidArgumentException("A callable is expected in AnnotationRegistry::registerLoader()."); + } + self::$loaders[] = $callabale; + } + + /** + * Autoload an annotation class silently. + * + * @param string $class + * @return void + */ + static public function loadAnnotationClass($class) + { + foreach (self::$autoloadNamespaces AS $namespace => $dirs) { + if (strpos($class, $namespace) === 0) { + $file = str_replace("\\", DIRECTORY_SEPARATOR, $class) . ".php"; + if ($dirs === null) { + if ($path = stream_resolve_include_path($file)) { + require $path; + return true; + } + } else { + foreach((array)$dirs AS $dir) { + if (file_exists($dir . DIRECTORY_SEPARATOR . $file)) { + require $dir . DIRECTORY_SEPARATOR . $file; + return true; + } + } + } + } + } + + foreach (self::$loaders AS $loader) { + if (call_user_func($loader, $class) === true) { + return true; + } + } + return false; + } +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Annotations/CachedReader.php b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/CachedReader.php new file mode 100644 index 0000000..6ea47c6 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/CachedReader.php @@ -0,0 +1,179 @@ +. + */ + +namespace Doctrine\Common\Annotations; + +use Doctrine\Common\Cache\Cache; + +/** + * A cache aware annotation reader. + * + * @author Johannes M. Schmitt + * @author Benjamin Eberlei + */ +final class CachedReader implements Reader +{ + private static $CACHE_SALT = '@[Annot]'; + + /** + * @var Reader + */ + private $delegate; + + /** + * @var Cache + */ + private $cache; + + /** + * @var boolean + */ + private $debug; + + /** + * @var array + */ + private $loadedAnnotations; + + /** + * @param Reader $reader + * @param Cache $cache + */ + public function __construct(Reader $reader, Cache $cache, $debug = false) + { + $this->delegate = $reader; + $this->cache = $cache; + $this->debug = $debug; + } + + public function getClassAnnotations(\ReflectionClass $class) + { + $cacheKey = $class->getName() . self::$CACHE_SALT; + + if (isset($this->loadedAnnotations[$cacheKey])) { + return $this->loadedAnnotations[$cacheKey]; + } + + // Attempt to grab data from cache + if (($data = $this->cache->fetch($cacheKey)) !== false) { + if (!$this->debug || $this->isCacheFresh($cacheKey, $class)) { + return $data; + } + } + + $annots = $this->delegate->getClassAnnotations($class); + $this->cache->save($cacheKey, $annots); + $this->cache->save('[C]'.$cacheKey, time()); + + return $this->loadedAnnotations[$cacheKey] = $annots; + } + + public function getClassAnnotation(\ReflectionClass $class, $annotationName) + { + foreach ($this->getClassAnnotations($class) as $annot) { + if ($annot instanceof $annotationName) { + return $annot; + } + } + + return null; + } + + public function getPropertyAnnotations(\ReflectionProperty $property) + { + $class = $property->getDeclaringClass(); + $cacheKey = $class->getName().'$'.$property->getName().self::$CACHE_SALT; + + if (isset($this->loadedAnnotations[$cacheKey])) { + return $this->loadedAnnotations[$cacheKey]; + } + + // Attempt to grab data from cache + if (($data = $this->cache->fetch($cacheKey)) !== false) { + if (!$this->debug || $this->isCacheFresh($cacheKey, $class)) { + return $data; + } + } + + $annots = $this->delegate->getPropertyAnnotations($property); + $this->cache->save($cacheKey, $annots); + $this->cache->save('[C]'.$cacheKey, time()); + + return $this->loadedAnnotations[$cacheKey] = $annots; + } + + public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName) + { + foreach ($this->getPropertyAnnotations($property) as $annot) { + if ($annot instanceof $annotationName) { + return $annot; + } + } + + return null; + } + + public function getMethodAnnotations(\ReflectionMethod $method) + { + $class = $method->getDeclaringClass(); + $cacheKey = $class->getName().'#'.$method->getName().self::$CACHE_SALT; + + if (isset($this->loadedAnnotations[$cacheKey])) { + return $this->loadedAnnotations[$cacheKey]; + } + + // Attempt to grab data from cache + if (($data = $this->cache->fetch($cacheKey)) !== false) { + if (!$this->debug || $this->isCacheFresh($cacheKey, $class)) { + return $data; + } + } + + $annots = $this->delegate->getMethodAnnotations($method); + $this->cache->save($cacheKey, $annots); + $this->cache->save('[C]'.$cacheKey, time()); + + return $this->loadedAnnotations[$cacheKey] = $annots; + } + + public function getMethodAnnotation(\ReflectionMethod $method, $annotationName) + { + foreach ($this->getMethodAnnotations($method) as $annot) { + if ($annot instanceof $annotationName) { + return $annot; + } + } + + return null; + } + + public function clearLoadedAnnotations() + { + $this->loadedAnnotations = array(); + } + + private function isCacheFresh($cacheKey, \ReflectionClass $class) + { + if (false === $filename = $class->getFilename()) { + return true; + } + + return $this->cache->fetch('[C]'.$cacheKey) >= filemtime($filename); + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Annotations/DocLexer.php b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/DocLexer.php new file mode 100644 index 0000000..c6223e3 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/DocLexer.php @@ -0,0 +1,140 @@ +. + */ + +namespace Doctrine\Common\Annotations; + +use Doctrine\Common\Lexer; + +/** + * Simple lexer for docblock annotations. + * + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Johannes M. Schmitt + */ +final class DocLexer extends Lexer +{ + const T_NONE = 1; + const T_IDENTIFIER = 2; + const T_INTEGER = 3; + const T_STRING = 4; + const T_FLOAT = 5; + + const T_AT = 101; + const T_CLOSE_CURLY_BRACES = 102; + const T_CLOSE_PARENTHESIS = 103; + const T_COMMA = 104; + const T_EQUALS = 105; + const T_FALSE = 106; + const T_NAMESPACE_SEPARATOR = 107; + const T_OPEN_CURLY_BRACES = 108; + const T_OPEN_PARENTHESIS = 109; + const T_TRUE = 110; + const T_NULL = 111; + const T_COLON = 112; + + /** + * @inheritdoc + */ + protected function getCatchablePatterns() + { + return array( + '[a-z_][a-z0-9_:]*', + '(?:[+-]?[0-9]+(?:[\.][0-9]+)*)(?:[eE][+-]?[0-9]+)?', + '"(?:[^"]|"")*"', + ); + } + + /** + * @inheritdoc + */ + protected function getNonCatchablePatterns() + { + return array('\s+', '\*+', '(.)'); + } + + /** + * @inheritdoc + */ + protected function getType(&$value) + { + $type = self::T_NONE; + + // Checking numeric value + if (is_numeric($value)) { + return (strpos($value, '.') !== false || stripos($value, 'e') !== false) + ? self::T_FLOAT : self::T_INTEGER; + } + + if ($value[0] === '"') { + $value = str_replace('""', '"', substr($value, 1, strlen($value) - 2)); + + return self::T_STRING; + } else { + switch (strtolower($value)) { + case '@': + return self::T_AT; + + case ',': + return self::T_COMMA; + + case '(': + return self::T_OPEN_PARENTHESIS; + + case ')': + return self::T_CLOSE_PARENTHESIS; + + case '{': + return self::T_OPEN_CURLY_BRACES; + + case '}': + return self::T_CLOSE_CURLY_BRACES; + + case '=': + return self::T_EQUALS; + + case '\\': + return self::T_NAMESPACE_SEPARATOR; + + case 'true': + return self::T_TRUE; + + case 'false': + return self::T_FALSE; + + case 'null': + return self::T_NULL; + + case ':': + return self::T_COLON; + + default: + if (ctype_alpha($value[0]) || $value[0] === '_') { + return self::T_IDENTIFIER; + } + + break; + } + } + + return $type; + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Annotations/DocParser.php b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/DocParser.php new file mode 100644 index 0000000..9d16b17 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/DocParser.php @@ -0,0 +1,891 @@ +. + */ + +namespace Doctrine\Common\Annotations; + +use Closure; +use ReflectionClass; +use Doctrine\Common\Annotations\Annotation\Target; +use Doctrine\Common\Annotations\Annotation\Attribute; +use Doctrine\Common\Annotations\Annotation\Attributes; + +/** + * A parser for docblock annotations. + * + * It is strongly discouraged to change the default annotation parsing process. + * + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Johannes M. Schmitt + * @author Fabio B. Silva + */ +final class DocParser +{ + /** + * An array of all valid tokens for a class name. + * + * @var array + */ + private static $classIdentifiers = array(DocLexer::T_IDENTIFIER, DocLexer::T_TRUE, DocLexer::T_FALSE, DocLexer::T_NULL); + + /** + * The lexer. + * + * @var Doctrine\Common\Annotations\DocLexer + */ + private $lexer; + + /** + * Current target context + * + * @var string + */ + private $target; + + /** + * Doc Parser used to collect annotation target + * + * @var Doctrine\Common\Annotations\DocParser + */ + private static $metadataParser; + + /** + * Flag to control if the current annotation is nested or not. + * + * @var boolean + */ + private $isNestedAnnotation = false; + + /** + * Hashmap containing all use-statements that are to be used when parsing + * the given doc block. + * + * @var array + */ + private $imports = array(); + + /** + * This hashmap is used internally to cache results of class_exists() + * look-ups. + * + * @var array + */ + private $classExists = array(); + + /** + * Whether annotations that have not been imported should be ignored. + * + * @var boolean + */ + private $ignoreNotImportedAnnotations = false; + + /** + * An array of default namespaces if operating in simple mode. + * + * @var array + */ + private $namespaces = array(); + + /** + * A list with annotations that are not causing exceptions when not resolved to an annotation class. + * + * The names must be the raw names as used in the class, not the fully qualified + * class names. + * + * @var array + */ + private $ignoredAnnotationNames = array(); + + /** + * @var string + */ + private $context = ''; + + /** + * Hash-map for caching annotation metadata + * @var array + */ + private static $annotationMetadata = array( + 'Doctrine\Common\Annotations\Annotation\Target' => array( + 'is_annotation' => true, + 'has_constructor' => true, + 'properties' => array(), + 'targets_literal' => 'ANNOTATION_CLASS', + 'targets' => Target::TARGET_CLASS, + 'default_property' => 'value', + 'attribute_types' => array( + 'value' => array( + 'required' => false, + 'type' =>'array', + 'array_type'=>'string', + 'value' =>'array' + ) + ), + ), + 'Doctrine\Common\Annotations\Annotation\Attribute' => array( + 'is_annotation' => true, + 'has_constructor' => false, + 'targets_literal' => 'ANNOTATION_ANNOTATION', + 'targets' => Target::TARGET_ANNOTATION, + 'default_property' => 'name', + 'properties' => array( + 'name' => 'name', + 'type' => 'type', + 'required' => 'required' + ), + 'attribute_types' => array( + 'value' => array( + 'required' => true, + 'type' =>'string', + 'value' =>'string' + ), + 'type' => array( + 'required' =>true, + 'type' =>'string', + 'value' =>'string' + ), + 'required' => array( + 'required' =>false, + 'type' =>'boolean', + 'value' =>'boolean' + ) + ), + ), + 'Doctrine\Common\Annotations\Annotation\Attributes' => array( + 'is_annotation' => true, + 'has_constructor' => false, + 'targets_literal' => 'ANNOTATION_CLASS', + 'targets' => Target::TARGET_CLASS, + 'default_property' => 'value', + 'properties' => array( + 'value' => 'value' + ), + 'attribute_types' => array( + 'value' => array( + 'type' =>'array', + 'required' =>true, + 'array_type'=>'Doctrine\Common\Annotations\Annotation\Attribute', + 'value' =>'array' + ) + ), + ), + ); + + /** + * Hash-map for handle types declaration + * + * @var array + */ + private static $typeMap = array( + 'float' => 'double', + 'bool' => 'boolean', + // allow uppercase Boolean in honor of George Boole + 'Boolean' => 'boolean', + 'int' => 'integer', + ); + + /** + * Constructs a new DocParser. + */ + public function __construct() + { + $this->lexer = new DocLexer; + } + + /** + * Sets the annotation names that are ignored during the parsing process. + * + * The names are supposed to be the raw names as used in the class, not the + * fully qualified class names. + * + * @param array $names + */ + public function setIgnoredAnnotationNames(array $names) + { + $this->ignoredAnnotationNames = $names; + } + + public function setIgnoreNotImportedAnnotations($bool) + { + $this->ignoreNotImportedAnnotations = (Boolean) $bool; + } + + /** + * Sets the default namespaces. + * @param array $namespaces + */ + public function addNamespace($namespace) + { + if ($this->imports) { + throw new \RuntimeException('You must either use addNamespace(), or setImports(), but not both.'); + } + $this->namespaces[] = $namespace; + } + + public function setImports(array $imports) + { + if ($this->namespaces) { + throw new \RuntimeException('You must either use addNamespace(), or setImports(), but not both.'); + } + $this->imports = $imports; + } + + /** + * Sets current target context as bitmask. + * + * @param integer $target + */ + public function setTarget($target) + { + $this->target = $target; + } + + /** + * Parses the given docblock string for annotations. + * + * @param string $input The docblock string to parse. + * @param string $context The parsing context. + * @return array Array of annotations. If no annotations are found, an empty array is returned. + */ + public function parse($input, $context = '') + { + if (false === $pos = strpos($input, '@')) { + return array(); + } + + // also parse whatever character is before the @ + if ($pos > 0) { + $pos -= 1; + } + + $this->context = $context; + $this->lexer->setInput(trim(substr($input, $pos), '* /')); + $this->lexer->moveNext(); + + return $this->Annotations(); + } + + /** + * Attempts to match the given token with the current lookahead token. + * If they match, updates the lookahead token; otherwise raises a syntax error. + * + * @param int Token type. + * @return bool True if tokens match; false otherwise. + */ + private function match($token) + { + if ( ! $this->lexer->isNextToken($token) ) { + $this->syntaxError($this->lexer->getLiteral($token)); + } + + return $this->lexer->moveNext(); + } + + /** + * Attempts to match the current lookahead token with any of the given tokens. + * + * If any of them matches, this method updates the lookahead token; otherwise + * a syntax error is raised. + * + * @param array $tokens + * @return bool + */ + private function matchAny(array $tokens) + { + if ( ! $this->lexer->isNextTokenAny($tokens)) { + $this->syntaxError(implode(' or ', array_map(array($this->lexer, 'getLiteral'), $tokens))); + } + + return $this->lexer->moveNext(); + } + + /** + * Generates a new syntax error. + * + * @param string $expected Expected string. + * @param array $token Optional token. + * @throws SyntaxException + */ + private function syntaxError($expected, $token = null) + { + if ($token === null) { + $token = $this->lexer->lookahead; + } + + $message = "Expected {$expected}, got "; + + if ($this->lexer->lookahead === null) { + $message .= 'end of string'; + } else { + $message .= "'{$token['value']}' at position {$token['position']}"; + } + + if (strlen($this->context)) { + $message .= ' in ' . $this->context; + } + + $message .= '.'; + + throw AnnotationException::syntaxError($message); + } + + /** + * Attempt to check if a class exists or not. This never goes through the PHP autoloading mechanism + * but uses the {@link AnnotationRegistry} to load classes. + * + * @param string $fqcn + * @return boolean + */ + private function classExists($fqcn) + { + if (isset($this->classExists[$fqcn])) { + return $this->classExists[$fqcn]; + } + + // first check if the class already exists, maybe loaded through another AnnotationReader + if (class_exists($fqcn, false)) { + return $this->classExists[$fqcn] = true; + } + + // final check, does this class exist? + return $this->classExists[$fqcn] = AnnotationRegistry::loadAnnotationClass($fqcn); + } + + /** + * Collects parsing metadata for a given annotation class + * + * @param string $name The annotation name + */ + private function collectAnnotationMetadata($name) + { + if (self::$metadataParser == null){ + self::$metadataParser = new self(); + self::$metadataParser->setTarget(Target::TARGET_CLASS); + self::$metadataParser->setIgnoreNotImportedAnnotations(true); + self::$metadataParser->setImports(array( + 'target' => 'Doctrine\Common\Annotations\Annotation\Target', + 'attribute' => 'Doctrine\Common\Annotations\Annotation\Attribute', + 'attributes' => 'Doctrine\Common\Annotations\Annotation\Attributes' + )); + AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Target.php'); + AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Attribute.php'); + AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Attributes.php'); + } + + $class = new \ReflectionClass($name); + $docComment = $class->getDocComment(); + + // Sets default values for annotation metadata + $metadata = array( + 'default_property' => null, + 'has_constructor' => (null !== $constructor = $class->getConstructor()) && $constructor->getNumberOfParameters() > 0, + 'properties' => array(), + 'property_types' => array(), + 'attribute_types' => array(), + 'targets_literal' => null, + 'targets' => Target::TARGET_ALL, + 'is_annotation' => false !== strpos($docComment, '@Annotation'), + ); + + // verify that the class is really meant to be an annotation + if ($metadata['is_annotation']) { + foreach (self::$metadataParser->parse($docComment, 'class @' . $name) as $annotation) { + if ($annotation instanceof Target) { + $metadata['targets'] = $annotation->targets; + $metadata['targets_literal'] = $annotation->literal; + + } elseif ($annotation instanceof Attributes) { + foreach ($annotation->value as $attrib) { + // handle internal type declaration + $type = isset(self::$typeMap[$attrib->type]) ? self::$typeMap[$attrib->type] : $attrib->type; + + // handle the case if the property type is mixed + if ('mixed' !== $type) { + // Checks if the property has array + if (false !== $pos = strpos($type, '<')) { + $arrayType = substr($type, $pos+1, -1); + $type = 'array'; + + if (isset(self::$typeMap[$arrayType])) { + $arrayType = self::$typeMap[$arrayType]; + } + + $metadata['attribute_types'][$attrib->name]['array_type'] = $arrayType; + } + + $metadata['attribute_types'][$attrib->name]['type'] = $type; + $metadata['attribute_types'][$attrib->name]['value'] = $attrib->type; + $metadata['attribute_types'][$attrib->name]['required'] = $attrib->required; + } + } + } + } + + // if not has a constructor will inject values into public properties + if (false === $metadata['has_constructor']) { + // collect all public properties + foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) { + $metadata['properties'][$property->name] = $property->name; + + // checks if the property has @var annotation + if ((false !== $propertyComment = $property->getDocComment()) + && false !== strpos($propertyComment, '@var') + && preg_match('/@var\s+([^\s]+)/',$propertyComment, $matches)) { + // literal type declaration + $value = $matches[1]; + + // handle internal type declaration + $type = isset(self::$typeMap[$value]) ? self::$typeMap[$value] : $value; + + // handle the case if the property type is mixed + if ('mixed' !== $type) { + // Checks if the property has @var array annotation + if (false !== $pos = strpos($type, '<')) { + $arrayType = substr($type, $pos+1, -1); + $type = 'array'; + + if (isset(self::$typeMap[$arrayType])) { + $arrayType = self::$typeMap[$arrayType]; + } + + $metadata['attribute_types'][$property->name]['array_type'] = $arrayType; + } + + $metadata['attribute_types'][$property->name]['type'] = $type; + $metadata['attribute_types'][$property->name]['value'] = $value; + $metadata['attribute_types'][$property->name]['required'] = false !== strpos($propertyComment, '@Required'); + } + } + } + + // choose the first property as default property + $metadata['default_property'] = reset($metadata['properties']); + } + } + + self::$annotationMetadata[$name] = $metadata; + } + + /** + * Annotations ::= Annotation {[ "*" ]* [Annotation]}* + * + * @return array + */ + private function Annotations() + { + $annotations = array(); + + while (null !== $this->lexer->lookahead) { + if (DocLexer::T_AT !== $this->lexer->lookahead['type']) { + $this->lexer->moveNext(); + continue; + } + + // make sure the @ is preceded by non-catchable pattern + if (null !== $this->lexer->token && $this->lexer->lookahead['position'] === $this->lexer->token['position'] + strlen($this->lexer->token['value'])) { + $this->lexer->moveNext(); + continue; + } + + // make sure the @ is followed by either a namespace separator, or + // an identifier token + if ((null === $peek = $this->lexer->glimpse()) + || (DocLexer::T_NAMESPACE_SEPARATOR !== $peek['type'] && !in_array($peek['type'], self::$classIdentifiers, true)) + || $peek['position'] !== $this->lexer->lookahead['position'] + 1) { + $this->lexer->moveNext(); + continue; + } + + $this->isNestedAnnotation = false; + if (false !== $annot = $this->Annotation()) { + $annotations[] = $annot; + } + } + + return $annotations; + } + + /** + * Annotation ::= "@" AnnotationName ["(" [Values] ")"] + * AnnotationName ::= QualifiedName | SimpleName + * QualifiedName ::= NameSpacePart "\" {NameSpacePart "\"}* SimpleName + * NameSpacePart ::= identifier | null | false | true + * SimpleName ::= identifier | null | false | true + * + * @return mixed False if it is not a valid annotation. + */ + private function Annotation() + { + $this->match(DocLexer::T_AT); + + // check if we have an annotation + if ($this->lexer->isNextTokenAny(self::$classIdentifiers)) { + $this->lexer->moveNext(); + $name = $this->lexer->token['value']; + } else if ($this->lexer->isNextToken(DocLexer::T_NAMESPACE_SEPARATOR)) { + $name = ''; + } else { + $this->syntaxError('namespace separator or identifier'); + } + + while ($this->lexer->lookahead['position'] === $this->lexer->token['position'] + strlen($this->lexer->token['value']) && $this->lexer->isNextToken(DocLexer::T_NAMESPACE_SEPARATOR)) { + $this->match(DocLexer::T_NAMESPACE_SEPARATOR); + $this->matchAny(self::$classIdentifiers); + $name .= '\\'.$this->lexer->token['value']; + } + + // only process names which are not fully qualified, yet + // fully qualified names must start with a \ + $originalName = $name; + if ('\\' !== $name[0]) { + $alias = (false === $pos = strpos($name, '\\'))? $name : substr($name, 0, $pos); + + $found = false; + if ($this->namespaces) { + foreach ($this->namespaces as $namespace) { + if ($this->classExists($namespace.'\\'.$name)) { + $name = $namespace.'\\'.$name; + $found = true; + break; + } + } + } elseif (isset($this->imports[$loweredAlias = strtolower($alias)])) { + if (false !== $pos) { + $name = $this->imports[$loweredAlias].substr($name, $pos); + } else { + $name = $this->imports[$loweredAlias]; + } + $found = true; + } elseif (isset($this->imports['__NAMESPACE__']) && $this->classExists($this->imports['__NAMESPACE__'].'\\'.$name)) { + $name = $this->imports['__NAMESPACE__'].'\\'.$name; + $found = true; + } elseif ($this->classExists($name)) { + $found = true; + } + + if (!$found) { + if ($this->ignoreNotImportedAnnotations || isset($this->ignoredAnnotationNames[$name])) { + return false; + } + + throw AnnotationException::semanticalError(sprintf('The annotation "@%s" in %s was never imported. Did you maybe forget to add a "use" statement for this annotation?', $name, $this->context)); + } + } + + if (!$this->classExists($name)) { + throw AnnotationException::semanticalError(sprintf('The annotation "@%s" in %s does not exist, or could not be auto-loaded.', $name, $this->context)); + } + + // at this point, $name contains the fully qualified class name of the + // annotation, and it is also guaranteed that this class exists, and + // that it is loaded + + + // collects the metadata annotation only if there is not yet + if (!isset(self::$annotationMetadata[$name])) { + $this->collectAnnotationMetadata($name); + } + + // verify that the class is really meant to be an annotation and not just any ordinary class + if (self::$annotationMetadata[$name]['is_annotation'] === false) { + if (isset($this->ignoredAnnotationNames[$originalName])) { + return false; + } + + throw AnnotationException::semanticalError(sprintf('The class "%s" is not annotated with @Annotation. Are you sure this class can be used as annotation? If so, then you need to add @Annotation to the _class_ doc comment of "%s". If it is indeed no annotation, then you need to add @IgnoreAnnotation("%s") to the _class_ doc comment of %s.', $name, $name, $originalName, $this->context)); + } + + //if target is nested annotation + $target = $this->isNestedAnnotation ? Target::TARGET_ANNOTATION : $this->target; + + // Next will be nested + $this->isNestedAnnotation = true; + + //if annotation does not support current target + if (0 === (self::$annotationMetadata[$name]['targets'] & $target) && $target) { + throw AnnotationException::semanticalError( + sprintf('Annotation @%s is not allowed to be declared on %s. You may only use this annotation on these code elements: %s.', + $originalName, $this->context, self::$annotationMetadata[$name]['targets_literal']) + ); + } + + $values = array(); + if ($this->lexer->isNextToken(DocLexer::T_OPEN_PARENTHESIS)) { + $this->match(DocLexer::T_OPEN_PARENTHESIS); + + if ( ! $this->lexer->isNextToken(DocLexer::T_CLOSE_PARENTHESIS)) { + $values = $this->Values(); + } + + $this->match(DocLexer::T_CLOSE_PARENTHESIS); + } + + // checks all declared attributes + foreach (self::$annotationMetadata[$name]['attribute_types'] as $property => $type) { + if ($property === self::$annotationMetadata[$name]['default_property'] + && !isset($values[$property]) && isset($values['value'])) { + $property = 'value'; + } + + // handle a not given attribute or null value + if (!isset($values[$property])) { + if ($type['required']) { + throw AnnotationException::requiredError($property, $originalName, $this->context, 'a(n) '.$type['value']); + } + + continue; + } + + if ($type['type'] === 'array') { + // handle the case of a single value + if (!is_array($values[$property])) { + $values[$property] = array($values[$property]); + } + + // checks if the attribute has array type declaration, such as "array" + if (isset($type['array_type'])) { + foreach ($values[$property] as $item) { + if (gettype($item) !== $type['array_type'] && !$item instanceof $type['array_type']) { + throw AnnotationException::typeError($property, $originalName, $this->context, 'either a(n) '.$type['array_type'].', or an array of '.$type['array_type'].'s', $item); + } + } + } + } elseif (gettype($values[$property]) !== $type['type'] && !$values[$property] instanceof $type['type']) { + throw AnnotationException::typeError($property, $originalName, $this->context, 'a(n) '.$type['value'], $values[$property]); + } + } + + // check if the annotation expects values via the constructor, + // or directly injected into public properties + if (self::$annotationMetadata[$name]['has_constructor'] === true) { + return new $name($values); + } + + $instance = new $name(); + foreach ($values as $property => $value) { + if (!isset(self::$annotationMetadata[$name]['properties'][$property])) { + if ('value' !== $property) { + throw AnnotationException::creationError(sprintf('The annotation @%s declared on %s does not have a property named "%s". Available properties: %s', $originalName, $this->context, $property, implode(', ', self::$annotationMetadata[$name]['properties']))); + } + + // handle the case if the property has no annotations + if (!$property = self::$annotationMetadata[$name]['default_property']) { + throw AnnotationException::creationError(sprintf('The annotation @%s declared on %s does not accept any values, but got %s.', $originalName, $this->context, json_encode($values))); + } + } + + $instance->{$property} = $value; + } + + return $instance; + } + + /** + * Values ::= Array | Value {"," Value}* + * + * @return array + */ + private function Values() + { + $values = array(); + + // Handle the case of a single array as value, i.e. @Foo({....}) + if ($this->lexer->isNextToken(DocLexer::T_OPEN_CURLY_BRACES)) { + $values['value'] = $this->Value(); + return $values; + } + + $values[] = $this->Value(); + + while ($this->lexer->isNextToken(DocLexer::T_COMMA)) { + $this->match(DocLexer::T_COMMA); + $token = $this->lexer->lookahead; + $value = $this->Value(); + + if ( ! is_object($value) && ! is_array($value)) { + $this->syntaxError('Value', $token); + } + + $values[] = $value; + } + + foreach ($values as $k => $value) { + if (is_object($value) && $value instanceof \stdClass) { + $values[$value->name] = $value->value; + } else if ( ! isset($values['value'])){ + $values['value'] = $value; + } else { + if ( ! is_array($values['value'])) { + $values['value'] = array($values['value']); + } + + $values['value'][] = $value; + } + + unset($values[$k]); + } + + return $values; + } + + /** + * Value ::= PlainValue | FieldAssignment + * + * @return mixed + */ + private function Value() + { + $peek = $this->lexer->glimpse(); + + if (DocLexer::T_EQUALS === $peek['type']) { + return $this->FieldAssignment(); + } + + return $this->PlainValue(); + } + + /** + * PlainValue ::= integer | string | float | boolean | Array | Annotation + * + * @return mixed + */ + private function PlainValue() + { + if ($this->lexer->isNextToken(DocLexer::T_OPEN_CURLY_BRACES)) { + return $this->Arrayx(); + } + + if ($this->lexer->isNextToken(DocLexer::T_AT)) { + return $this->Annotation(); + } + + switch ($this->lexer->lookahead['type']) { + case DocLexer::T_STRING: + $this->match(DocLexer::T_STRING); + return $this->lexer->token['value']; + + case DocLexer::T_INTEGER: + $this->match(DocLexer::T_INTEGER); + return (int)$this->lexer->token['value']; + + case DocLexer::T_FLOAT: + $this->match(DocLexer::T_FLOAT); + return (float)$this->lexer->token['value']; + + case DocLexer::T_TRUE: + $this->match(DocLexer::T_TRUE); + return true; + + case DocLexer::T_FALSE: + $this->match(DocLexer::T_FALSE); + return false; + + case DocLexer::T_NULL: + $this->match(DocLexer::T_NULL); + return null; + + default: + $this->syntaxError('PlainValue'); + } + } + + /** + * FieldAssignment ::= FieldName "=" PlainValue + * FieldName ::= identifier + * + * @return array + */ + private function FieldAssignment() + { + $this->match(DocLexer::T_IDENTIFIER); + $fieldName = $this->lexer->token['value']; + + $this->match(DocLexer::T_EQUALS); + + $item = new \stdClass(); + $item->name = $fieldName; + $item->value = $this->PlainValue(); + + return $item; + } + + /** + * Array ::= "{" ArrayEntry {"," ArrayEntry}* [","] "}" + * + * @return array + */ + private function Arrayx() + { + $array = $values = array(); + + $this->match(DocLexer::T_OPEN_CURLY_BRACES); + $values[] = $this->ArrayEntry(); + + while ($this->lexer->isNextToken(DocLexer::T_COMMA)) { + $this->match(DocLexer::T_COMMA); + + // optional trailing comma + if ($this->lexer->isNextToken(DocLexer::T_CLOSE_CURLY_BRACES)) { + break; + } + + $values[] = $this->ArrayEntry(); + } + + $this->match(DocLexer::T_CLOSE_CURLY_BRACES); + + foreach ($values as $value) { + list ($key, $val) = $value; + + if ($key !== null) { + $array[$key] = $val; + } else { + $array[] = $val; + } + } + + return $array; + } + + /** + * ArrayEntry ::= Value | KeyValuePair + * KeyValuePair ::= Key ("=" | ":") PlainValue + * Key ::= string | integer + * + * @return array + */ + private function ArrayEntry() + { + $peek = $this->lexer->glimpse(); + + if (DocLexer::T_EQUALS === $peek['type'] + || DocLexer::T_COLON === $peek['type']) { + $this->matchAny(array(DocLexer::T_INTEGER, DocLexer::T_STRING)); + + $key = $this->lexer->token['value']; + $this->matchAny(array(DocLexer::T_EQUALS, DocLexer::T_COLON)); + + return array($key, $this->PlainValue()); + } + + return array(null, $this->Value()); + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Annotations/FileCacheReader.php b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/FileCacheReader.php new file mode 100644 index 0000000..4a42b58 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/FileCacheReader.php @@ -0,0 +1,209 @@ +. + */ + +namespace Doctrine\Common\Annotations; + + +/** + * File cache reader for annotations. + * + * @author Johannes M. Schmitt + * @author Benjamin Eberlei + */ +class FileCacheReader implements Reader +{ + /** + * @var Reader + */ + private $reader; + private $dir; + private $debug; + private $loadedAnnotations = array(); + + public function __construct(Reader $reader, $cacheDir, $debug = false) + { + $this->reader = $reader; + if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0777, true)) { + throw new \InvalidArgumentException(sprintf('The directory "%s" does not exist and could not be created.', $cacheDir)); + } + if (!is_writable($cacheDir)) { + throw new \InvalidArgumentException(sprintf('The directory "%s" is not writable. Both, the webserver and the console user need access. You can manage access rights for multiple users with "chmod +a". If your system does not support this, check out the acl package.', $cacheDir)); + } + + $this->dir = rtrim($cacheDir, '\\/'); + $this->debug = $debug; + } + + public function getClassAnnotations(\ReflectionClass $class) + { + $key = $class->getName(); + + if (isset($this->loadedAnnotations[$key])) { + return $this->loadedAnnotations[$key]; + } + + $path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php'; + if (!file_exists($path)) { + $annot = $this->reader->getClassAnnotations($class); + $this->saveCacheFile($path, $annot); + return $this->loadedAnnotations[$key] = $annot; + } + + if ($this->debug + && (false !== $filename = $class->getFilename()) + && filemtime($path) < filemtime($filename)) { + @unlink($path); + + $annot = $this->reader->getClassAnnotations($class); + $this->saveCacheFile($path, $annot); + return $this->loadedAnnotations[$key] = $annot; + } + + return $this->loadedAnnotations[$key] = include $path; + } + + public function getPropertyAnnotations(\ReflectionProperty $property) + { + $class = $property->getDeclaringClass(); + $key = $class->getName().'$'.$property->getName(); + + if (isset($this->loadedAnnotations[$key])) { + return $this->loadedAnnotations[$key]; + } + + $path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php'; + if (!file_exists($path)) { + $annot = $this->reader->getPropertyAnnotations($property); + $this->saveCacheFile($path, $annot); + return $this->loadedAnnotations[$key] = $annot; + } + + if ($this->debug + && (false !== $filename = $class->getFilename()) + && filemtime($path) < filemtime($filename)) { + unlink($path); + + $annot = $this->reader->getPropertyAnnotations($property); + $this->saveCacheFile($path, $annot); + return $this->loadedAnnotations[$key] = $annot; + } + + return $this->loadedAnnotations[$key] = include $path; + } + + public function getMethodAnnotations(\ReflectionMethod $method) + { + $class = $method->getDeclaringClass(); + $key = $class->getName().'#'.$method->getName(); + + if (isset($this->loadedAnnotations[$key])) { + return $this->loadedAnnotations[$key]; + } + + $path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php'; + if (!file_exists($path)) { + $annot = $this->reader->getMethodAnnotations($method); + $this->saveCacheFile($path, $annot); + return $this->loadedAnnotations[$key] = $annot; + } + + if ($this->debug + && (false !== $filename = $class->getFilename()) + && filemtime($path) < filemtime($filename)) { + unlink($path); + + $annot = $this->reader->getMethodAnnotations($method); + $this->saveCacheFile($path, $annot); + return $this->loadedAnnotations[$key] = $annot; + } + + return $this->loadedAnnotations[$key] = include $path; + } + + private function saveCacheFile($path, $data) + { + file_put_contents($path, 'getClassAnnotations($class); + + foreach ($annotations as $annotation) { + if ($annotation instanceof $annotationName) { + return $annotation; + } + } + + return null; + } + + /** + * Gets a method annotation. + * + * @param ReflectionMethod $method + * @param string $annotationName The name of the annotation. + * @return The Annotation or NULL, if the requested annotation does not exist. + */ + public function getMethodAnnotation(\ReflectionMethod $method, $annotationName) + { + $annotations = $this->getMethodAnnotations($method); + + foreach ($annotations as $annotation) { + if ($annotation instanceof $annotationName) { + return $annotation; + } + } + + return null; + } + + /** + * Gets a property annotation. + * + * @param ReflectionProperty $property + * @param string $annotationName The name of the annotation. + * @return The Annotation or NULL, if the requested annotation does not exist. + */ + public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName) + { + $annotations = $this->getPropertyAnnotations($property); + + foreach ($annotations as $annotation) { + if ($annotation instanceof $annotationName) { + return $annotation; + } + } + + return null; + } + + public function clearLoadedAnnotations() + { + $this->loadedAnnotations = array(); + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Annotations/IndexedReader.php b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/IndexedReader.php new file mode 100644 index 0000000..1eea492 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/IndexedReader.php @@ -0,0 +1,94 @@ +. + */ + +namespace Doctrine\Common\Annotations; + +use Doctrine\Common\Annotations\Reader; + +/** + * Allows the reader to be used in-place of Doctrine's reader. + * + * @author Johannes M. Schmitt + */ +class IndexedReader implements Reader +{ + private $delegate; + + public function __construct(Reader $reader) + { + $this->delegate = $reader; + } + + public function getClassAnnotations(\ReflectionClass $class) + { + $annotations = array(); + foreach ($this->delegate->getClassAnnotations($class) as $annot) { + $annotations[get_class($annot)] = $annot; + } + + return $annotations; + } + + public function getClassAnnotation(\ReflectionClass $class, $annotation) + { + return $this->delegate->getClassAnnotation($class, $annotation); + } + + public function getMethodAnnotations(\ReflectionMethod $method) + { + $annotations = array(); + foreach ($this->delegate->getMethodAnnotations($method) as $annot) { + $annotations[get_class($annot)] = $annot; + } + + return $annotations; + } + + public function getMethodAnnotation(\ReflectionMethod $method, $annotation) + { + return $this->delegate->getMethodAnnotation($method, $annotation); + } + + public function getPropertyAnnotations(\ReflectionProperty $property) + { + $annotations = array(); + foreach ($this->delegate->getPropertyAnnotations($property) as $annot) { + $annotations[get_class($annot)] = $annot; + } + + return $annotations; + } + + public function getPropertyAnnotation(\ReflectionProperty $property, $annotation) + { + return $this->delegate->getPropertyAnnotation($property, $annotation); + } + + /** + * Proxy all methods to the delegate. + * + * @param type $method + * @param type $args + * @return type + */ + public function __call($method, $args) + { + return call_user_func_array(array($this->delegate, $method), $args); + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Annotations/PhpParser.php b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/PhpParser.php new file mode 100644 index 0000000..a14f8f5 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/PhpParser.php @@ -0,0 +1,203 @@ +. + */ + +namespace Doctrine\Common\Annotations; + +use SplFileObject; + +/** + * Parses a file for namespaces/use/class declarations. + * + * @author Fabien Potencier + * @author Christian Kaps + */ +final class PhpParser +{ + /** + * The token list. + * + * @var array + */ + private $tokens; + + /** + * The number of tokens. + * + * @var int + */ + private $numTokens = 0; + + /** + * The current array pointer. + * + * @var int + */ + private $pointer = 0; + + /** + * Parses a class. + * + * @param \ReflectionClass $class A ReflectionClass object. + * @return array A list with use statements in the form (Alias => FQN). + */ + public function parseClass(\ReflectionClass $class) + { + if (false === $filename = $class->getFilename()) { + return array(); + } + + $content = $this->getFileContent($filename, $class->getStartLine()); + $namespace = str_replace('\\', '\\\\', $class->getNamespaceName()); + $content = preg_replace('/^.*?(\bnamespace\s+' . $namespace . '\s*[;{].*)$/s', '\\1', $content); + $this->tokens = token_get_all('numTokens = count($this->tokens); + $this->pointer = 0; + + $statements = $this->parseUseStatements($class->getNamespaceName()); + + return $statements; + } + + /** + * Get the content of the file right up to the given line number. + * + * @param string $filename The name of the file to load. + * @param int $lineNumber The number of lines to read from file. + * @return string The content of the file. + */ + private function getFileContent($filename, $lineNumber) + { + $content = ''; + $lineCnt = 0; + $file = new SplFileObject($filename); + while(!$file->eof()) { + if ($lineCnt++ == $lineNumber) { + break; + } + + $content .= $file->fgets(); + } + + return $content; + } + + /** + * Gets the next non whitespace and non comment token. + * + * @return array The token if exists, null otherwise. + */ + private function next() + { + for ($i = $this->pointer; $i < $this->numTokens; $i++) { + $this->pointer++; + if ($this->tokens[$i][0] === T_WHITESPACE || + $this->tokens[$i][0] === T_COMMENT || + $this->tokens[$i][0] === T_DOC_COMMENT) { + + continue; + } + + return $this->tokens[$i]; + } + + return null; + } + + /** + * Get all use statements. + * + * @param string $namespaceName The namespace name of the reflected class. + * @return array A list with all found use statements. + */ + private function parseUseStatements($namespaceName) + { + $statements = array(); + while (($token = $this->next())) { + if ($token[0] === T_USE) { + $statements = array_merge($statements, $this->parseUseStatement()); + continue; + } else if ($token[0] !== T_NAMESPACE || $this->parseNamespace() != $namespaceName) { + continue; + } + + // Get fresh array for new namespace. This is to prevent the parser to collect the use statements + // for a previous namespace with the same name. This is the case if a namespace is defined twice + // or if a namespace with the same name is commented out. + $statements = array(); + } + + return $statements; + } + + /** + * Get the namespace name. + * + * @return string The found namespace name. + */ + private function parseNamespace() + { + $namespace = ''; + while (($token = $this->next())){ + if ($token[0] === T_STRING || $token[0] === T_NS_SEPARATOR) { + $namespace .= $token[1]; + } else { + break; + } + } + + return $namespace; + } + + /** + * Parse a single use statement. + * + * @return array A list with all found class names for a use statement. + */ + private function parseUseStatement() + { + $class = ''; + $alias = ''; + $statements = array(); + $explicitAlias = false; + while (($token = $this->next())) { + $isNameToken = $token[0] === T_STRING || $token[0] === T_NS_SEPARATOR; + if (!$explicitAlias && $isNameToken) { + $class .= $token[1]; + $alias = $token[1]; + } else if ($explicitAlias && $isNameToken) { + $alias .= $token[1]; + } else if ($token[0] === T_AS) { + $explicitAlias = true; + $alias = ''; + } else if ($token === ',') { + $statements[strtolower($alias)] = $class; + $class = ''; + $alias = ''; + $explicitAlias = false; + } else if ($token === ';') { + $statements[strtolower($alias)] = $class; + break; + } else { + break; + } + } + + return $statements; + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Annotations/Reader.php b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/Reader.php new file mode 100644 index 0000000..8e85d39 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/Reader.php @@ -0,0 +1,35 @@ +. + */ + +namespace Doctrine\Common\Annotations; + +/** + * Interface for annotation readers. + * + * @author Johannes M. Schmitt + */ +interface Reader +{ + function getClassAnnotations(\ReflectionClass $class); + function getClassAnnotation(\ReflectionClass $class, $annotationName); + function getMethodAnnotations(\ReflectionMethod $method); + function getMethodAnnotation(\ReflectionMethod $method, $annotationName); + function getPropertyAnnotations(\ReflectionProperty $property); + function getPropertyAnnotation(\ReflectionProperty $property, $annotationName); +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Annotations/SimpleAnnotationReader.php b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/SimpleAnnotationReader.php new file mode 100644 index 0000000..a13c7fa --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Annotations/SimpleAnnotationReader.php @@ -0,0 +1,152 @@ +. + */ + +namespace Doctrine\Common\Annotations; + +use Doctrine\Common\Annotations\Annotation\Target; + +/** + * Simple Annotation Reader. + * + * This annotation reader is intended to be used in projects where you have + * full-control over all annotations that are available. + * + * @since 2.2 + * @author Johannes M. Schmitt + * @author Fabio B. Silva + */ +class SimpleAnnotationReader implements Reader +{ + /** + * @var DocParser + */ + private $parser; + + /** + * Constructor. + * + * Initializes a new SimpleAnnotationReader. + */ + public function __construct() + { + $this->parser = new DocParser(); + $this->parser->setIgnoreNotImportedAnnotations(true); + } + + /** + * Adds a namespace in which we will look for annotations. + * + * @param string $namespace + */ + public function addNamespace($namespace) + { + $this->parser->addNamespace($namespace); + } + + /** + * Gets the annotations applied to a class. + * + * @param ReflectionClass $class The ReflectionClass of the class from which + * the class annotations should be read. + * @return array An array of Annotations. + */ + public function getClassAnnotations(\ReflectionClass $class) + { + return $this->parser->parse($class->getDocComment(), 'class '.$class->getName()); + } + + /** + * Gets the annotations applied to a method. + * + * @param ReflectionMethod $property The ReflectionMethod of the method from which + * the annotations should be read. + * @return array An array of Annotations. + */ + public function getMethodAnnotations(\ReflectionMethod $method) + { + return $this->parser->parse($method->getDocComment(), 'method '.$method->getDeclaringClass()->name.'::'.$method->getName().'()'); + } + + /** + * Gets the annotations applied to a property. + * + * @param ReflectionProperty $property The ReflectionProperty of the property + * from which the annotations should be read. + * @return array An array of Annotations. + */ + public function getPropertyAnnotations(\ReflectionProperty $property) + { + return $this->parser->parse($property->getDocComment(), 'property '.$property->getDeclaringClass()->name.'::$'.$property->getName()); + } + + /** + * Gets a class annotation. + * + * @param ReflectionClass $class The ReflectionClass of the class from which + * the class annotations should be read. + * @param string $annotationName The name of the annotation. + * @return The Annotation or NULL, if the requested annotation does not exist. + */ + public function getClassAnnotation(\ReflectionClass $class, $annotationName) + { + foreach ($this->getClassAnnotations($class) as $annot) { + if ($annot instanceof $annotationName) { + return $annot; + } + } + + return null; + } + + /** + * Gets a method annotation. + * + * @param ReflectionMethod $method + * @param string $annotationName The name of the annotation. + * @return The Annotation or NULL, if the requested annotation does not exist. + */ + public function getMethodAnnotation(\ReflectionMethod $method, $annotationName) + { + foreach ($this->getMethodAnnotations($method) as $annot) { + if ($annot instanceof $annotationName) { + return $annot; + } + } + + return null; + } + + /** + * Gets a property annotation. + * + * @param ReflectionProperty $property + * @param string $annotationName The name of the annotation. + * @return The Annotation or NULL, if the requested annotation does not exist. + */ + public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName) + { + foreach ($this->getPropertyAnnotations($property) as $annot) { + if ($annot instanceof $annotationName) { + return $annot; + } + } + + return null; + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Cache/ApcCache.php b/vendor/doctrine/common/lib/Doctrine/Common/Cache/ApcCache.php new file mode 100644 index 0000000..a59296f --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Cache/ApcCache.php @@ -0,0 +1,97 @@ +. + */ + +namespace Doctrine\Common\Cache; + +/** + * APC cache provider. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author David Abdemoulaie + */ +class ApcCache extends CacheProvider +{ + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + return apc_fetch($id); + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + $found = false; + + apc_fetch($id, $found); + + return $found; + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + return (bool) apc_store($id, $data, (int) $lifeTime); + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + return apc_delete($id); + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + return apc_clear_cache() && apc_clear_cache('user'); + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + $info = apc_cache_info(); + $sma = apc_sma_info(); + + return array( + Cache::STATS_HITS => $info['num_hits'], + Cache::STATS_MISSES => $info['num_misses'], + Cache::STATS_UPTIME => $info['start_time'], + Cache::STATS_MEMORY_USAGE => $info['mem_size'], + Cache::STATS_MEMORY_AVAILIABLE => $sma['avail_mem'], + ); + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Cache/ArrayCache.php b/vendor/doctrine/common/lib/Doctrine/Common/Cache/ArrayCache.php new file mode 100644 index 0000000..8a0b982 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Cache/ArrayCache.php @@ -0,0 +1,96 @@ +. + */ + +namespace Doctrine\Common\Cache; + +/** + * Array cache driver. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author David Abdemoulaie + */ +class ArrayCache extends CacheProvider +{ + /** + * @var array $data + */ + private $data = array(); + + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + return (isset($this->data[$id])) ? $this->data[$id] : false; + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + return isset($this->data[$id]); + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + $this->data[$id] = $data; + + return true; + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + unset($this->data[$id]); + + return true; + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + $this->data = array(); + + return true; + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + return null; + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Cache/Cache.php b/vendor/doctrine/common/lib/Doctrine/Common/Cache/Cache.php new file mode 100644 index 0000000..d303bde --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Cache/Cache.php @@ -0,0 +1,102 @@ +. + */ + +namespace Doctrine\Common\Cache; + +/** + * Interface for cache drivers. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Fabio B. Silva + */ +interface Cache +{ + const STATS_HITS = 'hits'; + const STATS_MISSES = 'misses'; + const STATS_UPTIME = 'uptime'; + const STATS_MEMORY_USAGE = 'memory_usage'; + const STATS_MEMORY_AVAILIABLE = 'memory_available'; + + /** + * Fetches an entry from the cache. + * + * @param string $id cache id The id of the cache entry to fetch. + * @return string The cached data or FALSE, if no cache entry exists for the given id. + */ + function fetch($id); + + /** + * Test if an entry exists in the cache. + * + * @param string $id cache id The cache id of the entry to check for. + * @return boolean TRUE if a cache entry exists for the given cache id, FALSE otherwise. + */ + function contains($id); + + /** + * Puts data into the cache. + * + * @param string $id The cache id. + * @param string $data The cache entry/data. + * @param int $lifeTime The lifetime. If != 0, sets a specific lifetime for this cache entry (0 => infinite lifeTime). + * @return boolean TRUE if the entry was successfully stored in the cache, FALSE otherwise. + */ + function save($id, $data, $lifeTime = 0); + + /** + * Deletes a cache entry. + * + * @param string $id cache id + * @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise. + */ + function delete($id); + + /** + * Retrieves cached information from data store + * + * The server's statistics array has the following values: + * + * - hits + * Number of keys that have been requested and found present. + * + * - misses + * Number of items that have been requested and not found. + * + * - uptime + * Time that the server is running. + * + * - memory_usage + * Memory used by this server to store items. + * + * - memory_available + * Memory allowed to use for storage. + * + * @since 2.2 + * @var array Associative array with server's statistics if available, NULL otherwise. + */ + function getStats(); +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Cache/CacheProvider.php b/vendor/doctrine/common/lib/Doctrine/Common/Cache/CacheProvider.php new file mode 100644 index 0000000..fa11fc2 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Cache/CacheProvider.php @@ -0,0 +1,188 @@ +. + */ + +namespace Doctrine\Common\Cache; + +/** + * Base class for cache provider implementations. + * + * @since 2.2 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Fabio B. Silva + */ +abstract class CacheProvider implements Cache +{ + const DOCTRINE_NAMESPACE_CACHEKEY = 'DoctrineNamespaceCacheKey[%s]'; + + /** + * @var string The namespace to prefix all cache ids with + */ + private $namespace = ''; + + /** + * Set the namespace to prefix all cache ids with. + * + * @param string $namespace + * @return void + */ + public function setNamespace($namespace) + { + $this->namespace = (string) $namespace; + } + + /** + * Retrieve the namespace that prefixes all cache ids. + * + * @return string + */ + public function getNamespace() + { + return $this->namespace; + } + + /** + * {@inheritdoc} + */ + public function fetch($id) + { + return $this->doFetch($this->getNamespacedId($id)); + } + + /** + * {@inheritdoc} + */ + public function contains($id) + { + return $this->doContains($this->getNamespacedId($id)); + } + + /** + * {@inheritdoc} + */ + public function save($id, $data, $lifeTime = 0) + { + return $this->doSave($this->getNamespacedId($id), $data, $lifeTime); + } + + /** + * {@inheritdoc} + */ + public function delete($id) + { + return $this->doDelete($this->getNamespacedId($id)); + } + + /** + * {@inheritdoc} + */ + public function getStats() + { + return $this->doGetStats(); + } + + /** + * Deletes all cache entries. + * + * @return boolean TRUE if the cache entries were successfully flushed, FALSE otherwise. + */ + public function flushAll() + { + return $this->doFlush(); + } + + /** + * Delete all cache entries. + * + * @return boolean TRUE if the cache entries were successfully deleted, FALSE otherwise. + */ + public function deleteAll() + { + $namespaceCacheKey = sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace); + $namespaceVersion = ($this->doContains($namespaceCacheKey)) ? $this->doFetch($namespaceCacheKey) : 1; + + return $this->doSave($namespaceCacheKey, $namespaceVersion + 1); + } + + /** + * Prefix the passed id with the configured namespace value + * + * @param string $id The id to namespace + * @return string $id The namespaced id + */ + private function getNamespacedId($id) + { + $namespaceCacheKey = sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace); + $namespaceVersion = ($this->doContains($namespaceCacheKey)) ? $this->doFetch($namespaceCacheKey) : 1; + + return sprintf('%s[%s][%s]', $this->namespace, $id, $namespaceVersion); + } + + /** + * Fetches an entry from the cache. + * + * @param string $id cache id The id of the cache entry to fetch. + * @return string The cached data or FALSE, if no cache entry exists for the given id. + */ + abstract protected function doFetch($id); + + /** + * Test if an entry exists in the cache. + * + * @param string $id cache id The cache id of the entry to check for. + * @return boolean TRUE if a cache entry exists for the given cache id, FALSE otherwise. + */ + abstract protected function doContains($id); + + /** + * Puts data into the cache. + * + * @param string $id The cache id. + * @param string $data The cache entry/data. + * @param int $lifeTime The lifetime. If != false, sets a specific lifetime for this cache entry (null => infinite lifeTime). + * @return boolean TRUE if the entry was successfully stored in the cache, FALSE otherwise. + */ + abstract protected function doSave($id, $data, $lifeTime = false); + + /** + * Deletes a cache entry. + * + * @param string $id cache id + * @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise. + */ + abstract protected function doDelete($id); + + /** + * Deletes all cache entries. + * + * @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise. + */ + abstract protected function doFlush(); + + /** + * Retrieves cached information from data store + * + * @since 2.2 + * @return array An associative array with server's statistics if available, NULL otherwise. + */ + abstract protected function doGetStats(); +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Cache/MemcacheCache.php b/vendor/doctrine/common/lib/Doctrine/Common/Cache/MemcacheCache.php new file mode 100644 index 0000000..dd6d1e3 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Cache/MemcacheCache.php @@ -0,0 +1,121 @@ +. + */ + +namespace Doctrine\Common\Cache; + +use \Memcache; + +/** + * Memcache cache provider. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author David Abdemoulaie + */ +class MemcacheCache extends CacheProvider +{ + /** + * @var Memcache + */ + private $memcache; + + /** + * Sets the memcache instance to use. + * + * @param Memcache $memcache + */ + public function setMemcache(Memcache $memcache) + { + $this->memcache = $memcache; + } + + /** + * Gets the memcache instance used by the cache. + * + * @return Memcache + */ + public function getMemcache() + { + return $this->memcache; + } + + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + return $this->memcache->get($id); + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + return (bool) $this->memcache->get($id); + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + if ($lifeTime > 30 * 24 * 3600) { + $lifeTime = time() + $lifeTime; + } + return $this->memcache->set($id, $data, 0, (int) $lifeTime); + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + return $this->memcache->delete($id); + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + return $this->memcache->flush(); + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + $stats = $this->memcache->getStats(); + return array( + Cache::STATS_HITS => $stats['get_hits'], + Cache::STATS_MISSES => $stats['get_misses'], + Cache::STATS_UPTIME => $stats['uptime'], + Cache::STATS_MEMORY_USAGE => $stats['bytes'], + Cache::STATS_MEMORY_AVAILIABLE => $stats['limit_maxbytes'], + ); + } +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Cache/MemcachedCache.php b/vendor/doctrine/common/lib/Doctrine/Common/Cache/MemcachedCache.php new file mode 100644 index 0000000..4675fae --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Cache/MemcachedCache.php @@ -0,0 +1,124 @@ +. + */ + +namespace Doctrine\Common\Cache; + +use \Memcached; + +/** + * Memcached cache provider. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.2 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author David Abdemoulaie + */ +class MemcachedCache extends CacheProvider +{ + /** + * @var Memcached + */ + private $memcached; + + /** + * Sets the memcache instance to use. + * + * @param Memcached $memcached + */ + public function setMemcached(Memcached $memcached) + { + $this->memcached = $memcached; + } + + /** + * Gets the memcached instance used by the cache. + * + * @return Memcached + */ + public function getMemcached() + { + return $this->memcached; + } + + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + return $this->memcached->get($id); + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + return (false !== $this->memcached->get($id)); + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + if ($lifeTime > 30 * 24 * 3600) { + $lifeTime = time() + $lifeTime; + } + return $this->memcached->set($id, $data, (int) $lifeTime); + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + return $this->memcached->delete($id); + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + return $this->memcached->flush(); + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + $stats = $this->memcached->getStats(); + $servers = $this->memcached->getServerList(); + $key = $servers[0]['host'] . ':' . $servers[0]['port']; + $stats = $stats[$key]; + return array( + Cache::STATS_HITS => $stats['get_hits'], + Cache::STATS_MISSES => $stats['get_misses'], + Cache::STATS_UPTIME => $stats['uptime'], + Cache::STATS_MEMORY_USAGE => $stats['bytes'], + Cache::STATS_MEMORY_AVAILIABLE => $stats['limit_maxbytes'], + ); + } +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Cache/WinCacheCache.php b/vendor/doctrine/common/lib/Doctrine/Common/Cache/WinCacheCache.php new file mode 100644 index 0000000..ed8ca74 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Cache/WinCacheCache.php @@ -0,0 +1,92 @@ +. + */ + +namespace Doctrine\Common\Cache; + +/** + * WinCache cache provider. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.2 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author David Abdemoulaie + */ +class WincacheCache extends CacheProvider +{ + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + return wincache_ucache_get($id); + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + return wincache_ucache_exists($id); + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + return (bool) wincache_ucache_set($id, $data, (int) $lifeTime); + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + return wincache_ucache_delete($id); + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + return wincache_ucache_clear(); + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + $info = wincache_ucache_info(); + $meminfo= wincache_ucache_meminfo(); + return array( + Cache::STATS_HITS => $info['total_hit_count'], + Cache::STATS_MISSES => $info['total_miss_count'], + Cache::STATS_UPTIME => $info['total_cache_uptime'], + Cache::STATS_MEMORY_USAGE => $meminfo['memory_total'], + Cache::STATS_MEMORY_AVAILIABLE => $meminfo['memory_free'], + ); + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Cache/XcacheCache.php b/vendor/doctrine/common/lib/Doctrine/Common/Cache/XcacheCache.php new file mode 100644 index 0000000..6e22d26 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Cache/XcacheCache.php @@ -0,0 +1,110 @@ +. + */ + +namespace Doctrine\Common\Cache; + +/** + * Xcache cache driver. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author David Abdemoulaie + */ +class XcacheCache extends CacheProvider +{ + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + return $this->doContains($id) ? unserialize(xcache_get($id)) : false; + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + return xcache_isset($id); + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + return xcache_set($id, serialize($data), (int) $lifeTime); + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + return xcache_unset($id); + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + $this->checkAuthorization(); + + xcache_clear_cache(XC_TYPE_VAR, 0); + + return true; + } + + /** + * Checks that xcache.admin.enable_auth is Off + * + * @throws \BadMethodCallException When xcache.admin.enable_auth is On + * @return void + */ + protected function checkAuthorization() + { + if (ini_get('xcache.admin.enable_auth')) { + throw new \BadMethodCallException('To use all features of \Doctrine\Common\Cache\XcacheCache, you must set "xcache.admin.enable_auth" to "Off" in your php.ini.'); + } + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + $this->checkAuthorization(); + + $info = xcache_info(XC_TYPE_VAR, 0); + return array( + Cache::STATS_HITS => $info['hits'], + Cache::STATS_MISSES => $info['misses'], + Cache::STATS_UPTIME => null, + Cache::STATS_MEMORY_USAGE => $info['size'], + Cache::STATS_MEMORY_AVAILIABLE => $info['avail'], + ); + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Cache/ZendDataCache.php b/vendor/doctrine/common/lib/Doctrine/Common/Cache/ZendDataCache.php new file mode 100644 index 0000000..4e4dabe --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Cache/ZendDataCache.php @@ -0,0 +1,84 @@ +. + */ + +namespace Doctrine\Common\Cache; + +/** + * Zend Data Cache cache driver. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Ralph Schindler + * @author Guilherme Blanco + */ +class ZendDataCache extends CacheProvider +{ + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + return zend_shm_cache_fetch($id); + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + return (false !== zend_shm_cache_fetch($id)); + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + return zend_shm_cache_store($id, $data, $lifeTime); + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + return zend_shm_cache_delete($id); + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + $namespace = $this->getNamespace(); + if (empty($namespace)) { + return zend_shm_cache_clear(); + } + return zend_shm_cache_clear($namespace); + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + return null; + } +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/ClassLoader.php b/vendor/doctrine/common/lib/Doctrine/Common/ClassLoader.php new file mode 100644 index 0000000..375b0d6 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/ClassLoader.php @@ -0,0 +1,262 @@ +. + */ + +namespace Doctrine\Common; + +/** + * A ClassLoader is an autoloader for class files that can be + * installed on the SPL autoload stack. It is a class loader that either loads only classes + * of a specific namespace or all namespaces and it is suitable for working together + * with other autoloaders in the SPL autoload stack. + * + * If no include path is configured through the constructor or {@link setIncludePath}, a ClassLoader + * relies on the PHP include_path. + * + * @author Roman Borschel + * @since 2.0 + */ +class ClassLoader +{ + /** + * @var string PHP file extension + */ + protected $fileExtension = '.php'; + + /** + * @var string Current namespace + */ + protected $namespace; + + /** + * @var string Current include path + */ + protected $includePath; + + /** + * @var string PHP namespace separator + */ + protected $namespaceSeparator = '\\'; + + /** + * Creates a new ClassLoader that loads classes of the + * specified namespace from the specified include path. + * + * If no include path is given, the ClassLoader relies on the PHP include_path. + * If neither a namespace nor an include path is given, the ClassLoader will + * be responsible for loading all classes, thereby relying on the PHP include_path. + * + * @param string $ns The namespace of the classes to load. + * @param string $includePath The base include path to use. + */ + public function __construct($ns = null, $includePath = null) + { + $this->namespace = $ns; + $this->includePath = $includePath; + } + + /** + * Sets the namespace separator used by classes in the namespace of this ClassLoader. + * + * @param string $sep The separator to use. + */ + public function setNamespaceSeparator($sep) + { + $this->namespaceSeparator = $sep; + } + + /** + * Gets the namespace separator used by classes in the namespace of this ClassLoader. + * + * @return string + */ + public function getNamespaceSeparator() + { + return $this->namespaceSeparator; + } + + /** + * Sets the base include path for all class files in the namespace of this ClassLoader. + * + * @param string $includePath + */ + public function setIncludePath($includePath) + { + $this->includePath = $includePath; + } + + /** + * Gets the base include path for all class files in the namespace of this ClassLoader. + * + * @return string + */ + public function getIncludePath() + { + return $this->includePath; + } + + /** + * Sets the file extension of class files in the namespace of this ClassLoader. + * + * @param string $fileExtension + */ + public function setFileExtension($fileExtension) + { + $this->fileExtension = $fileExtension; + } + + /** + * Gets the file extension of class files in the namespace of this ClassLoader. + * + * @return string + */ + public function getFileExtension() + { + return $this->fileExtension; + } + + /** + * Registers this ClassLoader on the SPL autoload stack. + */ + public function register() + { + spl_autoload_register(array($this, 'loadClass')); + } + + /** + * Removes this ClassLoader from the SPL autoload stack. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $classname The name of the class to load. + * @return boolean TRUE if the class has been successfully loaded, FALSE otherwise. + */ + public function loadClass($className) + { + if ($this->namespace !== null && strpos($className, $this->namespace.$this->namespaceSeparator) !== 0) { + return false; + } + + require ($this->includePath !== null ? $this->includePath . DIRECTORY_SEPARATOR : '') + . str_replace($this->namespaceSeparator, DIRECTORY_SEPARATOR, $className) + . $this->fileExtension; + + return true; + } + + /** + * Asks this ClassLoader whether it can potentially load the class (file) with + * the given name. + * + * @param string $className The fully-qualified name of the class. + * @return boolean TRUE if this ClassLoader can load the class, FALSE otherwise. + */ + public function canLoadClass($className) + { + if ($this->namespace !== null && strpos($className, $this->namespace.$this->namespaceSeparator) !== 0) { + return false; + } + + $file = str_replace($this->namespaceSeparator, DIRECTORY_SEPARATOR, $className) . $this->fileExtension; + + if ($this->includePath !== null) { + return file_exists($this->includePath . DIRECTORY_SEPARATOR . $file); + } + + return (false !== stream_resolve_include_path($file)); + } + + /** + * Checks whether a class with a given name exists. A class "exists" if it is either + * already defined in the current request or if there is an autoloader on the SPL + * autoload stack that is a) responsible for the class in question and b) is able to + * load a class file in which the class definition resides. + * + * If the class is not already defined, each autoloader in the SPL autoload stack + * is asked whether it is able to tell if the class exists. If the autoloader is + * a ClassLoader, {@link canLoadClass} is used, otherwise the autoload + * function of the autoloader is invoked and expected to return a value that + * evaluates to TRUE if the class (file) exists. As soon as one autoloader reports + * that the class exists, TRUE is returned. + * + * Note that, depending on what kinds of autoloaders are installed on the SPL + * autoload stack, the class (file) might already be loaded as a result of checking + * for its existence. This is not the case with a ClassLoader, who separates + * these responsibilities. + * + * @param string $className The fully-qualified name of the class. + * @return boolean TRUE if the class exists as per the definition given above, FALSE otherwise. + */ + public static function classExists($className) + { + if (class_exists($className, false) || interface_exists($className, false)) { + return true; + } + + foreach (spl_autoload_functions() as $loader) { + if (is_array($loader)) { // array(???, ???) + if (is_object($loader[0])) { + if ($loader[0] instanceof ClassLoader) { // array($obj, 'methodName') + if ($loader[0]->canLoadClass($className)) { + return true; + } + } else if ($loader[0]->{$loader[1]}($className)) { + return true; + } + } else if ($loader[0]::$loader[1]($className)) { // array('ClassName', 'methodName') + return true; + } + } else if ($loader instanceof \Closure) { // function($className) {..} + if ($loader($className)) { + return true; + } + } else if (is_string($loader) && $loader($className)) { // "MyClass::loadClass" + return true; + } + } + + return class_exists($className, false) || interface_exists($className, false); + } + + /** + * Gets the ClassLoader from the SPL autoload stack that is responsible + * for (and is able to load) the class with the given name. + * + * @param string $className The name of the class. + * @return The ClassLoader for the class or NULL if no such ClassLoader exists. + */ + public static function getClassLoader($className) + { + foreach (spl_autoload_functions() as $loader) { + if (is_array($loader) + && $loader[0] instanceof ClassLoader + && $loader[0]->canLoadClass($className) + ) { + return $loader[0]; + } + } + + return null; + } +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Collections/ArrayCollection.php b/vendor/doctrine/common/lib/Doctrine/Common/Collections/ArrayCollection.php new file mode 100644 index 0000000..2a7d4ea --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Collections/ArrayCollection.php @@ -0,0 +1,447 @@ +. + */ + +namespace Doctrine\Common\Collections; + +use Closure, ArrayIterator; + +/** + * An ArrayCollection is a Collection implementation that wraps a regular PHP array. + * + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class ArrayCollection implements Collection +{ + /** + * An array containing the entries of this collection. + * + * @var array + */ + private $_elements; + + /** + * Initializes a new ArrayCollection. + * + * @param array $elements + */ + public function __construct(array $elements = array()) + { + $this->_elements = $elements; + } + + /** + * Gets the PHP array representation of this collection. + * + * @return array The PHP array representation of this collection. + */ + public function toArray() + { + return $this->_elements; + } + + /** + * Sets the internal iterator to the first element in the collection and + * returns this element. + * + * @return mixed + */ + public function first() + { + return reset($this->_elements); + } + + /** + * Sets the internal iterator to the last element in the collection and + * returns this element. + * + * @return mixed + */ + public function last() + { + return end($this->_elements); + } + + /** + * Gets the current key/index at the current internal iterator position. + * + * @return mixed + */ + public function key() + { + return key($this->_elements); + } + + /** + * Moves the internal iterator position to the next element. + * + * @return mixed + */ + public function next() + { + return next($this->_elements); + } + + /** + * Gets the element of the collection at the current internal iterator position. + * + * @return mixed + */ + public function current() + { + return current($this->_elements); + } + + /** + * Removes an element with a specific key/index from the collection. + * + * @param mixed $key + * @return mixed The removed element or NULL, if no element exists for the given key. + */ + public function remove($key) + { + if (isset($this->_elements[$key])) { + $removed = $this->_elements[$key]; + unset($this->_elements[$key]); + + return $removed; + } + + return null; + } + + /** + * Removes the specified element from the collection, if it is found. + * + * @param mixed $element The element to remove. + * @return boolean TRUE if this collection contained the specified element, FALSE otherwise. + */ + public function removeElement($element) + { + $key = array_search($element, $this->_elements, true); + + if ($key !== false) { + unset($this->_elements[$key]); + + return true; + } + + return false; + } + + /** + * ArrayAccess implementation of offsetExists() + * + * @see containsKey() + */ + public function offsetExists($offset) + { + return $this->containsKey($offset); + } + + /** + * ArrayAccess implementation of offsetGet() + * + * @see get() + */ + public function offsetGet($offset) + { + return $this->get($offset); + } + + /** + * ArrayAccess implementation of offsetGet() + * + * @see add() + * @see set() + */ + public function offsetSet($offset, $value) + { + if ( ! isset($offset)) { + return $this->add($value); + } + return $this->set($offset, $value); + } + + /** + * ArrayAccess implementation of offsetUnset() + * + * @see remove() + */ + public function offsetUnset($offset) + { + return $this->remove($offset); + } + + /** + * Checks whether the collection contains a specific key/index. + * + * @param mixed $key The key to check for. + * @return boolean TRUE if the given key/index exists, FALSE otherwise. + */ + public function containsKey($key) + { + return isset($this->_elements[$key]); + } + + /** + * Checks whether the given element is contained in the collection. + * Only element values are compared, not keys. The comparison of two elements + * is strict, that means not only the value but also the type must match. + * For objects this means reference equality. + * + * @param mixed $element + * @return boolean TRUE if the given element is contained in the collection, + * FALSE otherwise. + */ + public function contains($element) + { + foreach ($this->_elements as $collectionElement) { + if ($element === $collectionElement) { + return true; + } + } + + return false; + } + + /** + * Tests for the existance of an element that satisfies the given predicate. + * + * @param Closure $p The predicate. + * @return boolean TRUE if the predicate is TRUE for at least one element, FALSE otherwise. + */ + public function exists(Closure $p) + { + foreach ($this->_elements as $key => $element) { + if ($p($key, $element)) { + return true; + } + } + return false; + } + + /** + * Searches for a given element and, if found, returns the corresponding key/index + * of that element. The comparison of two elements is strict, that means not + * only the value but also the type must match. + * For objects this means reference equality. + * + * @param mixed $element The element to search for. + * @return mixed The key/index of the element or FALSE if the element was not found. + */ + public function indexOf($element) + { + return array_search($element, $this->_elements, true); + } + + /** + * Gets the element with the given key/index. + * + * @param mixed $key The key. + * @return mixed The element or NULL, if no element exists for the given key. + */ + public function get($key) + { + if (isset($this->_elements[$key])) { + return $this->_elements[$key]; + } + return null; + } + + /** + * Gets all keys/indexes of the collection elements. + * + * @return array + */ + public function getKeys() + { + return array_keys($this->_elements); + } + + /** + * Gets all elements. + * + * @return array + */ + public function getValues() + { + return array_values($this->_elements); + } + + /** + * Returns the number of elements in the collection. + * + * Implementation of the Countable interface. + * + * @return integer The number of elements in the collection. + */ + public function count() + { + return count($this->_elements); + } + + /** + * Adds/sets an element in the collection at the index / with the specified key. + * + * When the collection is a Map this is like put(key,value)/add(key,value). + * When the collection is a List this is like add(position,value). + * + * @param mixed $key + * @param mixed $value + */ + public function set($key, $value) + { + $this->_elements[$key] = $value; + } + + /** + * Adds an element to the collection. + * + * @param mixed $value + * @return boolean Always TRUE. + */ + public function add($value) + { + $this->_elements[] = $value; + return true; + } + + /** + * Checks whether the collection is empty. + * + * Note: This is preferrable over count() == 0. + * + * @return boolean TRUE if the collection is empty, FALSE otherwise. + */ + public function isEmpty() + { + return ! $this->_elements; + } + + /** + * Gets an iterator for iterating over the elements in the collection. + * + * @return ArrayIterator + */ + public function getIterator() + { + return new ArrayIterator($this->_elements); + } + + /** + * Applies the given function to each element in the collection and returns + * a new collection with the elements returned by the function. + * + * @param Closure $func + * @return Collection + */ + public function map(Closure $func) + { + return new static(array_map($func, $this->_elements)); + } + + /** + * Returns all the elements of this collection that satisfy the predicate p. + * The order of the elements is preserved. + * + * @param Closure $p The predicate used for filtering. + * @return Collection A collection with the results of the filter operation. + */ + public function filter(Closure $p) + { + return new static(array_filter($this->_elements, $p)); + } + + /** + * Applies the given predicate p to all elements of this collection, + * returning true, if the predicate yields true for all elements. + * + * @param Closure $p The predicate. + * @return boolean TRUE, if the predicate yields TRUE for all elements, FALSE otherwise. + */ + public function forAll(Closure $p) + { + foreach ($this->_elements as $key => $element) { + if ( ! $p($key, $element)) { + return false; + } + } + + return true; + } + + /** + * Partitions this collection in two collections according to a predicate. + * Keys are preserved in the resulting collections. + * + * @param Closure $p The predicate on which to partition. + * @return array An array with two elements. The first element contains the collection + * of elements where the predicate returned TRUE, the second element + * contains the collection of elements where the predicate returned FALSE. + */ + public function partition(Closure $p) + { + $coll1 = $coll2 = array(); + foreach ($this->_elements as $key => $element) { + if ($p($key, $element)) { + $coll1[$key] = $element; + } else { + $coll2[$key] = $element; + } + } + return array(new static($coll1), new static($coll2)); + } + + /** + * Returns a string representation of this object. + * + * @return string + */ + public function __toString() + { + return __CLASS__ . '@' . spl_object_hash($this); + } + + /** + * Clears the collection. + */ + public function clear() + { + $this->_elements = array(); + } + + /** + * Extract a slice of $length elements starting at position $offset from the Collection. + * + * If $length is null it returns all elements from $offset to the end of the Collection. + * Keys have to be preserved by this method. Calling this method will only return the + * selected slice and NOT change the elements contained in the collection slice is called on. + * + * @param int $offset + * @param int $length + * @return array + */ + public function slice($offset, $length = null) + { + return array_slice($this->_elements, $offset, $length, true); + } +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Collections/Collection.php b/vendor/doctrine/common/lib/Doctrine/Common/Collections/Collection.php new file mode 100644 index 0000000..9fca659 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Collections/Collection.php @@ -0,0 +1,243 @@ +. + */ + +namespace Doctrine\Common\Collections; + +use Closure, Countable, IteratorAggregate, ArrayAccess; + +/** + * The missing (SPL) Collection/Array/OrderedMap interface. + * + * A Collection resembles the nature of a regular PHP array. That is, + * it is essentially an ordered map that can also be used + * like a list. + * + * A Collection has an internal iterator just like a PHP array. In addition, + * a Collection can be iterated with external iterators, which is preferrable. + * To use an external iterator simply use the foreach language construct to + * iterate over the collection (which calls {@link getIterator()} internally) or + * explicitly retrieve an iterator though {@link getIterator()} which can then be + * used to iterate over the collection. + * You can not rely on the internal iterator of the collection being at a certain + * position unless you explicitly positioned it before. Prefer iteration with + * external iterators. + * + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +interface Collection extends Countable, IteratorAggregate, ArrayAccess +{ + /** + * Adds an element at the end of the collection. + * + * @param mixed $element The element to add. + * @return boolean Always TRUE. + */ + function add($element); + + /** + * Clears the collection, removing all elements. + */ + function clear(); + + /** + * Checks whether an element is contained in the collection. + * This is an O(n) operation, where n is the size of the collection. + * + * @param mixed $element The element to search for. + * @return boolean TRUE if the collection contains the element, FALSE otherwise. + */ + function contains($element); + + /** + * Checks whether the collection is empty (contains no elements). + * + * @return boolean TRUE if the collection is empty, FALSE otherwise. + */ + function isEmpty(); + + /** + * Removes the element at the specified index from the collection. + * + * @param string|integer $key The kex/index of the element to remove. + * @return mixed The removed element or NULL, if the collection did not contain the element. + */ + function remove($key); + + /** + * Removes the specified element from the collection, if it is found. + * + * @param mixed $element The element to remove. + * @return boolean TRUE if this collection contained the specified element, FALSE otherwise. + */ + function removeElement($element); + + /** + * Checks whether the collection contains an element with the specified key/index. + * + * @param string|integer $key The key/index to check for. + * @return boolean TRUE if the collection contains an element with the specified key/index, + * FALSE otherwise. + */ + function containsKey($key); + + /** + * Gets the element at the specified key/index. + * + * @param string|integer $key The key/index of the element to retrieve. + * @return mixed + */ + function get($key); + + /** + * Gets all keys/indices of the collection. + * + * @return array The keys/indices of the collection, in the order of the corresponding + * elements in the collection. + */ + function getKeys(); + + /** + * Gets all values of the collection. + * + * @return array The values of all elements in the collection, in the order they + * appear in the collection. + */ + function getValues(); + + /** + * Sets an element in the collection at the specified key/index. + * + * @param string|integer $key The key/index of the element to set. + * @param mixed $value The element to set. + */ + function set($key, $value); + + /** + * Gets a native PHP array representation of the collection. + * + * @return array + */ + function toArray(); + + /** + * Sets the internal iterator to the first element in the collection and + * returns this element. + * + * @return mixed + */ + function first(); + + /** + * Sets the internal iterator to the last element in the collection and + * returns this element. + * + * @return mixed + */ + function last(); + + /** + * Gets the key/index of the element at the current iterator position. + * + */ + function key(); + + /** + * Gets the element of the collection at the current iterator position. + * + */ + function current(); + + /** + * Moves the internal iterator position to the next element. + * + */ + function next(); + + /** + * Tests for the existence of an element that satisfies the given predicate. + * + * @param Closure $p The predicate. + * @return boolean TRUE if the predicate is TRUE for at least one element, FALSE otherwise. + */ + function exists(Closure $p); + + /** + * Returns all the elements of this collection that satisfy the predicate p. + * The order of the elements is preserved. + * + * @param Closure $p The predicate used for filtering. + * @return Collection A collection with the results of the filter operation. + */ + function filter(Closure $p); + + /** + * Applies the given predicate p to all elements of this collection, + * returning true, if the predicate yields true for all elements. + * + * @param Closure $p The predicate. + * @return boolean TRUE, if the predicate yields TRUE for all elements, FALSE otherwise. + */ + function forAll(Closure $p); + + /** + * Applies the given function to each element in the collection and returns + * a new collection with the elements returned by the function. + * + * @param Closure $func + * @return Collection + */ + function map(Closure $func); + + /** + * Partitions this collection in two collections according to a predicate. + * Keys are preserved in the resulting collections. + * + * @param Closure $p The predicate on which to partition. + * @return array An array with two elements. The first element contains the collection + * of elements where the predicate returned TRUE, the second element + * contains the collection of elements where the predicate returned FALSE. + */ + function partition(Closure $p); + + /** + * Gets the index/key of a given element. The comparison of two elements is strict, + * that means not only the value but also the type must match. + * For objects this means reference equality. + * + * @param mixed $element The element to search for. + * @return mixed The key/index of the element or FALSE if the element was not found. + */ + function indexOf($element); + + /** + * Extract a slice of $length elements starting at position $offset from the Collection. + * + * If $length is null it returns all elements from $offset to the end of the Collection. + * Keys have to be preserved by this method. Calling this method will only return the + * selected slice and NOT change the elements contained in the collection slice is called on. + * + * @param int $offset + * @param int $length + * @return array + */ + function slice($offset, $length = null); +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/CommonException.php b/vendor/doctrine/common/lib/Doctrine/Common/CommonException.php new file mode 100644 index 0000000..8c5669b --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/CommonException.php @@ -0,0 +1,28 @@ +. + */ + +namespace Doctrine\Common; + +/** + * Base exception class for package Doctrine\Common + * @author heinrich + * + */ +class CommonException extends \Exception { +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Comparable.php b/vendor/doctrine/common/lib/Doctrine/Common/Comparable.php new file mode 100644 index 0000000..bc95d30 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Comparable.php @@ -0,0 +1,47 @@ +. + */ + + +namespace Doctrine\Common; + +/** + * Comparable interface that allows to compare two value objects to each other for similarity. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.2 + * @author Benjamin Eberlei + * @author Guilherme Blanco + */ +interface Comparable +{ + /** + * Compare the current object to the passed $other. + * + * Returns 0 if they are semantically equal, 1 if the other object + * is less than the current one, or -1 if its more than the current one. + * + * This method should not check for identity using ===, only for semantical equality for example + * when two different DateTime instances point to the exact same Date + TZ. + * + * @return int + */ + public function compareTo($other); +} + diff --git a/vendor/doctrine/common/lib/Doctrine/Common/EventArgs.php b/vendor/doctrine/common/lib/Doctrine/Common/EventArgs.php new file mode 100644 index 0000000..6a3c069 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/EventArgs.php @@ -0,0 +1,69 @@ +. + */ + +namespace Doctrine\Common; + +/** + * EventArgs is the base class for classes containing event data. + * + * This class contains no event data. It is used by events that do not pass state + * information to an event handler when an event is raised. The single empty EventArgs + * instance can be obtained through {@link getEmptyInstance}. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class EventArgs +{ + /** + * @var EventArgs Single instance of EventArgs + * @static + */ + private static $_emptyEventArgsInstance; + + /** + * Gets the single, empty and immutable EventArgs instance. + * + * This instance will be used when events are dispatched without any parameter, + * like this: EventManager::dispatchEvent('eventname'); + * + * The benefit from this is that only one empty instance is instantiated and shared + * (otherwise there would be instances for every dispatched in the abovementioned form) + * + * @see EventManager::dispatchEvent + * @link http://msdn.microsoft.com/en-us/library/system.eventargs.aspx + * @static + * @return EventArgs + */ + public static function getEmptyInstance() + { + if ( ! self::$_emptyEventArgsInstance) { + self::$_emptyEventArgsInstance = new EventArgs; + } + + return self::$_emptyEventArgsInstance; + } +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/EventManager.php b/vendor/doctrine/common/lib/Doctrine/Common/EventManager.php new file mode 100644 index 0000000..a1f11ed --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/EventManager.php @@ -0,0 +1,136 @@ +. + */ + +namespace Doctrine\Common; + +/** + * The EventManager is the central point of Doctrine's event listener system. + * Listeners are registered on the manager and events are dispatched through the + * manager. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class EventManager +{ + /** + * Map of registered listeners. + * => + * + * @var array + */ + private $_listeners = array(); + + /** + * Dispatches an event to all registered listeners. + * + * @param string $eventName The name of the event to dispatch. The name of the event is + * the name of the method that is invoked on listeners. + * @param EventArgs $eventArgs The event arguments to pass to the event handlers/listeners. + * If not supplied, the single empty EventArgs instance is used. + * @return boolean + */ + public function dispatchEvent($eventName, EventArgs $eventArgs = null) + { + if (isset($this->_listeners[$eventName])) { + $eventArgs = $eventArgs === null ? EventArgs::getEmptyInstance() : $eventArgs; + + foreach ($this->_listeners[$eventName] as $listener) { + $listener->$eventName($eventArgs); + } + } + } + + /** + * Gets the listeners of a specific event or all listeners. + * + * @param string $event The name of the event. + * @return array The event listeners for the specified event, or all event listeners. + */ + public function getListeners($event = null) + { + return $event ? $this->_listeners[$event] : $this->_listeners; + } + + /** + * Checks whether an event has any registered listeners. + * + * @param string $event + * @return boolean TRUE if the specified event has any listeners, FALSE otherwise. + */ + public function hasListeners($event) + { + return isset($this->_listeners[$event]) && $this->_listeners[$event]; + } + + /** + * Adds an event listener that listens on the specified events. + * + * @param string|array $events The event(s) to listen on. + * @param object $listener The listener object. + */ + public function addEventListener($events, $listener) + { + // Picks the hash code related to that listener + $hash = spl_object_hash($listener); + + foreach ((array) $events as $event) { + // Overrides listener if a previous one was associated already + // Prevents duplicate listeners on same event (same instance only) + $this->_listeners[$event][$hash] = $listener; + } + } + + /** + * Removes an event listener from the specified events. + * + * @param string|array $events + * @param object $listener + */ + public function removeEventListener($events, $listener) + { + // Picks the hash code related to that listener + $hash = spl_object_hash($listener); + + foreach ((array) $events as $event) { + // Check if actually have this listener associated + if (isset($this->_listeners[$event][$hash])) { + unset($this->_listeners[$event][$hash]); + } + } + } + + /** + * Adds an EventSubscriber. The subscriber is asked for all the events he is + * interested in and added as a listener for these events. + * + * @param Doctrine\Common\EventSubscriber $subscriber The subscriber. + */ + public function addEventSubscriber(EventSubscriber $subscriber) + { + $this->addEventListener($subscriber->getSubscribedEvents(), $subscriber); + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/EventSubscriber.php b/vendor/doctrine/common/lib/Doctrine/Common/EventSubscriber.php new file mode 100644 index 0000000..ed3383f --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/EventSubscriber.php @@ -0,0 +1,45 @@ +. + */ + +namespace Doctrine\Common; + +/** + * An EventSubscriber knows himself what events he is interested in. + * If an EventSubscriber is added to an EventManager, the manager invokes + * {@link getSubscribedEvents} and registers the subscriber as a listener for all + * returned events. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +interface EventSubscriber +{ + /** + * Returns an array of events this subscriber wants to listen to. + * + * @return array + */ + function getSubscribedEvents(); +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Lexer.php b/vendor/doctrine/common/lib/Doctrine/Common/Lexer.php new file mode 100644 index 0000000..8df3b84 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Lexer.php @@ -0,0 +1,266 @@ +. + */ + +namespace Doctrine\Common; + +/** + * Base class for writing simple lexers, i.e. for creating small DSLs. + * + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @todo Rename: AbstractLexer + */ +abstract class Lexer +{ + /** + * @var array Array of scanned tokens + */ + private $tokens = array(); + + /** + * @var integer Current lexer position in input string + */ + private $position = 0; + + /** + * @var integer Current peek of current lexer position + */ + private $peek = 0; + + /** + * @var array The next token in the input. + */ + public $lookahead; + + /** + * @var array The last matched/seen token. + */ + public $token; + + /** + * Sets the input data to be tokenized. + * + * The Lexer is immediately reset and the new input tokenized. + * Any unprocessed tokens from any previous input are lost. + * + * @param string $input The input to be tokenized. + */ + public function setInput($input) + { + $this->tokens = array(); + $this->reset(); + $this->scan($input); + } + + /** + * Resets the lexer. + */ + public function reset() + { + $this->lookahead = null; + $this->token = null; + $this->peek = 0; + $this->position = 0; + } + + /** + * Resets the peek pointer to 0. + */ + public function resetPeek() + { + $this->peek = 0; + } + + /** + * Resets the lexer position on the input to the given position. + * + * @param integer $position Position to place the lexical scanner + */ + public function resetPosition($position = 0) + { + $this->position = $position; + } + + /** + * Checks whether a given token matches the current lookahead. + * + * @param integer|string $token + * @return boolean + */ + public function isNextToken($token) + { + return null !== $this->lookahead && $this->lookahead['type'] === $token; + } + + /** + * Checks whether any of the given tokens matches the current lookahead + * + * @param array $tokens + * @return boolean + */ + public function isNextTokenAny(array $tokens) + { + return null !== $this->lookahead && in_array($this->lookahead['type'], $tokens, true); + } + + /** + * Moves to the next token in the input string. + * + * A token is an associative array containing three items: + * - 'value' : the string value of the token in the input string + * - 'type' : the type of the token (identifier, numeric, string, input + * parameter, none) + * - 'position' : the position of the token in the input string + * + * @return array|null the next token; null if there is no more tokens left + */ + public function moveNext() + { + $this->peek = 0; + $this->token = $this->lookahead; + $this->lookahead = (isset($this->tokens[$this->position])) + ? $this->tokens[$this->position++] : null; + + return $this->lookahead !== null; + } + + /** + * Tells the lexer to skip input tokens until it sees a token with the given value. + * + * @param $type The token type to skip until. + */ + public function skipUntil($type) + { + while ($this->lookahead !== null && $this->lookahead['type'] !== $type) { + $this->moveNext(); + } + } + + /** + * Checks if given value is identical to the given token + * + * @param mixed $value + * @param integer $token + * @return boolean + */ + public function isA($value, $token) + { + return $this->getType($value) === $token; + } + + /** + * Moves the lookahead token forward. + * + * @return array | null The next token or NULL if there are no more tokens ahead. + */ + public function peek() + { + if (isset($this->tokens[$this->position + $this->peek])) { + return $this->tokens[$this->position + $this->peek++]; + } else { + return null; + } + } + + /** + * Peeks at the next token, returns it and immediately resets the peek. + * + * @return array|null The next token or NULL if there are no more tokens ahead. + */ + public function glimpse() + { + $peek = $this->peek(); + $this->peek = 0; + return $peek; + } + + /** + * Scans the input string for tokens. + * + * @param string $input a query string + */ + protected function scan($input) + { + static $regex; + + if ( ! isset($regex)) { + $regex = '/(' . implode(')|(', $this->getCatchablePatterns()) . ')|' + . implode('|', $this->getNonCatchablePatterns()) . '/i'; + } + + $flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE; + $matches = preg_split($regex, $input, -1, $flags); + + foreach ($matches as $match) { + // Must remain before 'value' assignment since it can change content + $type = $this->getType($match[0]); + + $this->tokens[] = array( + 'value' => $match[0], + 'type' => $type, + 'position' => $match[1], + ); + } + } + + /** + * Gets the literal for a given token. + * + * @param integer $token + * @return string + */ + public function getLiteral($token) + { + $className = get_class($this); + $reflClass = new \ReflectionClass($className); + $constants = $reflClass->getConstants(); + + foreach ($constants as $name => $value) { + if ($value === $token) { + return $className . '::' . $name; + } + } + + return $token; + } + + /** + * Lexical catchable patterns. + * + * @return array + */ + abstract protected function getCatchablePatterns(); + + /** + * Lexical non-catchable patterns. + * + * @return array + */ + abstract protected function getNonCatchablePatterns(); + + /** + * Retrieve token type. Also processes the token value if necessary. + * + * @param string $value + * @return integer + */ + abstract protected function getType(&$value); +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/NotifyPropertyChanged.php b/vendor/doctrine/common/lib/Doctrine/Common/NotifyPropertyChanged.php new file mode 100644 index 0000000..93e504a --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/NotifyPropertyChanged.php @@ -0,0 +1,45 @@ +. + */ + +namespace Doctrine\Common; + +/** + * Contract for classes that provide the service of notifying listeners of + * changes to their properties. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +interface NotifyPropertyChanged +{ + /** + * Adds a listener that wants to be notified about property changes. + * + * @param PropertyChangedListener $listener + */ + function addPropertyChangedListener(PropertyChangedListener $listener); +} + diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/AbstractManagerRegistry.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/AbstractManagerRegistry.php new file mode 100644 index 0000000..f045286 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/AbstractManagerRegistry.php @@ -0,0 +1,218 @@ +. + */ + +namespace Doctrine\Common\Persistence; + +use Doctrine\Common\Persistence\ManagerRegistry; + +/** + * Abstract implementation of the ManagerRegistry contract. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.2 + * @author Fabien Potencier + * @author Benjamin Eberlei + * @author Lukas Kahwe Smith + */ +abstract class AbstractManagerRegistry implements ManagerRegistry +{ + private $name; + private $connections; + private $managers; + private $defaultConnection; + private $defaultManager; + private $proxyInterfaceName; + + public function __construct($name, array $connections, array $managers, $defaultConnection, $defaultManager, $proxyInterfaceName) + { + $this->name = $name; + $this->connections = $connections; + $this->managers = $managers; + $this->defaultConnection = $defaultConnection; + $this->defaultManager = $defaultManager; + $this->proxyInterfaceName = $proxyInterfaceName; + } + + /** + * Fetches/creates the given services + * + * A service in this context is connection or a manager instance + * + * @param string $name name of the service + * @return object instance of the given service + */ + abstract protected function getService($name); + + /** + * Resets the given services + * + * A service in this context is connection or a manager instance + * + * @param string $name name of the service + * @return void + */ + abstract protected function resetService($name); + + /** + * Get the name of the registry + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @inheritdoc + */ + public function getConnection($name = null) + { + if (null === $name) { + $name = $this->defaultConnection; + } + + if (!isset($this->connections[$name])) { + throw new \InvalidArgumentException(sprintf('Doctrine %s Connection named "%s" does not exist.', $this->name, $name)); + } + + return $this->getService($this->connections[$name]); + } + + /** + * @inheritdoc + */ + public function getConnectionNames() + { + return $this->connections; + } + + /** + * @inheritdoc + */ + public function getConnections() + { + $connections = array(); + foreach ($this->connections as $name => $id) { + $connections[$name] = $this->getService($id); + } + + return $connections; + } + + /** + * @inheritdoc + */ + public function getDefaultConnectionName() + { + return $this->defaultConnection; + } + + /** + * @inheritdoc + */ + public function getDefaultManagerName() + { + return $this->defaultManager; + } + + /** + * @inheritdoc + */ + public function getManager($name = null) + { + if (null === $name) { + $name = $this->defaultManager; + } + + if (!isset($this->managers[$name])) { + throw new \InvalidArgumentException(sprintf('Doctrine %s Manager named "%s" does not exist.', $this->name, $name)); + } + + return $this->getService($this->managers[$name]); + } + + /** + * @inheritdoc + */ + public function getManagerForClass($class) + { + $proxyClass = new \ReflectionClass($class); + if ($proxyClass->implementsInterface($this->proxyInterfaceName)) { + $class = $proxyClass->getParentClass()->getName(); + } + + foreach ($this->managers as $id) { + $manager = $this->getService($id); + + if (!$manager->getMetadataFactory()->isTransient($class)) { + return $manager; + } + } + } + + /** + * @inheritdoc + */ + public function getManagerNames() + { + return $this->managers; + } + + /** + * @inheritdoc + */ + public function getManagers() + { + $dms = array(); + foreach ($this->managers as $name => $id) { + $dms[$name] = $this->getService($id); + } + + return $dms; + } + + /** + * @inheritdoc + */ + public function getRepository($persistentObjectName, $persistentManagerName = null) + { + return $this->getManager($persistentManagerName)->getRepository($persistentObjectName); + } + + /** + * @inheritdoc + */ + public function resetManager($name = null) + { + if (null === $name) { + $name = $this->defaultManager; + } + + if (!isset($this->managers[$name])) { + throw new \InvalidArgumentException(sprintf('Doctrine %s Manager named "%s" does not exist.', $this->name, $name)); + } + + // force the creation of a new document manager + // if the current one is closed + $this->resetService($this->managers[$name]); + } +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/ConnectionRegistry.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/ConnectionRegistry.php new file mode 100644 index 0000000..a47727f --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/ConnectionRegistry.php @@ -0,0 +1,63 @@ +. + */ + +namespace Doctrine\Common\Persistence; + +/** + * Contract covering connection for a Doctrine persistence layer ManagerRegistry class to implement. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.2 + * @author Fabien Potencier + * @author Benjamin Eberlei + * @author Lukas Kahwe Smith + */ +interface ConnectionRegistry +{ + /** + * Gets the default connection name. + * + * @return string The default connection name + */ + function getDefaultConnectionName(); + + /** + * Gets the named connection. + * + * @param string $name The connection name (null for the default one) + * + * @return Connection + */ + function getConnection($name = null); + + /** + * Gets an array of all registered connections + * + * @return array An array of Connection instances + */ + function getConnections(); + + /** + * Gets all connection names. + * + * @return array An array of connection names + */ + function getConnectionNames(); +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/LifecycleEventArgs.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/LifecycleEventArgs.php new file mode 100644 index 0000000..8055b66 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/LifecycleEventArgs.php @@ -0,0 +1,77 @@ +. +*/ + +namespace Doctrine\Common\Persistence\Event; + +use Doctrine\Common\EventArgs; +use Doctrine\Common\Persistence\ObjectManager; + +/** + * Lifecycle Events are triggered by the UnitOfWork during lifecycle transitions + * of entities. + * + * @link www.doctrine-project.org + * @since 2.2 + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class LifecycleEventArgs extends EventArgs +{ + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * @var object + */ + private $entity; + + /** + * Constructor + * + * @param object $entity + * @param ObjectManager $objectManager + */ + public function __construct($entity, ObjectManager $objectManager) + { + $this->entity = $entity; + $this->objectManager = $objectManager; + } + + /** + * Retireve associated Entity. + * + * @return object + */ + public function getEntity() + { + return $this->entity; + } + + /** + * Retrieve associated ObjectManager. + * + * @return ObjectManager + */ + public function getObjectManager() + { + return $this->objectManager; + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/LoadClassMetadataEventArgs.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/LoadClassMetadataEventArgs.php new file mode 100644 index 0000000..4a18d16 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/LoadClassMetadataEventArgs.php @@ -0,0 +1,76 @@ +. + */ + +namespace Doctrine\Common\Persistence\Event; + +use Doctrine\Common\EventArgs; +use Doctrine\Common\Persistence\ObjectManager; +use Doctrine\Common\Persistence\Mapping\ClassMetadata; + +/** + * Class that holds event arguments for a loadMetadata event. + * + * @author Jonathan H. Wage + * @since 2.2 + */ +class LoadClassMetadataEventArgs extends EventArgs +{ + /** + * @var ClassMetadata + */ + private $classMetadata; + + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * Constructor. + * + * @param ClasseMetadata $classMetadata + * @param ObjectManager $objectManager + */ + public function __construct(ClassMetadata $classMetadata, ObjectManager $objectManager) + { + $this->classMetadata = $classMetadata; + $this->objectManager = $objectManager; + } + + /** + * Retrieve associated ClassMetadata. + * + * @return ClassMetadata + */ + public function getClassMetadata() + { + return $this->classMetadata; + } + + /** + * Retrieve associated ObjectManager. + * + * @return ObjectManager + */ + public function getObjectManager() + { + return $this->objectManager; + } +} + diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/ManagerEventArgs.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/ManagerEventArgs.php new file mode 100644 index 0000000..33c4d79 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/ManagerEventArgs.php @@ -0,0 +1,59 @@ +. +*/ + +namespace Doctrine\Common\Persistence\Event; + +use Doctrine\Common\Persistence\ObjectManager; + +/** + * Provides event arguments for the preFlush event. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.2 + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class ManagerEventArgs extends \Doctrine\Common\EventArgs +{ + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * Constructor. + * + * @param ObjectManager $objectManager + */ + public function __construct(ObjectManager $objectManager) + { + $this->objectManager = $objectManager; + } + + /** + * Retrieve associated ObjectManager. + * + * @return ObjectManager + */ + public function getObjectManager() + { + return $this->objectManager; + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/OnClearEventArgs.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/OnClearEventArgs.php new file mode 100644 index 0000000..f67ab50 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/OnClearEventArgs.php @@ -0,0 +1,84 @@ +. + */ + +namespace Doctrine\Common\Persistence\Event; + +/** + * Provides event arguments for the onClear event. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.2 + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class OnClearEventArgs extends \Doctrine\Common\EventArgs +{ + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * @var string + */ + private $entityClass; + + /** + * Constructor. + * + * @param ObjectManager $objectManager + * @param string $entityClass Optional entity class + */ + public function __construct($objectManager, $entityClass = null) + { + $this->objectManager = $objectManager; + $this->entityClass = $entityClass; + } + + /** + * Retrieve associated ObjectManager. + * + * @return ObjectManager + */ + public function getObjectManager() + { + return $this->objectManager; + } + + /** + * Name of the entity class that is cleared, or empty if all are cleared. + * + * @return string + */ + public function getEntityClass() + { + return $this->entityClass; + } + + /** + * Check if event clears all entities. + * + * @return bool + */ + public function clearsAllEntities() + { + return ($this->entityClass === null); + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/PreUpdateEventArgs.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/PreUpdateEventArgs.php new file mode 100644 index 0000000..191d053 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/PreUpdateEventArgs.php @@ -0,0 +1,129 @@ +. + */ + +namespace Doctrine\Common\Persistence\Event; + +use Doctrine\Common\EventArgs, + Doctrine\Common\Persistence\ObjectManager; + +/** + * Class that holds event arguments for a preUpdate event. + * + * @author Guilherme Blanco + * @author Roman Borschel + * @author Benjamin Eberlei + * @since 2.2 + */ +class PreUpdateEventArgs extends LifecycleEventArgs +{ + /** + * @var array + */ + private $entityChangeSet; + + /** + * Constructor. + * + * @param object $entity + * @param ObjectManager $objectManager + * @param array $changeSet + */ + public function __construct($entity, ObjectManager $objectManager, array &$changeSet) + { + parent::__construct($entity, $objectManager); + + $this->entityChangeSet = &$changeSet; + } + + /** + * Retrieve entity changeset. + * + * @return array + */ + public function getEntityChangeSet() + { + return $this->entityChangeSet; + } + + /** + * Check if field has a changeset. + * + * @return boolean + */ + public function hasChangedField($field) + { + return isset($this->entityChangeSet[$field]); + } + + /** + * Get the old value of the changeset of the changed field. + * + * @param string $field + * @return mixed + */ + public function getOldValue($field) + { + $this->assertValidField($field); + + return $this->entityChangeSet[$field][0]; + } + + /** + * Get the new value of the changeset of the changed field. + * + * @param string $field + * @return mixed + */ + public function getNewValue($field) + { + $this->assertValidField($field); + + return $this->entityChangeSet[$field][1]; + } + + /** + * Set the new value of this field. + * + * @param string $field + * @param mixed $value + */ + public function setNewValue($field, $value) + { + $this->assertValidField($field); + + $this->entityChangeSet[$field][1] = $value; + } + + /** + * Assert the field exists in changeset. + * + * @param string $field + */ + private function assertValidField($field) + { + if ( ! isset($this->entityChangeSet[$field])) { + throw new \InvalidArgumentException(sprintf( + 'Field "%s" is not a valid field of the entity "%s" in PreUpdateEventArgs.', + $field, + get_class($this->getEntity()) + )); + } + } +} + diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/ManagerRegistry.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/ManagerRegistry.php new file mode 100644 index 0000000..4d92426 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/ManagerRegistry.php @@ -0,0 +1,112 @@ +. + */ + +namespace Doctrine\Common\Persistence; + +/** + * Contract covering object managers for a Doctrine persistence layer ManagerRegistry class to implement. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.2 + * @author Fabien Potencier + * @author Benjamin Eberlei + * @author Lukas Kahwe Smith + */ +interface ManagerRegistry extends ConnectionRegistry +{ + /** + * Gets the default object manager name. + * + * @return string The default object manager name + */ + function getDefaultManagerName(); + + /** + * Gets a named object manager. + * + * @param string $name The object manager name (null for the default one) + * + * @return \Doctrine\Common\Persistence\ObjectManager + */ + function getManager($name = null); + + /** + * Gets an array of all registered object managers + * + * @return array An array of ObjectManager instances + */ + function getManagers(); + + /** + * Resets a named object manager. + * + * This method is useful when an object manager has been closed + * because of a rollbacked transaction AND when you think that + * it makes sense to get a new one to replace the closed one. + * + * Be warned that you will get a brand new object manager as + * the existing one is not useable anymore. This means that any + * other object with a dependency on this object manager will + * hold an obsolete reference. You can inject the registry instead + * to avoid this problem. + * + * @param string $name The object manager name (null for the default one) + * + * @return \Doctrine\Common\Persistence\ObjectManager + */ + function resetManager($name = null); + + /** + * Resolves a registered namespace alias to the full namespace. + * + * This method looks for the alias in all registered object managers. + * + * @param string $alias The alias + * + * @return string The full namespace + */ + function getAliasNamespace($alias); + + /** + * Gets all connection names. + * + * @return array An array of connection names + */ + function getManagerNames(); + + /** + * Gets the ObjectRepository for an persistent object. + * + * @param string $persistentObject The name of the persistent object. + * @param string $persistentManagerName The object manager name (null for the default one) + * + * @return \Doctrine\Common\Persistence\ObjectRepository + */ + function getRepository($persistentObject, $persistentManagerName = null); + + /** + * Gets the object manager associated with a given class. + * + * @param string $class A persistent object class name + * + * @return \Doctrine\Common\Persistence\ObjectManager|null + */ + function getManagerForClass($class); +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php new file mode 100644 index 0000000..a2a6185 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php @@ -0,0 +1,359 @@ +. + */ + +namespace Doctrine\Common\Persistence\Mapping; + +use Doctrine\Common\Cache\Cache; + +/** + * The ClassMetadataFactory is used to create ClassMetadata objects that contain all the + * metadata mapping informations of a class which describes how a class should be mapped + * to a relational database. + * + * This class was abstracted from the ORM ClassMetadataFactory + * + * @since 2.2 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +abstract class AbstractClassMetadataFactory implements ClassMetadataFactory +{ + /** + * Salt used by specific Object Manager implementation. + * + * @var string + */ + protected $cacheSalt = "\$CLASSMETADATA"; + + /** + * @var \Doctrine\Common\Cache\Cache + */ + private $cacheDriver; + + /** + * @var array + */ + private $loadedMetadata = array(); + + /** + * @var bool + */ + protected $initialized = false; + + /** + * @var ReflectionService + */ + private $reflectionService; + + /** + * Sets the cache driver used by the factory to cache ClassMetadata instances. + * + * @param Doctrine\Common\Cache\Cache $cacheDriver + */ + public function setCacheDriver(Cache $cacheDriver = null) + { + $this->cacheDriver = $cacheDriver; + } + + /** + * Gets the cache driver used by the factory to cache ClassMetadata instances. + * + * @return Doctrine\Common\Cache\Cache + */ + public function getCacheDriver() + { + return $this->cacheDriver; + } + + /** + * Return an array of all the loaded metadata currently in memory. + * + * @return array + */ + public function getLoadedMetadata() + { + return $this->loadedMetadata; + } + + /** + * Forces the factory to load the metadata of all classes known to the underlying + * mapping driver. + * + * @return array The ClassMetadata instances of all mapped classes. + */ + public function getAllMetadata() + { + if ( ! $this->initialized) { + $this->initialize(); + } + + $driver = $this->getDriver(); + $metadata = array(); + foreach ($driver->getAllClassNames() as $className) { + $metadata[] = $this->getMetadataFor($className); + } + + return $metadata; + } + + /** + * Lazy initialization of this stuff, especially the metadata driver, + * since these are not needed at all when a metadata cache is active. + * + * @return void + */ + abstract protected function initialize(); + + /** + * Get the fully qualified class-name from the namespace alias. + * + * @param string $namespaceAlias + * @param string $simpleClassName + * @return string + */ + abstract protected function getFqcnFromAlias($namespaceAlias, $simpleClassName); + + /** + * Return the mapping driver implementation. + * + * @return MappingDriver + */ + abstract protected function getDriver(); + + /** + * Wakeup reflection after ClassMetadata gets unserialized from cache. + * + * @param ClassMetadata $class + * @param ReflectionService $reflService + * @return void + */ + abstract protected function wakeupReflection(ClassMetadata $class, ReflectionService $reflService); + + /** + * Initialize Reflection after ClassMetadata was constructed. + * + * @param ClassMetadata $class + * @param ReflectionSErvice $reflService + * @return void + */ + abstract protected function initializeReflection(ClassMetadata $class, ReflectionService $reflService); + + /** + * Gets the class metadata descriptor for a class. + * + * @param string $className The name of the class. + * @return Doctrine\Common\Persistence\Mapping\ClassMetadata + */ + public function getMetadataFor($className) + { + if ( ! isset($this->loadedMetadata[$className])) { + $realClassName = $className; + + // Check for namespace alias + if (strpos($className, ':') !== false) { + list($namespaceAlias, $simpleClassName) = explode(':', $className); + $realClassName = $this->getFqcnFromAlias($namespaceAlias, $simpleClassName); + + if (isset($this->loadedMetadata[$realClassName])) { + // We do not have the alias name in the map, include it + $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName]; + + return $this->loadedMetadata[$realClassName]; + } + } + + if ($this->cacheDriver) { + if (($cached = $this->cacheDriver->fetch($realClassName . $this->cacheSalt)) !== false) { + $this->loadedMetadata[$realClassName] = $cached; + $this->wakeupReflection($cached, $this->getReflectionService()); + } else { + foreach ($this->loadMetadata($realClassName) as $loadedClassName) { + $this->cacheDriver->save( + $loadedClassName . $this->cacheSalt, $this->loadedMetadata[$loadedClassName], null + ); + } + } + } else { + $this->loadMetadata($realClassName); + } + + if ($className != $realClassName) { + // We do not have the alias name in the map, include it + $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName]; + } + } + + return $this->loadedMetadata[$className]; + } + + /** + * Checks whether the factory has the metadata for a class loaded already. + * + * @param string $className + * @return boolean TRUE if the metadata of the class in question is already loaded, FALSE otherwise. + */ + public function hasMetadataFor($className) + { + return isset($this->loadedMetadata[$className]); + } + + /** + * Sets the metadata descriptor for a specific class. + * + * NOTE: This is only useful in very special cases, like when generating proxy classes. + * + * @param string $className + * @param ClassMetadata $class + */ + public function setMetadataFor($className, $class) + { + $this->loadedMetadata[$className] = $class; + } + + /** + * Get array of parent classes for the given entity class + * + * @param string $name + * @return array $parentClasses + */ + protected function getParentClasses($name) + { + // Collect parent classes, ignoring transient (not-mapped) classes. + $parentClasses = array(); + foreach (array_reverse($this->getReflectionService()->getParentClasses($name)) as $parentClass) { + if ( ! $this->getDriver()->isTransient($parentClass)) { + $parentClasses[] = $parentClass; + } + } + return $parentClasses; + } + + /** + * Loads the metadata of the class in question and all it's ancestors whose metadata + * is still not loaded. + * + * @param string $name The name of the class for which the metadata should get loaded. + * @param array $tables The metadata collection to which the loaded metadata is added. + */ + protected function loadMetadata($name) + { + if ( ! $this->initialized) { + $this->initialize(); + } + + $loaded = array(); + + $parentClasses = $this->getParentClasses($name); + $parentClasses[] = $name; + + // Move down the hierarchy of parent classes, starting from the topmost class + $parent = null; + $rootEntityFound = false; + $visited = array(); + $reflService = $this->getReflectionService(); + foreach ($parentClasses as $className) { + if (isset($this->loadedMetadata[$className])) { + $parent = $this->loadedMetadata[$className]; + if (isset($parent->isMappedSuperclass) && $parent->isMappedSuperclass === false) { + $rootEntityFound = true; + array_unshift($visited, $className); + } + continue; + } + + $class = $this->newClassMetadataInstance($className); + $this->initializeReflection($class, $reflService); + + $this->doLoadMetadata($class, $parent, $rootEntityFound); + + $this->loadedMetadata[$className] = $class; + + $parent = $class; + + if (isset($parent->isMappedSuperclass) && $class->isMappedSuperclass === false) { + $rootEntityFound = true; + array_unshift($visited, $className); + } + + $this->wakeupReflection($class, $reflService); + + $loaded[] = $className; + } + + return $loaded; + } + + /** + * Actually load the metadata from the underlying metadata + * + * @param ClassMetadata $class + * @param ClassMetadata $parent + * @param bool $rootEntityFound + * @return void + */ + abstract protected function doLoadMetadata($class, $parent, $rootEntityFound); + + /** + * Creates a new ClassMetadata instance for the given class name. + * + * @param string $className + * @return ClassMetadata + */ + abstract protected function newClassMetadataInstance($className); + + /** + * Check if this class is mapped by this Object Manager + ClassMetadata configuration + * + * @param $class + * @return bool + */ + public function isTransient($class) + { + if ( ! $this->initialized) { + $this->initialize(); + } + + return $this->getDriver()->isTransient($class); + } + + /** + * Set reflectionService. + * + * @param ReflectionService $reflectionService + */ + public function setReflectionService(ReflectionService $reflectionService) + { + $this->reflectionService = $reflectionService; + } + + /** + * Get the reflection service associated with this metadata factory. + * + * @return ReflectionService + */ + public function getReflectionService() + { + if ($this->reflectionService === null) { + $this->reflectionService = new RuntimeReflectionService(); + } + return $this->reflectionService; + } +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/ClassMetadata.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/ClassMetadata.php new file mode 100644 index 0000000..705d59a --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/ClassMetadata.php @@ -0,0 +1,165 @@ +. + */ + +namespace Doctrine\Common\Persistence\Mapping; + +/** + * Contract for a Doctrine persistence layer ClassMetadata class to implement. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.1 + * @author Benjamin Eberlei + * @author Jonathan Wage + */ +interface ClassMetadata +{ + /** + * Get fully-qualified class name of this persistent class. + * + * @return string + */ + function getName(); + + /** + * Gets the mapped identifier field name. + * + * The returned structure is an array of the identifier field names. + * + * @return array + */ + function getIdentifier(); + + /** + * Gets the ReflectionClass instance for this mapped class. + * + * @return ReflectionClass + */ + function getReflectionClass(); + + /** + * Checks if the given field name is a mapped identifier for this class. + * + * @param string $fieldName + * @return boolean + */ + function isIdentifier($fieldName); + + /** + * Checks if the given field is a mapped property for this class. + * + * @param string $fieldName + * @return boolean + */ + function hasField($fieldName); + + /** + * Checks if the given field is a mapped association for this class. + * + * @param string $fieldName + * @return boolean + */ + function hasAssociation($fieldName); + + /** + * Checks if the given field is a mapped single valued association for this class. + * + * @param string $fieldName + * @return boolean + */ + function isSingleValuedAssociation($fieldName); + + /** + * Checks if the given field is a mapped collection valued association for this class. + * + * @param string $fieldName + * @return boolean + */ + function isCollectionValuedAssociation($fieldName); + + /** + * A numerically indexed list of field names of this persistent class. + * + * This array includes identifier fields if present on this class. + * + * @return array + */ + function getFieldNames(); + + /** + * Returns an array of identifier field names numerically indexed. + * + * @return array + */ + function getIdentifierFieldNames(); + + /** + * A numerically indexed list of association names of this persistent class. + * + * This array includes identifier associations if present on this class. + * + * @return array + */ + function getAssociationNames(); + + /** + * Returns a type name of this field. + * + * This type names can be implementation specific but should at least include the php types: + * integer, string, boolean, float/double, datetime. + * + * @param string $fieldName + * @return string + */ + function getTypeOfField($fieldName); + + /** + * Returns the target class name of the given association. + * + * @param string $assocName + * @return string + */ + function getAssociationTargetClass($assocName); + + /** + * Checks if the association is the inverse side of a bidirectional association + * + * @param string $assocName + * @return boolean + */ + function isAssociationInverseSide($assocName); + + /** + * Returns the target field of the owning side of the association + * + * @param string $assocName + * @return string + */ + function getAssociationMappedByTargetField($assocName); + + /** + * Return the identifier of this object as an array with field name as key. + * + * Has to return an empty array if no identifier isset. + * + * @param object $object + * @return array + */ + function getIdentifierValues($object); +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/ClassMetadataFactory.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/ClassMetadataFactory.php new file mode 100644 index 0000000..bf27ba9 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/ClassMetadataFactory.php @@ -0,0 +1,74 @@ +. + */ + +namespace Doctrine\Common\Persistence\Mapping; + +/** + * Contract for a Doctrine persistence layer ClassMetadata class to implement. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.1 + * @author Benjamin Eberlei + * @author Jonathan Wage + */ +interface ClassMetadataFactory +{ + /** + * Forces the factory to load the metadata of all classes known to the underlying + * mapping driver. + * + * @return array The ClassMetadata instances of all mapped classes. + */ + function getAllMetadata(); + + /** + * Gets the class metadata descriptor for a class. + * + * @param string $className The name of the class. + * @return ClassMetadata + */ + function getMetadataFor($className); + + /** + * Checks whether the factory has the metadata for a class loaded already. + * + * @param string $className + * @return boolean TRUE if the metadata of the class in question is already loaded, FALSE otherwise. + */ + function hasMetadataFor($className); + + /** + * Sets the metadata descriptor for a specific class. + * + * @param string $className + * @param ClassMetadata $class + */ + function setMetadataFor($className, $class); + + /** + * Whether the class with the specified name should have its metadata loaded. + * This is only the case if it is either mapped directly or as a + * MappedSuperclass. + * + * @param string $className + * @return boolean + */ + function isTransient($className); +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php new file mode 100644 index 0000000..f52d37e --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php @@ -0,0 +1,214 @@ +. + */ + +namespace Doctrine\Common\Persistence\Mapping\Driver; + +use Doctrine\Common\Cache\ArrayCache, + Doctrine\Common\Annotations\AnnotationReader, + Doctrine\Common\Annotations\AnnotationRegistry, + Doctrine\Common\Persistence\Mapping\MappingException; + +/** + * The AnnotationDriver reads the mapping metadata from docblock annotations. + * + * @since 2.2 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan H. Wage + * @author Roman Borschel + */ +abstract class AnnotationDriver implements MappingDriver +{ + /** + * The AnnotationReader. + * + * @var AnnotationReader + */ + protected $reader; + + /** + * The paths where to look for mapping files. + * + * @var array + */ + protected $paths = array(); + + /** + * The file extension of mapping documents. + * + * @var string + */ + protected $fileExtension = '.php'; + + /** + * Cache for AnnotationDriver#getAllClassNames() + * + * @var array + */ + protected $classNames; + + /** + * Name of the entity annotations as keys + * + * @var array + */ + protected $entityAnnotationClasses = array(); + + /** + * Initializes a new AnnotationDriver that uses the given AnnotationReader for reading + * docblock annotations. + * + * @param AnnotationReader $reader The AnnotationReader to use, duck-typed. + * @param string|array $paths One or multiple paths where mapping classes can be found. + */ + public function __construct($reader, $paths = null) + { + $this->reader = $reader; + if ($paths) { + $this->addPaths((array) $paths); + } + } + + /** + * Append lookup paths to metadata driver. + * + * @param array $paths + */ + public function addPaths(array $paths) + { + $this->paths = array_unique(array_merge($this->paths, $paths)); + } + + /** + * Retrieve the defined metadata lookup paths. + * + * @return array + */ + public function getPaths() + { + return $this->paths; + } + + /** + * Retrieve the current annotation reader + * + * @return AnnotationReader + */ + public function getReader() + { + return $this->reader; + } + + /** + * Get the file extension used to look for mapping files under + * + * @return void + */ + public function getFileExtension() + { + return $this->fileExtension; + } + + /** + * Set the file extension used to look for mapping files under + * + * @param string $fileExtension The file extension to set + * @return void + */ + public function setFileExtension($fileExtension) + { + $this->fileExtension = $fileExtension; + } + + /** + * Whether the class with the specified name is transient. Only non-transient + * classes, that is entities and mapped superclasses, should have their metadata loaded. + * + * A class is non-transient if it is annotated with an annotation + * from the {@see AnnotationDriver::entityAnnotationClasses}. + * + * @param string $className + * @return boolean + */ + public function isTransient($className) + { + $classAnnotations = $this->reader->getClassAnnotations(new \ReflectionClass($className)); + + foreach ($classAnnotations as $annot) { + if (isset($this->entityAnnotationClasses[get_class($annot)])) { + return false; + } + } + return true; + } + + /** + * {@inheritDoc} + */ + public function getAllClassNames() + { + if ($this->classNames !== null) { + return $this->classNames; + } + + if (!$this->paths) { + throw MappingException::pathRequired(); + } + + $classes = array(); + $includedFiles = array(); + + foreach ($this->paths as $path) { + if ( ! is_dir($path)) { + throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path); + } + + $iterator = new \RegexIterator( + new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS), + \RecursiveIteratorIterator::LEAVES_ONLY + ), + '/^.+' . str_replace('.', '\.', $this->fileExtension) . '$/i', + \RecursiveRegexIterator::GET_MATCH + ); + + foreach ($iterator as $file) { + $sourceFile = realpath($file[0]); + + require_once $sourceFile; + + $includedFiles[] = $sourceFile; + } + } + + $declared = get_declared_classes(); + + foreach ($declared as $className) { + $rc = new \ReflectionClass($className); + $sourceFile = $rc->getFileName(); + if (in_array($sourceFile, $includedFiles) && ! $this->isTransient($className)) { + $classes[] = $className; + } + } + + $this->classNames = $classes; + + return $classes; + } +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/DefaultFileLocator.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/DefaultFileLocator.php new file mode 100644 index 0000000..efaf545 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/DefaultFileLocator.php @@ -0,0 +1,169 @@ +. +*/ + +namespace Doctrine\Common\Persistence\Mapping\Driver; + +use Doctrine\Common\Persistence\Mapping\MappingException; + +/** + * Locate the file that contains the metadata information for a given class name. + * + * This behavior is inpependent of the actual content of the file. It just detects + * the file which is responsible for the given class name. + * + * @author Benjamin Eberlei + * @author Johannes M. Schmitt + */ +class DefaultFileLocator implements FileLocator +{ + /** + * The paths where to look for mapping files. + * + * @var array + */ + protected $paths = array(); + + /** + * The file extension of mapping documents. + * + * @var string + */ + protected $fileExtension; + + /** + * Initializes a new FileDriver that looks in the given path(s) for mapping + * documents and operates in the specified operating mode. + * + * @param string|array $paths One or multiple paths where mapping documents can be found. + */ + public function __construct($paths, $fileExtension = null) + { + $this->addPaths((array) $paths); + $this->fileExtension = $fileExtension; + } + + /** + * Append lookup paths to metadata driver. + * + * @param array $paths + */ + public function addPaths(array $paths) + { + $this->paths = array_unique(array_merge($this->paths, $paths)); + } + + /** + * Retrieve the defined metadata lookup paths. + * + * @return array + */ + public function getPaths() + { + return $this->paths; + } + + /** + * Get the file extension used to look for mapping files under + * + * @return void + */ + public function getFileExtension() + { + return $this->fileExtension; + } + + /** + * Set the file extension used to look for mapping files under + * + * @param string $fileExtension The file extension to set + * @return void + */ + public function setFileExtension($fileExtension) + { + $this->fileExtension = $fileExtension; + } + + /** + * {@inheritDoc} + */ + public function findMappingFile($className) + { + $fileName = str_replace('\\', '.', $className) . $this->fileExtension; + + // Check whether file exists + foreach ($this->paths as $path) { + if (file_exists($path . DIRECTORY_SEPARATOR . $fileName)) { + return $path . DIRECTORY_SEPARATOR . $fileName; + } + } + + throw MappingException::mappingFileNotFound($className, $fileName); + } + + /** + * {@inheritDoc} + */ + public function getAllClassNames($globalBasename) + { + $classes = array(); + + if ($this->paths) { + foreach ($this->paths as $path) { + if ( ! is_dir($path)) { + throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path); + } + + $iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($path), + \RecursiveIteratorIterator::LEAVES_ONLY + ); + + foreach ($iterator as $file) { + $fileName = $file->getBasename($this->fileExtension); + + if ($fileName == $file->getBasename() || $fileName == $globalBasename) { + continue; + } + + // NOTE: All files found here means classes are not transient! + $classes[] = str_replace('.', '\\', $fileName); + } + } + } + + return $classes; + } + + /** + * {@inheritDoc} + */ + public function fileExists($className) + { + $fileName = str_replace('\\', '.', $className) . $this->fileExtension; + + // Check whether file exists + foreach ((array) $this->paths as $path) { + if (file_exists($path . DIRECTORY_SEPARATOR . $fileName)) { + return true; + } + } + + return false; + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/FileDriver.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/FileDriver.php new file mode 100644 index 0000000..22cf117 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/FileDriver.php @@ -0,0 +1,178 @@ +. + */ + +namespace Doctrine\Common\Persistence\Mapping\Driver; + +use Doctrine\Common\Persistence\Mapping\MappingException; + +/** + * Base driver for file-based metadata drivers. + * + * A file driver operates in a mode where it loads the mapping files of individual + * classes on demand. This requires the user to adhere to the convention of 1 mapping + * file per class and the file names of the mapping files must correspond to the full + * class name, including namespace, with the namespace delimiters '\', replaced by dots '.'. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.2 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan H. Wage + * @author Roman Borschel + */ +abstract class FileDriver implements MappingDriver +{ + /** + * @var FileLocator + */ + protected $locator; + + /** + * @var array + */ + protected $classCache; + + /** + * @var string + */ + protected $globalBasename; + + /** + * Initializes a new FileDriver that looks in the given path(s) for mapping + * documents and operates in the specified operating mode. + * + * @param string|array|FileLocator $paths A FileLocator or one/multiple paths where mapping documents can be found. + * @param string $fileExtension + */ + public function __construct($locator, $fileExtension = null) + { + if ($locator instanceof FileLocator) { + $this->locator = $locator; + } else { + $this->locator = new DefaultFileLocator((array)$locator, $fileExtension); + } + } + + public function setGlobalBasename($file) + { + $this->globalBasename = $file; + } + + public function getGlobalBasename() + { + return $this->globalBasename; + } + + /** + * Get the element of schema meta data for the class from the mapping file. + * This will lazily load the mapping file if it is not loaded yet + * + * @return array $element The element of schema meta data + */ + public function getElement($className) + { + if ($this->classCache === null) { + $this->initialize(); + } + + if (isset($this->classCache[$className])) { + return $this->classCache[$className]; + } + + $result = $this->loadMappingFile($this->locator->findMappingFile($className)); + + return $result[$className]; + } + + /** + * Whether the class with the specified name should have its metadata loaded. + * This is only the case if it is either mapped as an Entity or a + * MappedSuperclass. + * + * @param string $className + * @return boolean + */ + public function isTransient($className) + { + if ($this->classCache === null) { + $this->initialize(); + } + + if (isset($this->classCache[$className])) { + return false; + } + + return !$this->locator->fileExists($className); + } + + /** + * Gets the names of all mapped classes known to this driver. + * + * @return array The names of all mapped classes known to this driver. + */ + public function getAllClassNames() + { + if ($this->classCache === null) { + $this->initialize(); + } + + $classNames = (array)$this->locator->getAllClassNames($this->globalBasename); + if ($this->classCache) { + $classNames = array_merge(array_keys($this->classCache), $classNames); + } + return $classNames; + } + + /** + * Loads a mapping file with the given name and returns a map + * from class/entity names to their corresponding file driver elements. + * + * @param string $file The mapping file to load. + * @return array + */ + abstract protected function loadMappingFile($file); + + /** + * Initialize the class cache from all the global files. + * + * Using this feature adds a substantial performance hit to file drivers as + * more metadata has to be loaded into memory than might actually be + * necessary. This may not be relevant to scenarios where caching of + * metadata is in place, however hits very hard in scenarios where no + * caching is used. + * + * @return void + */ + protected function initialize() + { + $this->classCache = array(); + if (null !== $this->globalBasename) { + foreach ($this->locator->getPaths() as $path) { + $file = $path.'/'.$this->globalBasename.$this->locator->getFileExtension(); + if (is_file($file)) { + $this->classCache = array_merge( + $this->classCache, + $this->loadMappingFile($file) + ); + } + } + } + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/FileLocator.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/FileLocator.php new file mode 100644 index 0000000..a1019d7 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/FileLocator.php @@ -0,0 +1,69 @@ +. +*/ + +namespace Doctrine\Common\Persistence\Mapping\Driver; + +/** + * Locate the file that contains the metadata information for a given class name. + * + * This behavior is inpependent of the actual content of the file. It just detects + * the file which is responsible for the given class name. + * + * @author Benjamin Eberlei + * @author Johannes M. Schmitt + */ +interface FileLocator +{ + /** + * Locate mapping file for the given class name. + * + * @param string $className + * @return string + */ + function findMappingFile($className); + + /** + * Get all class names that are found with this file locator. + * + * @param string $globalBasename Passed to allow excluding the basename + * @return array + */ + function getAllClassNames($globalBasename); + + /** + * Check if a file can be found for this class name. + * + * @return bool + */ + function fileExists($className); + + /** + * Get all the paths that this file locator looks for mapping files. + * + * @return array + */ + function getPaths(); + + /** + * Get the file extension that mapping files are suffixed with. + * + * @return string + */ + function getFileExtension(); +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriver.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriver.php new file mode 100644 index 0000000..c050d32 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriver.php @@ -0,0 +1,56 @@ +. + */ + +namespace Doctrine\Common\Persistence\Mapping\Driver; + +use Doctrine\Common\Persistence\Mapping\ClassMetadata; + +/** + * Contract for metadata drivers. + * + * @since 2.2 + * @author Jonathan H. Wage + */ +interface MappingDriver +{ + /** + * Loads the metadata for the specified class into the provided container. + * + * @param string $className + * @param ClassMetadata $metadata + */ + function loadMetadataForClass($className, ClassMetadata $metadata); + + /** + * Gets the names of all mapped classes known to this driver. + * + * @return array The names of all mapped classes known to this driver. + */ + function getAllClassNames(); + + /** + * Whether the class with the specified name should have its metadata loaded. + * This is only the case if it is either mapped as an Entity or a + * MappedSuperclass. + * + * @param string $className + * @return boolean + */ + function isTransient($className); +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php new file mode 100644 index 0000000..c7c1452 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php @@ -0,0 +1,125 @@ +. + */ + +namespace Doctrine\Common\Persistence\Mapping\Driver; + +use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver, + Doctrine\Common\Persistence\Mapping\ClassMetadata, + Doctrine\Common\Persistence\Mapping\MappingException; + +/** + * The DriverChain allows you to add multiple other mapping drivers for + * certain namespaces + * + * @since 2.2 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan H. Wage + * @author Roman Borschel + */ +class MappingDriverChain implements MappingDriver +{ + /** + * @var array + */ + private $drivers = array(); + + /** + * Add a nested driver. + * + * @param Driver $nestedDriver + * @param string $namespace + */ + public function addDriver(MappingDriver $nestedDriver, $namespace) + { + $this->drivers[$namespace] = $nestedDriver; + } + + /** + * Get the array of nested drivers. + * + * @return array $drivers + */ + public function getDrivers() + { + return $this->drivers; + } + + /** + * Loads the metadata for the specified class into the provided container. + * + * @param string $className + * @param ClassMetadataInfo $metadata + */ + public function loadMetadataForClass($className, ClassMetadata $metadata) + { + foreach ($this->drivers as $namespace => $driver) { + if (strpos($className, $namespace) === 0) { + $driver->loadMetadataForClass($className, $metadata); + return; + } + } + + throw MappingException::classNotFoundInNamespaces($className, array_keys($this->drivers)); + } + + /** + * Gets the names of all mapped classes known to this driver. + * + * @return array The names of all mapped classes known to this driver. + */ + public function getAllClassNames() + { + $classNames = array(); + $driverClasses = array(); + foreach ($this->drivers AS $namespace => $driver) { + $oid = spl_object_hash($driver); + if (!isset($driverClasses[$oid])) { + $driverClasses[$oid] = $driver->getAllClassNames(); + } + + foreach ($driverClasses[$oid] AS $className) { + if (strpos($className, $namespace) === 0) { + $classNames[$className] = true; + } + } + } + return array_keys($classNames); + } + + /** + * Whether the class with the specified name should have its metadata loaded. + * + * This is only the case for non-transient classes either mapped as an Entity or MappedSuperclass. + * + * @param string $className + * @return boolean + */ + public function isTransient($className) + { + foreach ($this->drivers AS $namespace => $driver) { + if (strpos($className, $namespace) === 0) { + return $driver->isTransient($className); + } + } + + // class isTransient, i.e. not an entity or mapped superclass + return true; + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/PHPDriver.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/PHPDriver.php new file mode 100644 index 0000000..7751dae --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/PHPDriver.php @@ -0,0 +1,70 @@ +. + */ + +namespace Doctrine\Common\Persistence\Mapping\Driver; + +use Doctrine\Common\Persistence\Mapping\ClassMetadata; + +/** + * The PHPDriver includes php files which just populate ClassMetadataInfo + * instances with plain php code + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan H. Wage + * @author Roman Borschel + */ +class PHPDriver extends FileDriver +{ + /** + * {@inheritdoc} + */ + protected $metadata; + + /** + * {@inheritDoc} + */ + public function __construct($locator, $fileExtension = null) + { + $fileExtension = ".php"; + parent::__construct($locator, $fileExtension); + } + + /** + * {@inheritdoc} + */ + public function loadMetadataForClass($className, ClassMetadata $metadata) + { + $this->metadata = $metadata; + $this->loadMappingFile($this->locator->findMappingFile($className)); + } + + /** + * {@inheritdoc} + */ + protected function loadMappingFile($file) + { + $metadata = $this->metadata; + include $file; + } +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/StaticPHPDriver.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/StaticPHPDriver.php new file mode 100644 index 0000000..9103ed8 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/StaticPHPDriver.php @@ -0,0 +1,131 @@ +. + */ + +namespace Doctrine\Common\Persistence\Mapping\Driver; + +use Doctrine\Common\Persistence\Mapping\ClassMetadata; +use Doctrine\Common\Persistence\Mapping\MappingException; + +/** + * The StaticPHPDriver calls a static loadMetadata() method on your entity + * classes where you can manually populate the ClassMetadata instance. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.2 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan H. Wage + * @author Roman Borschel + */ +class StaticPHPDriver implements MappingDriver +{ + /** + * Paths of entity directories. + * + * @var array + */ + private $paths = array(); + + /** + * Map of all class names. + * + * @var array + */ + private $classNames; + + public function __construct($paths) + { + $this->addPaths((array) $paths); + } + + public function addPaths(array $paths) + { + $this->paths = array_unique(array_merge($this->paths, $paths)); + } + + /** + * {@inheritdoc} + */ + public function loadMetadataForClass($className, ClassMetadata $metadata) + { + $className::loadMetadata($metadata); + } + + /** + * {@inheritDoc} + * @todo Same code exists in AnnotationDriver, should we re-use it somehow or not worry about it? + */ + public function getAllClassNames() + { + if ($this->classNames !== null) { + return $this->classNames; + } + + if (!$this->paths) { + throw MappingException::pathRequired(); + } + + $classes = array(); + $includedFiles = array(); + + foreach ($this->paths as $path) { + if (!is_dir($path)) { + throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path); + } + + $iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($path), + \RecursiveIteratorIterator::LEAVES_ONLY + ); + + foreach ($iterator as $file) { + if ($file->getBasename('.php') == $file->getBasename()) { + continue; + } + + $sourceFile = realpath($file->getPathName()); + require_once $sourceFile; + $includedFiles[] = $sourceFile; + } + } + + $declared = get_declared_classes(); + + foreach ($declared as $className) { + $rc = new \ReflectionClass($className); + $sourceFile = $rc->getFileName(); + if (in_array($sourceFile, $includedFiles) && !$this->isTransient($className)) { + $classes[] = $className; + } + } + + $this->classNames = $classes; + + return $classes; + } + + /** + * {@inheritdoc} + */ + public function isTransient($className) + { + return ! method_exists($className, 'loadMetadata'); + } +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/SymfonyFileLocator.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/SymfonyFileLocator.php new file mode 100644 index 0000000..d338cf6 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/SymfonyFileLocator.php @@ -0,0 +1,198 @@ +. +*/ + +namespace Doctrine\Common\Persistence\Mapping\Driver; + +use Doctrine\Common\Persistence\Mapping\MappingException; + +/** + * The Symfony File Locator makes a simplifying assumptions compared + * to the DefaultFileLocator. By assuming paths only contain entities of a certain + * namespace the mapping files consists of the short classname only. + * + * @author Fabien Potencier + * @author Benjamin Eberlei + * @license MIT + */ +class SymfonyFileLocator implements FileLocator +{ + /** + * The paths where to look for mapping files. + * + * @var array + */ + protected $paths = array(); + + /** + * A map of mapping directory path to namespace prefix used to expand class shortnames. + * + * @var array + */ + protected $prefixes = array(); + + /** + * File extension that is searched for. + * + * @var string + */ + protected $fileExtension; + + public function __construct(array $prefixes, $fileExtension = null) + { + $this->addNamespacePrefixes($prefixes); + $this->fileExtension = $fileExtension; + } + + public function addNamespacePrefixes(array $prefixes) + { + $this->prefixes = array_merge($this->prefixes, $prefixes); + $this->paths = array_merge($this->paths, array_keys($prefixes)); + } + + public function getNamespacePrefixes() + { + return $this->prefixes; + } + + /** + * {@inheritDoc} + */ + public function getPaths() + { + return $this->paths; + } + + /** + * {@inheritDoc} + */ + public function getFileExtension() + { + return $this->fileExtension; + } + + /** + * Set the file extension used to look for mapping files under + * + * @param string $fileExtension The file extension to set + * @return void + */ + public function setFileExtension($fileExtension) + { + $this->fileExtension = $fileExtension; + } + + /** + * {@inheritDoc} + */ + public function fileExists($className) + { + $defaultFileName = str_replace('\\', '.', $className).$this->fileExtension; + foreach ($this->paths as $path) { + if (!isset($this->prefixes[$path])) { + // global namespace class + if (is_file($path.DIRECTORY_SEPARATOR.$defaultFileName)) { + return true; + } + + continue; + } + + $prefix = $this->prefixes[$path]; + + if (0 !== strpos($className, $prefix.'\\')) { + continue; + } + + $filename = $path.'/'.strtr(substr($className, strlen($prefix)+1), '\\', '.').$this->fileExtension; + return is_file($filename); + } + + return false; + } + + /** + * {@inheritDoc} + */ + public function getAllClassNames($globalBasename = null) + { + $classes = array(); + + if ($this->paths) { + foreach ((array) $this->paths as $path) { + if (!is_dir($path)) { + throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path); + } + + $iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($path), + \RecursiveIteratorIterator::LEAVES_ONLY + ); + + foreach ($iterator as $file) { + $fileName = $file->getBasename($this->fileExtension); + + if ($fileName == $file->getBasename() || $fileName == $globalBasename) { + continue; + } + + // NOTE: All files found here means classes are not transient! + if (isset($this->prefixes[$path])) { + $classes[] = $this->prefixes[$path].'\\'.str_replace('.', '\\', $fileName); + } else { + $classes[] = str_replace('.', '\\', $fileName); + } + } + } + } + + return $classes; + } + + /** + * {@inheritDoc} + */ + public function findMappingFile($className) + { + $defaultFileName = str_replace('\\', '.', $className).$this->fileExtension; + foreach ($this->paths as $path) { + if (!isset($this->prefixes[$path])) { + if (is_file($path.DIRECTORY_SEPARATOR.$defaultFileName)) { + return $path.DIRECTORY_SEPARATOR.$defaultFileName; + } + + continue; + } + + $prefix = $this->prefixes[$path]; + + if (0 !== strpos($className, $prefix.'\\')) { + continue; + } + + $filename = $path.'/'.strtr(substr($className, strlen($prefix)+1), '\\', '.').$this->fileExtension; + if (is_file($filename)) { + return $filename; + } + + throw MappingException::mappingFileNotFound($className, $filename); + } + + throw MappingException::mappingFileNotFound($className, substr($className, strrpos($className, '\\') + 1).$this->fileExtension); + } +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/MappingException.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/MappingException.php new file mode 100644 index 0000000..4ecd2ad --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/MappingException.php @@ -0,0 +1,57 @@ +. + */ + +namespace Doctrine\Common\Persistence\Mapping; + +/** + * A MappingException indicates that something is wrong with the mapping setup. + * + * @since 2.2 + */ +class MappingException extends \Exception +{ + public static function classNotFoundInNamespaces($className, $namespaces) + { + return new self("The class '" . $className . "' was not found in the ". + "chain configured namespaces " . implode(", ", $namespaces)); + } + + public static function pathRequired() + { + return new self("Specifying the paths to your entities is required ". + "in the AnnotationDriver to retrieve all class names."); + } + + public static function fileMappingDriversRequireConfiguredDirectoryPath($path = null) + { + if ( ! empty($path)) { + $path = '[' . $path . ']'; + } + + return new self( + 'File mapping drivers must have a valid directory path, ' . + 'however the given path ' . $path . ' seems to be incorrect!' + ); + } + + public static function mappingFileNotFound($entityName, $fileName) + { + return new self("No mapping file found named '$fileName' for class '$entityName'."); + } +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/ReflectionService.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/ReflectionService.php new file mode 100644 index 0000000..4e0e312 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/ReflectionService.php @@ -0,0 +1,80 @@ +. + */ + +namespace Doctrine\Common\Persistence\Mapping; + +/** + * Very simple reflection service abstraction. + * + * This is required inside metadata layers that may require either + * static or runtime reflection. + * + * @author Benjamin Eberlei + */ +interface ReflectionService +{ + /** + * Return an array of the parent classes (not interfaces) for the given class. + * + * @param string $class + * @return array + */ + function getParentClasses($class); + + /** + * Return the shortname of a class. + * + * @param string $class + * @return string + */ + function getClassShortName($class); + + /** + * @param string $class + * @return string + */ + function getClassNamespace($class); + + /** + * Return a reflection class instance or null + * + * @param string $class + * @return ReflectionClass|null + */ + function getClass($class); + + /** + * Return an accessible property (setAccessible(true)) or null. + * + * @param string $class + * @param string $property + * @return ReflectionProperty|null + */ + function getAccessibleProperty($class, $property); + + /** + * Check if the class have a public method with the given name. + * + * @param mixed $class + * @param mixed $method + * @return bool + */ + function hasPublicMethod($class, $method); +} + diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/RuntimeReflectionService.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/RuntimeReflectionService.php new file mode 100644 index 0000000..abcff58 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/RuntimeReflectionService.php @@ -0,0 +1,102 @@ +. + */ + +namespace Doctrine\Common\Persistence\Mapping; + +use ReflectionClass; +use ReflectionProperty; + +/** + * PHP Runtime Reflection Service + * + * @author Benjamin Eberlei + */ +class RuntimeReflectionService implements ReflectionService +{ + /** + * Return an array of the parent classes (not interfaces) for the given class. + * + * @param string $class + * @return array + */ + public function getParentClasses($class) + { + return class_parents($class); + } + + /** + * Return the shortname of a class. + * + * @param string $class + * @return string + */ + public function getClassShortName($class) + { + $r = new ReflectionClass($class); + return $r->getShortName(); + } + + /** + * @param string $class + * @return string + */ + public function getClassNamespace($class) + { + $r = new ReflectionClass($class); + return $r->getNamespaceName(); + } + + /** + * Return a reflection class instance or null + * + * @param string $class + * @return ReflectionClass|null + */ + public function getClass($class) + { + return new ReflectionClass($class); + } + + /** + * Return an accessible property (setAccessible(true)) or null. + * + * @param string $class + * @param string $property + * @return ReflectionProperty|null + */ + public function getAccessibleProperty($class, $property) + { + $property = new ReflectionProperty($class, $property); + $property->setAccessible(true); + return $property; + } + + /** + * Check if the class have a public method with the given name. + * + * @param mixed $class + * @param mixed $method + * @return bool + */ + public function hasPublicMethod($class, $method) + { + return method_exists($class, $method) && is_callable(array($class, $method)); + } +} + diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/StaticReflectionService.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/StaticReflectionService.php new file mode 100644 index 0000000..2de6e76 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/StaticReflectionService.php @@ -0,0 +1,107 @@ +. + */ + +namespace Doctrine\Common\Persistence\Mapping; + +use ReflectionClass; +use ReflectionProperty; + +/** + * PHP Runtime Reflection Service + * + * @author Benjamin Eberlei + */ +class StaticReflectionService implements ReflectionService +{ + /** + * Return an array of the parent classes (not interfaces) for the given class. + * + * @param string $class + * @return array + */ + public function getParentClasses($class) + { + return array(); + } + + /** + * Return the shortname of a class. + * + * @param string $className + * @return string + */ + public function getClassShortName($className) + { + if (strpos($className, '\\') !== false) { + $className = substr($className, strrpos($className, "\\")+1); + } + return $className; + } + + /** + * Return the namespace of a class. + * + * @param string $className + * @return string + */ + public function getClassNamespace($className) + { + $namespace = ''; + if (strpos($className, '\\') !== false) { + $namespace = strrev(substr( strrev($className), strpos(strrev($className), '\\')+1 )); + } + return $namespace; + } + + /** + * Return a reflection class instance or null + * + * @param string $class + * @return ReflectionClass|null + */ + public function getClass($class) + { + return null; + } + + /** + * Return an accessible property (setAccessible(true)) or null. + * + * @param string $class + * @param string $property + * @return ReflectionProperty|null + */ + public function getAccessibleProperty($class, $property) + { + return null; + } + + /** + * Check if the class have a public method with the given name. + * + * @param mixed $class + * @param mixed $method + * @return bool + */ + public function hasPublicMethod($class, $method) + { + return method_exists($class, $method) && is_callable(array($class, $method)); + } +} + diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/ObjectManager.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/ObjectManager.php new file mode 100644 index 0000000..6d70fc1 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/ObjectManager.php @@ -0,0 +1,143 @@ +. + */ + +namespace Doctrine\Common\Persistence; + +/** + * Contract for a Doctrine persistence layer ObjectManager class to implement. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.1 + * @author Benjamin Eberlei + * @author Jonathan Wage + */ +interface ObjectManager +{ + /** + * Finds a object by its identifier. + * + * This is just a convenient shortcut for getRepository($className)->find($id). + * + * @param string + * @param mixed + * @return object + */ + function find($className, $id); + + /** + * Tells the ObjectManager to make an instance managed and persistent. + * + * The object will be entered into the database as a result of the flush operation. + * + * NOTE: The persist operation always considers objects that are not yet known to + * this ObjectManager as NEW. Do not pass detached objects to the persist operation. + * + * @param object $object The instance to make managed and persistent. + */ + function persist($object); + + /** + * Removes an object instance. + * + * A removed object will be removed from the database as a result of the flush operation. + * + * @param object $object The object instance to remove. + */ + function remove($object); + + /** + * Merges the state of a detached object into the persistence context + * of this ObjectManager and returns the managed copy of the object. + * The object passed to merge will not become associated/managed with this ObjectManager. + * + * @param object $object + */ + function merge($object); + + /** + * Detaches an object from the ObjectManager, causing a managed object to + * become detached. Unflushed changes made to the object if any + * (including removal of the object), will not be synchronized to the database. + * Objects which previously referenced the detached object will continue to + * reference it. + * + * @param object $object The object to detach. + */ + function detach($object); + + /** + * Refreshes the persistent state of an object from the database, + * overriding any local changes that have not yet been persisted. + * + * @param object $object The object to refresh. + */ + function refresh($object); + + /** + * Flushes all changes to objects that have been queued up to now to the database. + * This effectively synchronizes the in-memory state of managed objects with the + * database. + */ + function flush(); + + /** + * Gets the repository for a class. + * + * @param string $className + * @return \Doctrine\Common\Persistence\ObjectRepository + */ + function getRepository($className); + + /** + * Returns the ClassMetadata descriptor for a class. + * + * The class name must be the fully-qualified class name without a leading backslash + * (as it is returned by get_class($obj)). + * + * @param string $className + * @return \Doctrine\Common\Persistence\Mapping\ClassMetadata + */ + function getClassMetadata($className); + + /** + * Gets the metadata factory used to gather the metadata of classes. + * + * @return Doctrine\Common\Persistence\Mapping\ClassMetadataFactory + */ + function getMetadataFactory(); + + /** + * Helper method to initialize a lazy loading proxy or persistent collection. + * + * This method is a no-op for other objects. + * + * @param object $obj + */ + function initializeObject($obj); + + /** + * Check if the object is part of the current UnitOfWork and therefore + * managed. + * + * @param object $object + * @return bool + */ + function contains($object); +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/ObjectManagerAware.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/ObjectManagerAware.php new file mode 100644 index 0000000..015dd3d --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/ObjectManagerAware.php @@ -0,0 +1,49 @@ +. + */ + +namespace Doctrine\Common\Persistence; + +use Doctrine\Common\Persistence\Mapping\ClassMetadata; + +/** + * Makes a Persistent Objects aware of its own object-manager. + * + * Using this interface the managing object manager and class metadata instances + * are injected into the persistent object after construction. This allows + * you to implement ActiveRecord functionality on top of the persistance-ignorance + * that Doctrine propagates. + * + * Word of Warning: This is a very powerful hook to change how you can work with your domain models. + * Using this hook will break the Single Responsibility Principle inside your Domain Objects + * and increase the coupling of database and objects. + * + * Every ObjectManager has to implement this functionality itself. + * + * @author Benjamin Eberlei + */ +interface ObjectManagerAware +{ + /** + * Injects responsible ObjectManager and the ClassMetadata into this persistent object. + * + * @param ObjectManager $objectManager + * @param ClassMetadata $classMetadata + */ + public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata); +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/ObjectRepository.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/ObjectRepository.php new file mode 100644 index 0000000..2263328 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/ObjectRepository.php @@ -0,0 +1,78 @@ +. + */ + +namespace Doctrine\Common\Persistence; + +/** + * Contract for a Doctrine persistence layer ObjectRepository class to implement. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.1 + * @author Benjamin Eberlei + * @author Jonathan Wage + */ +interface ObjectRepository +{ + /** + * Finds an object by its primary key / identifier. + * + * @param $id The identifier. + * @return object The object. + */ + function find($id); + + /** + * Finds all objects in the repository. + * + * @return mixed The objects. + */ + function findAll(); + + /** + * Finds objects by a set of criteria. + * + * Optionally sorting and limiting details can be passed. An implementation may throw + * an UnexpectedValueException if certain values of the sorting or limiting details are + * not supported. + * + * @throws UnexpectedValueException + * @param array $criteria + * @param array|null $orderBy + * @param int|null $limit + * @param int|null $offset + * @return mixed The objects. + */ + function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null); + + /** + * Finds a single object by a set of criteria. + * + * @param array $criteria + * @return object The object. + */ + function findOneBy(array $criteria); + + /** + * Returns the class name of the object managed by the repository + * + * @return string + */ + function getClassName(); +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/PersistentObject.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/PersistentObject.php new file mode 100644 index 0000000..4274af6 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/PersistentObject.php @@ -0,0 +1,233 @@ +. + */ + +namespace Doctrine\Common\Persistence; + +use Doctrine\Common\Persistence\Mapping\ClassMetadata; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; + +/** + * PersistentObject base class that implements getter/setter methods for all mapped fields and associations + * by overriding __call. + * + * This class is a forward compatible implementation of the PersistentObject trait. + * + * + * Limitations: + * + * 1. All persistent objects have to be associated with a single ObjectManager, multiple + * ObjectManagers are not supported. You can set the ObjectManager with `PersistentObject#setObjectManager()`. + * 2. Setters and getters only work if a ClassMetadata instance was injected into the PersistentObject. + * This is either done on `postLoad` of an object or by accessing the global object manager. + * 3. There are no hooks for setters/getters. Just implement the method yourself instead of relying on __call(). + * 4. Slower than handcoded implementations: An average of 7 method calls per access to a field and 11 for an association. + * 5. Only the inverse side associations get autoset on the owning side aswell. Setting objects on the owning side + * will not set the inverse side associations. + * + * @example + * + * PersistentObject::setObjectManager($em); + * + * class Foo extends PersistentObject + * { + * private $id; + * } + * + * $foo = new Foo(); + * $foo->getId(); // method exists through __call + * + * @author Benjamin Eberlei + */ +abstract class PersistentObject implements ObjectManagerAware +{ + /** + * @var ObjectManager + */ + private static $objectManager; + + /** + * @var ClassMetadata + */ + private $cm; + + /** + * Set the object manager responsible for all persistent object base classes. + * + * @param ObjectManager $objectManager + */ + static public function setObjectManager(ObjectManager $objectManager = null) + { + self::$objectManager = $objectManager; + } + + /** + * @return ObjectManager + */ + static public function getObjectManager() + { + return self::$objectManager; + } + + /** + * Inject Doctrine Object Manager + * + * @param ObjectManager $objectManager + * @param ClassMetadata $classMetadata + */ + public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata) + { + if ($objectManager !== self::$objectManager) { + throw new \RuntimeException("Trying to use PersistentObject with different ObjectManager instances. " . + "Was PersistentObject::setObjectManager() called?"); + } + + $this->cm = $classMetadata; + } + + /** + * Sets a persistent fields value. + * + * @throws InvalidArgumentException - When the wrong target object type is passed to an association + * @throws BadMethodCallException - When no persistent field exists by that name. + * @param string $field + * @param array $args + * @return void + */ + private function set($field, $args) + { + $this->initializeDoctrine(); + + if ($this->cm->hasField($field) && !$this->cm->isIdentifier($field)) { + $this->$field = $args[0]; + } else if ($this->cm->hasAssociation($field) && $this->cm->isSingleValuedAssociation($field)) { + $targetClass = $this->cm->getAssociationTargetClass($field); + if (!($args[0] instanceof $targetClass) && $args[0] !== null) { + throw new \InvalidArgumentException("Expected persistent object of type '".$targetClass."'"); + } + $this->$field = $args[0]; + $this->completeOwningSide($field, $targetClass, $args[0]); + } else { + throw new \BadMethodCallException("no field with name '".$field."' exists on '".$this->cm->getName()."'"); + } + } + + /** + * Get persistent field value. + * + * @throws BadMethodCallException - When no persistent field exists by that name. + * @param string $field + * @return mixed + */ + private function get($field) + { + $this->initializeDoctrine(); + + if ( $this->cm->hasField($field) || $this->cm->hasAssociation($field) ) { + return $this->$field; + } else { + throw new \BadMethodCallException("no field with name '".$field."' exists on '".$this->cm->getName()."'"); + } + } + + /** + * If this is an inverse side association complete the owning side. + * + * @param string $field + * @param ClassMetadata $targetClass + * @param object $targetObject + */ + private function completeOwningSide($field, $targetClass, $targetObject) + { + // add this object on the owning side aswell, for obvious infinite recursion + // reasons this is only done when called on the inverse side. + if ($this->cm->isAssociationInverseSide($field)) { + $mappedByField = $this->cm->getAssociationMappedByTargetField($field); + $targetMetadata = self::$objectManager->getClassMetadata($targetClass); + + $setter = ($targetMetadata->isCollectionValuedAssociation($mappedByField) ? "add" : "set").$mappedByField; + $targetObject->$setter($this); + } + } + + /** + * Add an object to a collection + * + * @param type $field + * @param assoc $args + */ + private function add($field, $args) + { + $this->initializeDoctrine(); + + if ($this->cm->hasAssociation($field) && $this->cm->isCollectionValuedAssociation($field)) { + $targetClass = $this->cm->getAssociationTargetClass($field); + if (!($args[0] instanceof $targetClass)) { + throw new \InvalidArgumentException("Expected persistent object of type '".$targetClass."'"); + } + if (!($this->$field instanceof Collection)) { + $this->$field = new ArrayCollection($this->$field ?: array()); + } + $this->$field->add($args[0]); + $this->completeOwningSide($field, $targetClass, $args[0]); + } else { + throw new \BadMethodCallException("There is no method add".$field."() on ".$this->cm->getName()); + } + } + + /** + * Initialize Doctrine Metadata for this class. + * + * @return void + */ + private function initializeDoctrine() + { + if ($this->cm !== null) { + return; + } + + if (!self::$objectManager) { + throw new \RuntimeException("No runtime object manager set. Call PersistentObject#setObjectManager()."); + } + + $this->cm = self::$objectManager->getClassMetadata(get_class($this)); + } + + /** + * Magic method that implements + * + * @param string $method + * @param array $args + * @return mixed + */ + public function __call($method, $args) + { + $command = substr($method, 0, 3); + $field = lcfirst(substr($method, 3)); + if ($command == "set") { + $this->set($field, $args); + } else if ($command == "get") { + return $this->get($field); + } else if ($command == "add") { + $this->add($field, $args); + } else { + throw new \BadMethodCallException("There is no method ".$method." on ".$this->cm->getName()); + } + } +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Proxy.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Proxy.php new file mode 100644 index 0000000..726979f --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Proxy.php @@ -0,0 +1,60 @@ +. + */ + +namespace Doctrine\Common\Persistence; + +/** + * Interface for proxy classes. + * + * @author Roman Borschel + * @since 2.2 + */ +interface Proxy +{ + /** + * Marker for Proxy class names. + * + * @var string + */ + const MARKER = '__CG__'; + + /** + * Length of the proxy marker + * + * @var int + */ + const MARKER_LENGTH = 6; + + /** + * Initialize this proxy if its not yet initialized. + * + * Acts as a no-op if already initialized. + * + * @return void + */ + public function __load(); + + /** + * Is this proxy initialized or not. + * + * @return bool + */ + public function __isInitialized(); +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/PropertyChangedListener.php b/vendor/doctrine/common/lib/Doctrine/Common/PropertyChangedListener.php new file mode 100644 index 0000000..87c5b41 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/PropertyChangedListener.php @@ -0,0 +1,48 @@ +. + */ + +namespace Doctrine\Common; + +/** + * Contract for classes that are potential listeners of a NotifyPropertyChanged + * implementor. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +interface PropertyChangedListener +{ + /** + * Notifies the listener of a property change. + * + * @param object $sender The object on which the property changed. + * @param string $propertyName The name of the property that changed. + * @param mixed $oldValue The old value of the property that changed. + * @param mixed $newValue The new value of the property that changed. + */ + function propertyChanged($sender, $propertyName, $oldValue, $newValue); +} + diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Util/ClassUtils.php b/vendor/doctrine/common/lib/Doctrine/Common/Util/ClassUtils.php new file mode 100644 index 0000000..c346278 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Util/ClassUtils.php @@ -0,0 +1,103 @@ +. + */ + +namespace Doctrine\Common\Util; + +use Doctrine\Common\Persistence\Proxy; + +/** + * Class and reflection related functionality for objects that + * might or not be proxy objects at the moment. + * + * @author Benjamin Eberlei + * @author Johannes Schmitt + */ +class ClassUtils +{ + /** + * Get the real class name of a class name that could be a proxy. + * + * @param string + * @return string + */ + public static function getRealClass($class) + { + if (false === $pos = strrpos($class, '\\'.Proxy::MARKER.'\\')) { + return $class; + } + + return substr($class, $pos + Proxy::MARKER_LENGTH + 2); + } + + /** + * Get the real class name of an object (even if its a proxy) + * + * @param object + * @return string + */ + public static function getClass($object) + { + return self::getRealClass(get_class($object)); + } + + /** + * Get the real parent class name of a class or object + * + * @param string + * @return string + */ + public static function getParentClass($className) + { + return get_parent_class( self::getRealClass( $className ) ); + } + + /** + * Create a new reflection class + * + * @param string + * @return ReflectionClass + */ + public static function newReflectionClass($class) + { + return new \ReflectionClass( self::getRealClass( $class ) ); + } + + /** + * Create a new reflection object + * + * @param object + * @return ReflectionObject + */ + public static function newReflectionObject($object) + { + return self::newReflectionClass( self::getClass( $object ) ); + } + + /** + * Given a class name and a proxy namespace return the proxy name. + * + * @param string $className + * @param string $proxyNamespace + * @return string + */ + public static function generateProxyClassName($className, $proxyNamespace) + { + return rtrim($proxyNamespace, '\\') . '\\'.Proxy::MARKER.'\\' . ltrim($className, '\\'); + } +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Util/Debug.php b/vendor/doctrine/common/lib/Doctrine/Common/Util/Debug.php new file mode 100644 index 0000000..57ae312 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Util/Debug.php @@ -0,0 +1,123 @@ +. + */ + +namespace Doctrine\Common\Util; + +/** + * Static class containing most used debug methods. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Giorgio Sironi + */ +final class Debug +{ + /** + * Private constructor (prevents from instantiation) + * + */ + private function __construct() {} + + /** + * Prints a dump of the public, protected and private properties of $var. + * + * @static + * @link http://xdebug.org/ + * @param mixed $var + * @param integer $maxDepth Maximum nesting level for object properties + * @param boolean $stripTags Flag that indicate if output should strip HTML tags + */ + public static function dump($var, $maxDepth = 2, $stripTags = true) + { + ini_set('html_errors', 'On'); + + if (extension_loaded('xdebug')) { + ini_set('xdebug.var_display_max_depth', $maxDepth); + } + + $var = self::export($var, $maxDepth++); + + ob_start(); + var_dump($var); + $dump = ob_get_contents(); + ob_end_clean(); + + echo ($stripTags ? strip_tags(html_entity_decode($dump)) : $dump); + + ini_set('html_errors', 'Off'); + } + + public static function export($var, $maxDepth) + { + $return = null; + $isObj = is_object($var); + + if ($isObj && in_array('Doctrine\Common\Collections\Collection', class_implements($var))) { + $var = $var->toArray(); + } + + if ($maxDepth) { + if (is_array($var)) { + $return = array(); + + foreach ($var as $k => $v) { + $return[$k] = self::export($v, $maxDepth - 1); + } + } else if ($isObj) { + $return = new \stdclass(); + if ($var instanceof \DateTime) { + $return->__CLASS__ = "DateTime"; + $return->date = $var->format('c'); + $return->timezone = $var->getTimeZone()->getName(); + } else { + $reflClass = ClassUtils::newReflectionObject($var); + $return->__CLASS__ = ClassUtils::getClass($var); + + if ($var instanceof \Doctrine\Common\Persistence\Proxy) { + $return->__IS_PROXY__ = true; + $return->__PROXY_INITIALIZED__ = $var->__isInitialized(); + } + + foreach ($reflClass->getProperties() as $reflProperty) { + $name = $reflProperty->getName(); + + $reflProperty->setAccessible(true); + $return->$name = self::export($reflProperty->getValue($var), $maxDepth - 1); + } + } + } else { + $return = $var; + } + } else { + $return = is_object($var) ? get_class($var) + : (is_array($var) ? 'Array(' . count($var) . ')' : $var); + } + + return $return; + } + + public static function toString($obj) + { + return method_exists('__toString', $obj) ? (string) $obj : get_class($obj) . '@' . spl_object_hash($obj); + } +} diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Util/Inflector.php b/vendor/doctrine/common/lib/Doctrine/Common/Util/Inflector.php new file mode 100644 index 0000000..ba1eb17 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Util/Inflector.php @@ -0,0 +1,72 @@ +. + */ + +namespace Doctrine\Common\Util; + +/** + * Doctrine inflector has static methods for inflecting text + * + * The methods in these classes are from several different sources collected + * across several different php projects and several different authors. The + * original author names and emails are not known + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 1.0 + * @version $Revision: 3189 $ + * @author Konsta Vesterinen + * @author Jonathan H. Wage + */ +class Inflector +{ + /** + * Convert word in to the format for a Doctrine table name. Converts 'ModelName' to 'model_name' + * + * @param string $word Word to tableize + * @return string $word Tableized word + */ + public static function tableize($word) + { + return strtolower(preg_replace('~(?<=\\w)([A-Z])~', '_$1', $word)); + } + + /** + * Convert a word in to the format for a Doctrine class name. Converts 'table_name' to 'TableName' + * + * @param string $word Word to classify + * @return string $word Classified word + */ + public static function classify($word) + { + return str_replace(" ", "", ucwords(strtr($word, "_-", " "))); + } + + /** + * Camelize a word. This uses the classify() method and turns the first character to lowercase + * + * @param string $word + * @return string $word + */ + public static function camelize($word) + { + return lcfirst(self::classify($word)); + } +} \ No newline at end of file diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Version.php b/vendor/doctrine/common/lib/Doctrine/Common/Version.php new file mode 100644 index 0000000..b7c9a82 --- /dev/null +++ b/vendor/doctrine/common/lib/Doctrine/Common/Version.php @@ -0,0 +1,55 @@ +. + */ + +namespace Doctrine\Common; + +/** + * Class to store and retrieve the version of Doctrine + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class Version +{ + /** + * Current Doctrine Version + */ + const VERSION = '2.2.2'; + + /** + * Compares a Doctrine version with the current one. + * + * @param string $version Doctrine version to compare. + * @return int Returns -1 if older, 0 if it is the same, 1 if version + * passed as argument is newer. + */ + public static function compare($version) + { + $currentVersion = str_replace(' ', '', strtolower(self::VERSION)); + $version = str_replace(' ', '', $version); + + return version_compare($version, $currentVersion); + } +} diff --git a/vendor/doctrine/common/phpunit.xml.dist b/vendor/doctrine/common/phpunit.xml.dist new file mode 100644 index 0000000..b9d3b34 --- /dev/null +++ b/vendor/doctrine/common/phpunit.xml.dist @@ -0,0 +1,31 @@ + + + + + + ./tests/Doctrine/ + + + + + + ./lib/Doctrine/ + + + + + + performance + + + diff --git a/vendor/doctrine/dbal/.travis.yml b/vendor/doctrine/dbal/.travis.yml new file mode 100644 index 0000000..ab6fde0 --- /dev/null +++ b/vendor/doctrine/dbal/.travis.yml @@ -0,0 +1,20 @@ +language: php + +php: + - 5.3 + - 5.4 +env: + - DB=mysql + - DB=pgsql + - DB=sqlite + +before_script: + - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'DROP DATABASE IF EXISTS doctrine_tests;' -U postgres; fi" + - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'DROP DATABASE IF EXISTS doctrine_tests_tmp;' -U postgres; fi" + - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database doctrine_tests;' -U postgres; fi" + - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database doctrine_tests_tmp;' -U postgres; fi" + - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS doctrine_tests_tmp;create database IF NOT EXISTS doctrine_tests;'; fi" + - git submodule update --init + +script: phpunit --configuration tests/travis/$DB.travis.xml + diff --git a/vendor/doctrine/dbal/LICENSE b/vendor/doctrine/dbal/LICENSE new file mode 100644 index 0000000..1c03f74 --- /dev/null +++ b/vendor/doctrine/dbal/LICENSE @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/vendor/doctrine/dbal/README.md b/vendor/doctrine/dbal/README.md new file mode 100644 index 0000000..70617c3 --- /dev/null +++ b/vendor/doctrine/dbal/README.md @@ -0,0 +1,14 @@ +# Doctrine DBAL + +Powerful database abstraction layer with many features for database schema introspection, schema management and PDO abstraction. + +* Master: [![Build Status](https://secure.travis-ci.org/doctrine/dbal.png?branch=master)](http://travis-ci.org/doctrine/dbal) +* Master: [![Build Status](https://secure.travis-ci.org/doctrine/dbal.png?branch=2.2)](http://travis-ci.org/doctrine/dbal) +* 2.1.x: [![Build Status](https://secure.travis-ci.org/doctrine/dbal.png?branch=2.1.x)](http://travis-ci.org/doctrine/dbal) + +## More resources: + +* [Website](http://www.doctrine-project.org) +* [Documentation](http://www.doctrine-project.org/projects/dbal/current/docs/en) +* [Issue Tracker](http://www.doctrine-project.org/jira/browse/DBAL) +* [Downloads](http://github.com/doctrine/dbal/downloads) diff --git a/vendor/doctrine/dbal/UPGRADE b/vendor/doctrine/dbal/UPGRADE new file mode 100644 index 0000000..9466d7a --- /dev/null +++ b/vendor/doctrine/dbal/UPGRADE @@ -0,0 +1,72 @@ +# Upgrade to 2.2 + +## Doctrine\DBAL\Connection#insert and Doctrine\DBAL\Connnection#update + +Both methods now accept an optional last parameter $types with binding types of the values passed. +This can potentially break child classes that have overwritten one of these methods. + +## Doctrine\DBAL\Connection#executeQuery + +Doctrine\DBAL\Connection#executeQuery() got a new last parameter "QueryCacheProfile $qcp" + +## Doctrine\DBAL\Driver\Statement split + +The Driver statement was split into a ResultStatement and the normal statement extending from it. +This seperates the configuration and the retrieval API from a statement. + +## MsSql Platform/SchemaManager renamed + +The MsSqlPlatform was renamed to SQLServerPlatform, the MsSqlSchemaManager was renamed +to SQLServerSchemaManager. + +## Cleanup SQLServer Platform version mess + +DBAL 2.1 and before were actually only compatible to SQL Server 2008, not earlier versions. +Still other parts of the platform did use old features instead of newly introduced datatypes +in SQL Server 2005. Starting with DBAL 2.2 you can pick the Doctrine abstraction exactly +matching your SQL Server version. + +The PDO SqlSrv driver now uses the new `SQLServer2008Platform` as default platform. +This platform uses new features of SQL Server as of version 2008. This also includes a switch +in the used fields for "text" and "blob" field types to: + + "text" => "VARCHAR(MAX)" + "blob" => "VARBINARY(MAX)" + +Additionally `SQLServerPlatform` in DBAL 2.1 and before used "DATE", "TIME" and "DATETIME2" for dates. +This types are only available since version 2008 and the introduction of an explicit +SQLServer 2008 platform makes this dependency explicit. + +An `SQLServer2005Platform` was also introduced to differentiate the features between +versions 2003, earlier and 2005. + +With this change the `SQLServerPlatform` now throws an exception for using limit queries +with an offset, since SQLServer 2003 and lower do not support this feature. + +To use the old SQL Server Platform, because you are using SQL Server 2003 and below use +the following configuration code: + + use Doctrine\DBAL\DriverManager; + use Doctrine\DBAL\Platforms\SQLServerPlatform; + use Doctrine\DBAL\Platforms\SQLServer2005Platform; + + // You are using SQL Server 2003 or earlier + $conn = DriverManager::getConnection(array( + 'driver' => 'pdo_sqlsrv', + 'platform' => new SQLServerPlatform() + // .. additional parameters + )); + + // You are using SQL Server 2005 + $conn = DriverManager::getConnection(array( + 'driver' => 'pdo_sqlsrv', + 'platform' => new SQLServer2005Platform() + // .. additional parameters + )); + + // You are using SQL Server 2008 + $conn = DriverManager::getConnection(array( + 'driver' => 'pdo_sqlsrv', + // 2008 is default platform + // .. additional parameters + )); diff --git a/vendor/doctrine/dbal/composer.json b/vendor/doctrine/dbal/composer.json new file mode 100644 index 0000000..9fca5d3 --- /dev/null +++ b/vendor/doctrine/dbal/composer.json @@ -0,0 +1,21 @@ +{ + "name": "doctrine/dbal", + "type": "library", + "description": "Database Abstraction Layer", + "keywords": ["dbal", "database", "persistence", "queryobject"], + "homepage": "http://www.doctrine-project.org", + "license": "LGPL", + "authors": [ + {"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"}, + {"name": "Roman Borschel", "email": "roman@code-factory.org"}, + {"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"}, + {"name": "Jonathan Wage", "email": "jonwage@gmail.com"} + ], + "require": { + "php": ">=5.3.2", + "doctrine/common": ">=2.2.0,<=2.2.99" + }, + "autoload": { + "psr-0": { "Doctrine\\DBAL": "lib/" } + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/ArrayStatement.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/ArrayStatement.php new file mode 100644 index 0000000..4818cd2 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/ArrayStatement.php @@ -0,0 +1,98 @@ +. + */ + +namespace Doctrine\DBAL\Cache; + +use Doctrine\DBAL\Driver\ResultStatement; +use PDO; + +class ArrayStatement implements \IteratorAggregate, ResultStatement +{ + private $data; + private $columnCount = 0; + private $num = 0; + private $defaultFetchStyle = PDO::FETCH_BOTH; + + public function __construct(array $data) + { + $this->data = $data; + if (count($data)) { + $this->columnCount = count($data[0]); + } + } + + public function closeCursor() + { + unset ($this->data); + } + + public function columnCount() + { + return $this->columnCount; + } + + public function setFetchMode($fetchStyle, $arg2 = null, $arg3 = null) + { + if ($arg2 !== null || $arg3 !== null) { + throw new \InvalidArgumentException("Caching layer does not support 2nd/3rd argument to setFetchMode()"); + } + + $this->defaultFetchStyle = $fetchStyle; + } + + public function getIterator() + { + $data = $this->fetchAll($this->defaultFetchStyle); + return new \ArrayIterator($data); + } + + public function fetch($fetchStyle = PDO::FETCH_BOTH) + { + if (isset($this->data[$this->num])) { + $row = $this->data[$this->num++]; + if ($fetchStyle === PDO::FETCH_ASSOC) { + return $row; + } else if ($fetchStyle === PDO::FETCH_NUM) { + return array_values($row); + } else if ($fetchStyle === PDO::FETCH_BOTH) { + return array_merge($row, array_values($row)); + } + } + return false; + } + + public function fetchAll($fetchStyle = PDO::FETCH_BOTH) + { + $rows = array(); + while ($row = $this->fetch($fetchStyle)) { + $rows[] = $row; + } + return $rows; + } + + public function fetchColumn($columnIndex = 0) + { + $row = $this->fetch(PDO::FETCH_NUM); + if (!isset($row[$columnIndex])) { + // TODO: verify this is correct behavior + return false; + } + return $row[$columnIndex]; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/CacheException.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/CacheException.php new file mode 100644 index 0000000..367ab81 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/CacheException.php @@ -0,0 +1,37 @@ +. + */ + +namespace Doctrine\DBAL\Cache; + +/** + * @author Benjamin Eberlei + * @since 2.2 + */ +class CacheException extends \Doctrine\DBAL\DBALException +{ + static public function noCacheKey() + { + return new self("No cache key was set."); + } + + static public function noResultDriverConfigured() + { + return new self("Trying to cache a query but no result driver is configured."); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/QueryCacheProfile.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/QueryCacheProfile.php new file mode 100644 index 0000000..1ffbd97 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/QueryCacheProfile.php @@ -0,0 +1,131 @@ +. + */ + +namespace Doctrine\DBAL\Cache; + +use Doctrine\Common\Cache\Cache; + +/** + * Query Cache Profile handles the data relevant for query caching. + * + * It is a value object, setter methods return NEW instances. + * + * @author Benjamin Eberlei + */ +class QueryCacheProfile +{ + /** + * @var Cache + */ + private $resultCacheDriver; + /** + * @var int + */ + private $lifetime = 0; + /** + * @var string + */ + private $cacheKey; + + /** + * @param int $lifetime + * @param string $cacheKey + * @param Cache $resultCache + */ + public function __construct($lifetime = 0, $cacheKey = null, Cache $resultCache = null) + { + $this->lifetime = $lifetime; + $this->cacheKey = $cacheKey; + $this->resultCacheDriver = $resultCache; + } + + /** + * @return Cache + */ + public function getResultCacheDriver() + { + return $this->resultCacheDriver; + } + + /** + * @return int + */ + public function getLifetime() + { + return $this->lifetime; + } + + /** + * @return string + */ + public function getCacheKey() + { + if ($this->cacheKey === null) { + throw CacheException::noCacheKey(); + } + return $this->cacheKey; + } + + /** + * Generate the real cache key from query, params and types. + * + * @param string $query + * @param array $params + * @param array $types + * @return array + */ + public function generateCacheKeys($query, $params, $types) + { + $realCacheKey = $query . "-" . serialize($params) . "-" . serialize($types); + // should the key be automatically generated using the inputs or is the cache key set? + if ($this->cacheKey === null) { + $cacheKey = sha1($realCacheKey); + } else { + $cacheKey = $this->cacheKey; + } + return array($cacheKey, $realCacheKey); + } + + /** + * @param Cache $cache + * @return QueryCacheProfile + */ + public function setResultCacheDriver(Cache $cache) + { + return new QueryCacheProfile($this->lifetime, $this->cacheKey, $cache); + } + + /** + * @param string|null $cacheKey + * @return QueryCacheProfile + */ + public function setCacheKey($cacheKey) + { + return new QueryCacheProfile($this->lifetime, $cacheKey, $this->resultCacheDriver); + } + + /** + * @param int $lifetime + * @return QueryCacheProfile + */ + public function setLifetime($lifetime) + { + return new QueryCacheProfile($lifetime, $this->cacheKey, $this->resultCacheDriver); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/ResultCacheStatement.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/ResultCacheStatement.php new file mode 100644 index 0000000..6054184 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/ResultCacheStatement.php @@ -0,0 +1,255 @@ +. + */ + +namespace Doctrine\DBAL\Cache; + +use Doctrine\DBAL\Driver\Statement; +use Doctrine\DBAL\Driver\ResultStatement; +use Doctrine\DBAL\Connection; +use Doctrine\Common\Cache\Cache; +use PDO; + +/** + * Cache statement for SQL results. + * + * A result is saved in multiple cache keys, there is the originally specified + * cache key which is just pointing to result rows by key. The following things + * have to be ensured: + * + * 1. lifetime of the original key has to be longer than that of all the individual rows keys + * 2. if any one row key is missing the query has to be re-executed. + * + * Also you have to realize that the cache will load the whole result into memory at once to ensure 2. + * This means that the memory usage for cached results might increase by using this feature. + */ +class ResultCacheStatement implements \IteratorAggregate, ResultStatement +{ + /** + * @var \Doctrine\Common\Cache\Cache + */ + private $resultCache; + + /** + * + * @var string + */ + private $cacheKey; + + /** + * @var string + */ + private $realKey; + + /** + * @var int + */ + private $lifetime; + + /** + * @var Doctrine\DBAL\Driver\Statement + */ + private $statement; + + /** + * Did we reach the end of the statement? + * + * @var bool + */ + private $emptied = false; + + /** + * @var array + */ + private $data; + + /** + * @var int + */ + private $defaultFetchStyle = PDO::FETCH_BOTH; + + /** + * @param Statement $stmt + * @param Cache $resultCache + * @param string $cacheKey + * @param string $realKey + * @param int $lifetime + */ + public function __construct(Statement $stmt, Cache $resultCache, $cacheKey, $realKey, $lifetime) + { + $this->statement = $stmt; + $this->resultCache = $resultCache; + $this->cacheKey = $cacheKey; + $this->realKey = $realKey; + $this->lifetime = $lifetime; + } + + /** + * Closes the cursor, enabling the statement to be executed again. + * + * @return boolean Returns TRUE on success or FALSE on failure. + */ + public function closeCursor() + { + $this->statement->closeCursor(); + if ($this->emptied && $this->data !== null) { + $data = $this->resultCache->fetch($this->cacheKey); + if (!$data) { + $data = array(); + } + $data[$this->realKey] = $this->data; + + $this->resultCache->save($this->cacheKey, $data, $this->lifetime); + unset($this->data); + } + } + + /** + * columnCount + * Returns the number of columns in the result set + * + * @return integer Returns the number of columns in the result set represented + * by the PDOStatement object. If there is no result set, + * this method should return 0. + */ + public function columnCount() + { + return $this->statement->columnCount(); + } + + public function setFetchMode($fetchStyle, $arg2 = null, $arg3 = null) + { + $this->defaultFetchStyle = $fetchStyle; + } + + public function getIterator() + { + $data = $this->fetchAll($this->defaultFetchStyle); + return new \ArrayIterator($data); + } + + /** + * fetch + * + * @see Query::HYDRATE_* constants + * @param integer $fetchStyle Controls how the next row will be returned to the caller. + * This value must be one of the Query::HYDRATE_* constants, + * defaulting to Query::HYDRATE_BOTH + * + * @param integer $cursorOrientation For a PDOStatement object representing a scrollable cursor, + * this value determines which row will be returned to the caller. + * This value must be one of the Query::HYDRATE_ORI_* constants, defaulting to + * Query::HYDRATE_ORI_NEXT. To request a scrollable cursor for your + * PDOStatement object, + * you must set the PDO::ATTR_CURSOR attribute to Doctrine::CURSOR_SCROLL when you + * prepare the SQL statement with Doctrine_Adapter_Interface->prepare(). + * + * @param integer $cursorOffset For a PDOStatement object representing a scrollable cursor for which the + * $cursorOrientation parameter is set to Query::HYDRATE_ORI_ABS, this value specifies + * the absolute number of the row in the result set that shall be fetched. + * + * For a PDOStatement object representing a scrollable cursor for + * which the $cursorOrientation parameter is set to Query::HYDRATE_ORI_REL, this value + * specifies the row to fetch relative to the cursor position before + * PDOStatement->fetch() was called. + * + * @return mixed + */ + public function fetch($fetchStyle = PDO::FETCH_BOTH) + { + if ($this->data === null) { + $this->data = array(); + } + + $row = $this->statement->fetch(PDO::FETCH_ASSOC); + if ($row) { + $this->data[] = $row; + + if ($fetchStyle == PDO::FETCH_ASSOC) { + return $row; + } else if ($fetchStyle == PDO::FETCH_NUM) { + return array_values($row); + } else if ($fetchStyle == PDO::FETCH_BOTH) { + return array_merge($row, array_values($row)); + } else { + throw new \InvalidArgumentException("Invalid fetch-style given for caching result."); + } + } + $this->emptied = true; + return false; + } + + /** + * Returns an array containing all of the result set rows + * + * @param integer $fetchStyle Controls how the next row will be returned to the caller. + * This value must be one of the Query::HYDRATE_* constants, + * defaulting to Query::HYDRATE_BOTH + * + * @param integer $columnIndex Returns the indicated 0-indexed column when the value of $fetchStyle is + * Query::HYDRATE_COLUMN. Defaults to 0. + * + * @return array + */ + public function fetchAll($fetchStyle = PDO::FETCH_BOTH) + { + $rows = array(); + while ($row = $this->fetch($fetchStyle)) { + $rows[] = $row; + } + return $rows; + } + + /** + * fetchColumn + * Returns a single column from the next row of a + * result set or FALSE if there are no more rows. + * + * @param integer $columnIndex 0-indexed number of the column you wish to retrieve from the row. If no + * value is supplied, PDOStatement->fetchColumn() + * fetches the first column. + * + * @return string returns a single column in the next row of a result set. + */ + public function fetchColumn($columnIndex = 0) + { + $row = $this->fetch(PDO::FETCH_NUM); + if (!isset($row[$columnIndex])) { + // TODO: verify this is correct behavior + return false; + } + return $row[$columnIndex]; + } + + /** + * rowCount + * rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement + * executed by the corresponding object. + * + * If the last SQL statement executed by the associated Statement object was a SELECT statement, + * some databases may return the number of rows returned by that statement. However, + * this behaviour is not guaranteed for all databases and should not be + * relied on for portable applications. + * + * @return integer Returns the number of rows. + */ + public function rowCount() + { + return $this->statement->rowCount(); + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Configuration.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Configuration.php new file mode 100644 index 0000000..03327fb --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Configuration.php @@ -0,0 +1,113 @@ +. + */ + +namespace Doctrine\DBAL; + +use Doctrine\DBAL\Logging\SQLLogger; +use Doctrine\Common\Cache\Cache; + +/** + * Configuration container for the Doctrine DBAL. + * + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @internal When adding a new configuration option just write a getter/setter + * pair and add the option to the _attributes array with a proper default value. + */ +class Configuration +{ + /** + * The attributes that are contained in the configuration. + * Values are default values. + * + * @var array + */ + protected $_attributes = array(); + + /** + * Sets the SQL logger to use. Defaults to NULL which means SQL logging is disabled. + * + * @param SQLLogger $logger + */ + public function setSQLLogger(SQLLogger $logger = null) + { + $this->_attributes['sqlLogger'] = $logger; + } + + /** + * Gets the SQL logger that is used. + * + * @return SQLLogger + */ + public function getSQLLogger() + { + return isset($this->_attributes['sqlLogger']) ? + $this->_attributes['sqlLogger'] : null; + } + + /** + * Gets the cache driver implementation that is used for query result caching. + * + * @return \Doctrine\Common\Cache\Cache + */ + public function getResultCacheImpl() + { + return isset($this->_attributes['resultCacheImpl']) ? + $this->_attributes['resultCacheImpl'] : null; + } + + /** + * Sets the cache driver implementation that is used for query result caching. + * + * @param \Doctrine\Common\Cache\Cache $cacheImpl + */ + public function setResultCacheImpl(Cache $cacheImpl) + { + $this->_attributes['resultCacheImpl'] = $cacheImpl; + } + + /** + * Filter schema assets expression. + * + * Only include tables/sequences matching the filter expression regexp in + * schema instances generated for the active connection when calling + * {AbstractSchemaManager#createSchema()}. + * + * @param string $filterExpression + */ + public function setFilterSchemaAssetsExpression($filterExpression) + { + $this->_attributes['filterSchemaAssetsExpression'] = $filterExpression; + } + + /** + * Return filter schema assets expression. + * + * @return string|null + */ + public function getFilterSchemaAssetsExpression() + { + if (isset($this->_attributes['filterSchemaAssetsExpression'])) { + return $this->_attributes['filterSchemaAssetsExpression']; + } + return null; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php new file mode 100644 index 0000000..abe9376 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php @@ -0,0 +1,1168 @@ +. + */ + +namespace Doctrine\DBAL; + +use PDO, Closure, Exception, + Doctrine\DBAL\Types\Type, + Doctrine\DBAL\Driver\Connection as DriverConnection, + Doctrine\Common\EventManager, + Doctrine\DBAL\DBALException, + Doctrine\DBAL\Cache\ResultCacheStatement, + Doctrine\DBAL\Cache\QueryCacheProfile, + Doctrine\DBAL\Cache\ArrayStatement, + Doctrine\DBAL\Cache\CacheException; + +/** + * A wrapper around a Doctrine\DBAL\Driver\Connection that adds features like + * events, transaction isolation levels, configuration, emulated transaction nesting, + * lazy connecting and more. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Konsta Vesterinen + * @author Lukas Smith (MDB2 library) + * @author Benjamin Eberlei + */ +class Connection implements DriverConnection +{ + /** + * Constant for transaction isolation level READ UNCOMMITTED. + */ + const TRANSACTION_READ_UNCOMMITTED = 1; + + /** + * Constant for transaction isolation level READ COMMITTED. + */ + const TRANSACTION_READ_COMMITTED = 2; + + /** + * Constant for transaction isolation level REPEATABLE READ. + */ + const TRANSACTION_REPEATABLE_READ = 3; + + /** + * Constant for transaction isolation level SERIALIZABLE. + */ + const TRANSACTION_SERIALIZABLE = 4; + + /** + * Represents an array of ints to be expanded by Doctrine SQL parsing. + * + * @var int + */ + const PARAM_INT_ARRAY = 101; + + /** + * Represents an array of strings to be expanded by Doctrine SQL parsing. + * + * @var int + */ + const PARAM_STR_ARRAY = 102; + + /** + * Offset by which PARAM_* constants are detected as arrays of the param type. + * + * @var int + */ + const ARRAY_PARAM_OFFSET = 100; + + /** + * The wrapped driver connection. + * + * @var Doctrine\DBAL\Driver\Connection + */ + protected $_conn; + + /** + * @var Doctrine\DBAL\Configuration + */ + protected $_config; + + /** + * @var Doctrine\Common\EventManager + */ + protected $_eventManager; + + /** + * @var Doctrine\DBAL\Query\ExpressionBuilder + */ + protected $_expr; + + /** + * Whether or not a connection has been established. + * + * @var boolean + */ + private $_isConnected = false; + + /** + * The transaction nesting level. + * + * @var integer + */ + private $_transactionNestingLevel = 0; + + /** + * The currently active transaction isolation level. + * + * @var integer + */ + private $_transactionIsolationLevel; + + /** + * If nested transations should use savepoints + * + * @var integer + */ + private $_nestTransactionsWithSavepoints; + + /** + * The parameters used during creation of the Connection instance. + * + * @var array + */ + private $_params = array(); + + /** + * The DatabasePlatform object that provides information about the + * database platform used by the connection. + * + * @var Doctrine\DBAL\Platforms\AbstractPlatform + */ + protected $_platform; + + /** + * The schema manager. + * + * @var Doctrine\DBAL\Schema\SchemaManager + */ + protected $_schemaManager; + + /** + * The used DBAL driver. + * + * @var Doctrine\DBAL\Driver + */ + protected $_driver; + + /** + * Flag that indicates whether the current transaction is marked for rollback only. + * + * @var boolean + */ + private $_isRollbackOnly = false; + + /** + * Initializes a new instance of the Connection class. + * + * @param array $params The connection parameters. + * @param Driver $driver + * @param Configuration $config + * @param EventManager $eventManager + */ + public function __construct(array $params, Driver $driver, Configuration $config = null, + EventManager $eventManager = null) + { + $this->_driver = $driver; + $this->_params = $params; + + if (isset($params['pdo'])) { + $this->_conn = $params['pdo']; + $this->_isConnected = true; + } + + // Create default config and event manager if none given + if ( ! $config) { + $config = new Configuration(); + } + + if ( ! $eventManager) { + $eventManager = new EventManager(); + } + + $this->_config = $config; + $this->_eventManager = $eventManager; + + $this->_expr = new Query\Expression\ExpressionBuilder($this); + + if ( ! isset($params['platform'])) { + $this->_platform = $driver->getDatabasePlatform(); + } else if ($params['platform'] instanceof Platforms\AbstractPlatform) { + $this->_platform = $params['platform']; + } else { + throw DBALException::invalidPlatformSpecified(); + } + + $this->_platform->setEventManager($eventManager); + + $this->_transactionIsolationLevel = $this->_platform->getDefaultTransactionIsolationLevel(); + } + + /** + * Gets the parameters used during instantiation. + * + * @return array $params + */ + public function getParams() + { + return $this->_params; + } + + /** + * Gets the name of the database this Connection is connected to. + * + * @return string $database + */ + public function getDatabase() + { + return $this->_driver->getDatabase($this); + } + + /** + * Gets the hostname of the currently connected database. + * + * @return string + */ + public function getHost() + { + return isset($this->_params['host']) ? $this->_params['host'] : null; + } + + /** + * Gets the port of the currently connected database. + * + * @return mixed + */ + public function getPort() + { + return isset($this->_params['port']) ? $this->_params['port'] : null; + } + + /** + * Gets the username used by this connection. + * + * @return string + */ + public function getUsername() + { + return isset($this->_params['user']) ? $this->_params['user'] : null; + } + + /** + * Gets the password used by this connection. + * + * @return string + */ + public function getPassword() + { + return isset($this->_params['password']) ? $this->_params['password'] : null; + } + + /** + * Gets the DBAL driver instance. + * + * @return \Doctrine\DBAL\Driver + */ + public function getDriver() + { + return $this->_driver; + } + + /** + * Gets the Configuration used by the Connection. + * + * @return \Doctrine\DBAL\Configuration + */ + public function getConfiguration() + { + return $this->_config; + } + + /** + * Gets the EventManager used by the Connection. + * + * @return \Doctrine\Common\EventManager + */ + public function getEventManager() + { + return $this->_eventManager; + } + + /** + * Gets the DatabasePlatform for the connection. + * + * @return \Doctrine\DBAL\Platforms\AbstractPlatform + */ + public function getDatabasePlatform() + { + return $this->_platform; + } + + /** + * Gets the ExpressionBuilder for the connection. + * + * @return \Doctrine\DBAL\Query\ExpressionBuilder + */ + public function getExpressionBuilder() + { + return $this->_expr; + } + + /** + * Establishes the connection with the database. + * + * @return boolean TRUE if the connection was successfully established, FALSE if + * the connection is already open. + */ + public function connect() + { + if ($this->_isConnected) return false; + + $driverOptions = isset($this->_params['driverOptions']) ? + $this->_params['driverOptions'] : array(); + $user = isset($this->_params['user']) ? $this->_params['user'] : null; + $password = isset($this->_params['password']) ? + $this->_params['password'] : null; + + $this->_conn = $this->_driver->connect($this->_params, $user, $password, $driverOptions); + $this->_isConnected = true; + + if ($this->_eventManager->hasListeners(Events::postConnect)) { + $eventArgs = new Event\ConnectionEventArgs($this); + $this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs); + } + + return true; + } + + /** + * Prepares and executes an SQL query and returns the first row of the result + * as an associative array. + * + * @param string $statement The SQL query. + * @param array $params The query parameters. + * @return array + */ + public function fetchAssoc($statement, array $params = array()) + { + return $this->executeQuery($statement, $params)->fetch(PDO::FETCH_ASSOC); + } + + /** + * Prepares and executes an SQL query and returns the first row of the result + * as a numerically indexed array. + * + * @param string $statement sql query to be executed + * @param array $params prepared statement params + * @return array + */ + public function fetchArray($statement, array $params = array()) + { + return $this->executeQuery($statement, $params)->fetch(PDO::FETCH_NUM); + } + + /** + * Prepares and executes an SQL query and returns the value of a single column + * of the first row of the result. + * + * @param string $statement sql query to be executed + * @param array $params prepared statement params + * @param int $colnum 0-indexed column number to retrieve + * @return mixed + */ + public function fetchColumn($statement, array $params = array(), $colnum = 0) + { + return $this->executeQuery($statement, $params)->fetchColumn($colnum); + } + + /** + * Whether an actual connection to the database is established. + * + * @return boolean + */ + public function isConnected() + { + return $this->_isConnected; + } + + /** + * Checks whether a transaction is currently active. + * + * @return boolean TRUE if a transaction is currently active, FALSE otherwise. + */ + public function isTransactionActive() + { + return $this->_transactionNestingLevel > 0; + } + + /** + * Executes an SQL DELETE statement on a table. + * + * @param string $table The name of the table on which to delete. + * @param array $identifier The deletion criteria. An associateve array containing column-value pairs. + * @return integer The number of affected rows. + */ + public function delete($tableName, array $identifier) + { + $this->connect(); + + $criteria = array(); + + foreach (array_keys($identifier) as $columnName) { + $criteria[] = $columnName . ' = ?'; + } + + $query = 'DELETE FROM ' . $tableName . ' WHERE ' . implode(' AND ', $criteria); + + return $this->executeUpdate($query, array_values($identifier)); + } + + /** + * Closes the connection. + * + * @return void + */ + public function close() + { + unset($this->_conn); + + $this->_isConnected = false; + } + + /** + * Sets the transaction isolation level. + * + * @param integer $level The level to set. + */ + public function setTransactionIsolation($level) + { + $this->_transactionIsolationLevel = $level; + + return $this->executeUpdate($this->_platform->getSetTransactionIsolationSQL($level)); + } + + /** + * Gets the currently active transaction isolation level. + * + * @return integer The current transaction isolation level. + */ + public function getTransactionIsolation() + { + return $this->_transactionIsolationLevel; + } + + /** + * Executes an SQL UPDATE statement on a table. + * + * @param string $table The name of the table to update. + * @param array $identifier The update criteria. An associative array containing column-value pairs. + * @param array $types Types of the merged $data and $identifier arrays in that order. + * @return integer The number of affected rows. + */ + public function update($tableName, array $data, array $identifier, array $types = array()) + { + $this->connect(); + $set = array(); + foreach ($data as $columnName => $value) { + $set[] = $columnName . ' = ?'; + } + + $params = array_merge(array_values($data), array_values($identifier)); + + $sql = 'UPDATE ' . $tableName . ' SET ' . implode(', ', $set) + . ' WHERE ' . implode(' = ? AND ', array_keys($identifier)) + . ' = ?'; + + return $this->executeUpdate($sql, $params, $types); + } + + /** + * Inserts a table row with specified data. + * + * @param string $table The name of the table to insert data into. + * @param array $data An associative array containing column-value pairs. + * @param array $types Types of the inserted data. + * @return integer The number of affected rows. + */ + public function insert($tableName, array $data, array $types = array()) + { + $this->connect(); + + // column names are specified as array keys + $cols = array(); + $placeholders = array(); + + foreach ($data as $columnName => $value) { + $cols[] = $columnName; + $placeholders[] = '?'; + } + + $query = 'INSERT INTO ' . $tableName + . ' (' . implode(', ', $cols) . ')' + . ' VALUES (' . implode(', ', $placeholders) . ')'; + + return $this->executeUpdate($query, array_values($data), $types); + } + + /** + * Sets the given charset on the current connection. + * + * @param string $charset The charset to set. + */ + public function setCharset($charset) + { + $this->executeUpdate($this->_platform->getSetCharsetSQL($charset)); + } + + /** + * Quote a string so it can be safely used as a table or column name, even if + * it is a reserved name. + * + * Delimiting style depends on the underlying database platform that is being used. + * + * NOTE: Just because you CAN use quoted identifiers does not mean + * you SHOULD use them. In general, they end up causing way more + * problems than they solve. + * + * @param string $str The name to be quoted. + * @return string The quoted name. + */ + public function quoteIdentifier($str) + { + return $this->_platform->quoteIdentifier($str); + } + + /** + * Quotes a given input parameter. + * + * @param mixed $input Parameter to be quoted. + * @param string $type Type of the parameter. + * @return string The quoted parameter. + */ + public function quote($input, $type = null) + { + $this->connect(); + + list($value, $bindingType) = $this->getBindingInfo($input, $type); + return $this->_conn->quote($value, $bindingType); + } + + /** + * Prepares and executes an SQL query and returns the result as an associative array. + * + * @param string $sql The SQL query. + * @param array $params The query parameters. + * @return array + */ + public function fetchAll($sql, array $params = array()) + { + return $this->executeQuery($sql, $params)->fetchAll(PDO::FETCH_ASSOC); + } + + /** + * Prepares an SQL statement. + * + * @param string $statement The SQL statement to prepare. + * @return Doctrine\DBAL\Driver\Statement The prepared statement. + */ + public function prepare($statement) + { + $this->connect(); + + return new Statement($statement, $this); + } + + /** + * Executes an, optionally parameterized, SQL query. + * + * If the query is parameterized, a prepared statement is used. + * If an SQLLogger is configured, the execution is logged. + * + * @param string $query The SQL query to execute. + * @param array $params The parameters to bind to the query, if any. + * @param array $types The types the previous parameters are in. + * @param QueryCacheProfile $qcp + * @return Doctrine\DBAL\Driver\Statement The executed statement. + * @internal PERF: Directly prepares a driver statement, not a wrapper. + */ + public function executeQuery($query, array $params = array(), $types = array(), QueryCacheProfile $qcp = null) + { + if ($qcp !== null) { + return $this->executeCacheQuery($query, $params, $types, $qcp); + } + + $this->connect(); + + $hasLogger = $this->_config->getSQLLogger() !== null; + if ($hasLogger) { + $this->_config->getSQLLogger()->startQuery($query, $params, $types); + } + + if ($params) { + list($query, $params, $types) = SQLParserUtils::expandListParameters($query, $params, $types); + + $stmt = $this->_conn->prepare($query); + if ($types) { + $this->_bindTypedValues($stmt, $params, $types); + $stmt->execute(); + } else { + $stmt->execute($params); + } + } else { + $stmt = $this->_conn->query($query); + } + + if ($hasLogger) { + $this->_config->getSQLLogger()->stopQuery(); + } + + return $stmt; + } + + /** + * Execute a caching query and + * + * @param string $query + * @param array $params + * @param array $types + * @param QueryCacheProfile $qcp + * @return \Doctrine\DBAL\Driver\ResultStatement + */ + public function executeCacheQuery($query, $params, $types, QueryCacheProfile $qcp) + { + $resultCache = $qcp->getResultCacheDriver() ?: $this->_config->getResultCacheImpl(); + if (!$resultCache) { + throw CacheException::noResultDriverConfigured(); + } + + list($cacheKey, $realKey) = $qcp->generateCacheKeys($query, $params, $types); + + // fetch the row pointers entry + if ($data = $resultCache->fetch($cacheKey)) { + // is the real key part of this row pointers map or is the cache only pointing to other cache keys? + if (isset($data[$realKey])) { + return new ArrayStatement($data[$realKey]); + } else if (array_key_exists($realKey, $data)) { + return new ArrayStatement(array()); + } + } + return new ResultCacheStatement($this->executeQuery($query, $params, $types), $resultCache, $cacheKey, $realKey, $qcp->getLifetime()); + } + + /** + * Executes an, optionally parameterized, SQL query and returns the result, + * applying a given projection/transformation function on each row of the result. + * + * @param string $query The SQL query to execute. + * @param array $params The parameters, if any. + * @param Closure $mapper The transformation function that is applied on each row. + * The function receives a single paramater, an array, that + * represents a row of the result set. + * @return mixed The projected result of the query. + */ + public function project($query, array $params, Closure $function) + { + $result = array(); + $stmt = $this->executeQuery($query, $params ?: array()); + + while ($row = $stmt->fetch()) { + $result[] = $function($row); + } + + $stmt->closeCursor(); + + return $result; + } + + /** + * Executes an SQL statement, returning a result set as a Statement object. + * + * @param string $statement + * @param integer $fetchType + * @return Doctrine\DBAL\Driver\Statement + */ + public function query() + { + $this->connect(); + + $args = func_get_args(); + + $logger = $this->getConfiguration()->getSQLLogger(); + if ($logger) { + $logger->startQuery($args[0]); + } + + $statement = call_user_func_array(array($this->_conn, 'query'), $args); + + if ($logger) { + $logger->stopQuery(); + } + + return $statement; + } + + /** + * Executes an SQL INSERT/UPDATE/DELETE query with the given parameters + * and returns the number of affected rows. + * + * This method supports PDO binding types as well as DBAL mapping types. + * + * @param string $query The SQL query. + * @param array $params The query parameters. + * @param array $types The parameter types. + * @return integer The number of affected rows. + * @internal PERF: Directly prepares a driver statement, not a wrapper. + */ + public function executeUpdate($query, array $params = array(), array $types = array()) + { + $this->connect(); + + $hasLogger = $this->_config->getSQLLogger() !== null; + if ($hasLogger) { + $this->_config->getSQLLogger()->startQuery($query, $params, $types); + } + + if ($params) { + list($query, $params, $types) = SQLParserUtils::expandListParameters($query, $params, $types); + + $stmt = $this->_conn->prepare($query); + if ($types) { + $this->_bindTypedValues($stmt, $params, $types); + $stmt->execute(); + } else { + $stmt->execute($params); + } + $result = $stmt->rowCount(); + } else { + $result = $this->_conn->exec($query); + } + + if ($hasLogger) { + $this->_config->getSQLLogger()->stopQuery(); + } + + return $result; + } + + /** + * Execute an SQL statement and return the number of affected rows. + * + * @param string $statement + * @return integer The number of affected rows. + */ + public function exec($statement) + { + $this->connect(); + return $this->_conn->exec($statement); + } + + /** + * Returns the current transaction nesting level. + * + * @return integer The nesting level. A value of 0 means there's no active transaction. + */ + public function getTransactionNestingLevel() + { + return $this->_transactionNestingLevel; + } + + /** + * Fetch the SQLSTATE associated with the last database operation. + * + * @return integer The last error code. + */ + public function errorCode() + { + $this->connect(); + return $this->_conn->errorCode(); + } + + /** + * Fetch extended error information associated with the last database operation. + * + * @return array The last error information. + */ + public function errorInfo() + { + $this->connect(); + return $this->_conn->errorInfo(); + } + + /** + * Returns the ID of the last inserted row, or the last value from a sequence object, + * depending on the underlying driver. + * + * Note: This method may not return a meaningful or consistent result across different drivers, + * because the underlying database may not even support the notion of AUTO_INCREMENT/IDENTITY + * columns or sequences. + * + * @param string $seqName Name of the sequence object from which the ID should be returned. + * @return string A string representation of the last inserted ID. + */ + public function lastInsertId($seqName = null) + { + $this->connect(); + return $this->_conn->lastInsertId($seqName); + } + + /** + * Executes a function in a transaction. + * + * The function gets passed this Connection instance as an (optional) parameter. + * + * If an exception occurs during execution of the function or transaction commit, + * the transaction is rolled back and the exception re-thrown. + * + * @param Closure $func The function to execute transactionally. + */ + public function transactional(Closure $func) + { + $this->beginTransaction(); + try { + $func($this); + $this->commit(); + } catch (Exception $e) { + $this->rollback(); + throw $e; + } + } + + /** + * Set if nested transactions should use savepoints + * + * @param boolean + * @return void + */ + public function setNestTransactionsWithSavepoints($nestTransactionsWithSavepoints) + { + if ($this->_transactionNestingLevel > 0) { + throw ConnectionException::mayNotAlterNestedTransactionWithSavepointsInTransaction(); + } + + if (!$this->_platform->supportsSavepoints()) { + throw ConnectionException::savepointsNotSupported(); + } + + $this->_nestTransactionsWithSavepoints = $nestTransactionsWithSavepoints; + } + + /** + * Get if nested transactions should use savepoints + * + * @return boolean + */ + public function getNestTransactionsWithSavepoints() + { + return $this->_nestTransactionsWithSavepoints; + } + + /** + * Returns the savepoint name to use for nested transactions are false if they are not supported + * "savepointFormat" parameter is not set + * + * @return mixed a string with the savepoint name or false + */ + protected function _getNestedTransactionSavePointName() + { + return 'DOCTRINE2_SAVEPOINT_'.$this->_transactionNestingLevel; + } + + /** + * Starts a transaction by suspending auto-commit mode. + * + * @return void + */ + public function beginTransaction() + { + $this->connect(); + + ++$this->_transactionNestingLevel; + + if ($this->_transactionNestingLevel == 1) { + $this->_conn->beginTransaction(); + } else if ($this->_nestTransactionsWithSavepoints) { + $this->createSavepoint($this->_getNestedTransactionSavePointName()); + } + } + + /** + * Commits the current transaction. + * + * @return void + * @throws ConnectionException If the commit failed due to no active transaction or + * because the transaction was marked for rollback only. + */ + public function commit() + { + if ($this->_transactionNestingLevel == 0) { + throw ConnectionException::noActiveTransaction(); + } + if ($this->_isRollbackOnly) { + throw ConnectionException::commitFailedRollbackOnly(); + } + + $this->connect(); + + if ($this->_transactionNestingLevel == 1) { + $this->_conn->commit(); + } else if ($this->_nestTransactionsWithSavepoints) { + $this->releaseSavepoint($this->_getNestedTransactionSavePointName()); + } + + --$this->_transactionNestingLevel; + } + + /** + * Cancel any database changes done during the current transaction. + * + * this method can be listened with onPreTransactionRollback and onTransactionRollback + * eventlistener methods + * + * @throws ConnectionException If the rollback operation failed. + */ + public function rollback() + { + if ($this->_transactionNestingLevel == 0) { + throw ConnectionException::noActiveTransaction(); + } + + $this->connect(); + + if ($this->_transactionNestingLevel == 1) { + $this->_transactionNestingLevel = 0; + $this->_conn->rollback(); + $this->_isRollbackOnly = false; + } else if ($this->_nestTransactionsWithSavepoints) { + $this->rollbackSavepoint($this->_getNestedTransactionSavePointName()); + --$this->_transactionNestingLevel; + } else { + $this->_isRollbackOnly = true; + --$this->_transactionNestingLevel; + } + } + + /** + * createSavepoint + * creates a new savepoint + * + * @param string $savepoint name of a savepoint to set + * @return void + */ + public function createSavepoint($savepoint) + { + if (!$this->_platform->supportsSavepoints()) { + throw ConnectionException::savepointsNotSupported(); + } + + $this->_conn->exec($this->_platform->createSavePoint($savepoint)); + } + + /** + * releaseSavePoint + * releases given savepoint + * + * @param string $savepoint name of a savepoint to release + * @return void + */ + public function releaseSavepoint($savepoint) + { + if (!$this->_platform->supportsSavepoints()) { + throw ConnectionException::savepointsNotSupported(); + } + + if ($this->_platform->supportsReleaseSavepoints()) { + $this->_conn->exec($this->_platform->releaseSavePoint($savepoint)); + } + } + + /** + * rollbackSavePoint + * releases given savepoint + * + * @param string $savepoint name of a savepoint to rollback to + * @return void + */ + public function rollbackSavepoint($savepoint) + { + if (!$this->_platform->supportsSavepoints()) { + throw ConnectionException::savepointsNotSupported(); + } + + $this->_conn->exec($this->_platform->rollbackSavePoint($savepoint)); + } + + /** + * Gets the wrapped driver connection. + * + * @return Doctrine\DBAL\Driver\Connection + */ + public function getWrappedConnection() + { + $this->connect(); + + return $this->_conn; + } + + /** + * Gets the SchemaManager that can be used to inspect or change the + * database schema through the connection. + * + * @return Doctrine\DBAL\Schema\AbstractSchemaManager + */ + public function getSchemaManager() + { + if ( ! $this->_schemaManager) { + $this->_schemaManager = $this->_driver->getSchemaManager($this); + } + + return $this->_schemaManager; + } + + /** + * Marks the current transaction so that the only possible + * outcome for the transaction to be rolled back. + * + * @throws ConnectionException If no transaction is active. + */ + public function setRollbackOnly() + { + if ($this->_transactionNestingLevel == 0) { + throw ConnectionException::noActiveTransaction(); + } + $this->_isRollbackOnly = true; + } + + /** + * Check whether the current transaction is marked for rollback only. + * + * @return boolean + * @throws ConnectionException If no transaction is active. + */ + public function isRollbackOnly() + { + if ($this->_transactionNestingLevel == 0) { + throw ConnectionException::noActiveTransaction(); + } + return $this->_isRollbackOnly; + } + + /** + * Converts a given value to its database representation according to the conversion + * rules of a specific DBAL mapping type. + * + * @param mixed $value The value to convert. + * @param string $type The name of the DBAL mapping type. + * @return mixed The converted value. + */ + public function convertToDatabaseValue($value, $type) + { + return Type::getType($type)->convertToDatabaseValue($value, $this->_platform); + } + + /** + * Converts a given value to its PHP representation according to the conversion + * rules of a specific DBAL mapping type. + * + * @param mixed $value The value to convert. + * @param string $type The name of the DBAL mapping type. + * @return mixed The converted type. + */ + public function convertToPHPValue($value, $type) + { + return Type::getType($type)->convertToPHPValue($value, $this->_platform); + } + + /** + * Binds a set of parameters, some or all of which are typed with a PDO binding type + * or DBAL mapping type, to a given statement. + * + * @param $stmt The statement to bind the values to. + * @param array $params The map/list of named/positional parameters. + * @param array $types The parameter types (PDO binding types or DBAL mapping types). + * @internal Duck-typing used on the $stmt parameter to support driver statements as well as + * raw PDOStatement instances. + */ + private function _bindTypedValues($stmt, array $params, array $types) + { + // Check whether parameters are positional or named. Mixing is not allowed, just like in PDO. + if (is_int(key($params))) { + // Positional parameters + $typeOffset = array_key_exists(0, $types) ? -1 : 0; + $bindIndex = 1; + foreach ($params as $position => $value) { + $typeIndex = $bindIndex + $typeOffset; + if (isset($types[$typeIndex])) { + $type = $types[$typeIndex]; + list($value, $bindingType) = $this->getBindingInfo($value, $type); + $stmt->bindValue($bindIndex, $value, $bindingType); + } else { + $stmt->bindValue($bindIndex, $value); + } + ++$bindIndex; + } + } else { + // Named parameters + foreach ($params as $name => $value) { + if (isset($types[$name])) { + $type = $types[$name]; + list($value, $bindingType) = $this->getBindingInfo($value, $type); + $stmt->bindValue($name, $value, $bindingType); + } else { + $stmt->bindValue($name, $value); + } + } + } + } + + /** + * Gets the binding type of a given type. The given type can be a PDO or DBAL mapping type. + * + * @param mixed $value The value to bind + * @param mixed $type The type to bind (PDO or DBAL) + * @return array [0] => the (escaped) value, [1] => the binding type + */ + private function getBindingInfo($value, $type) + { + if (is_string($type)) { + $type = Type::getType($type); + } + if ($type instanceof Type) { + $value = $type->convertToDatabaseValue($value, $this->_platform); + $bindingType = $type->getBindingType(); + } else { + $bindingType = $type; // PDO::PARAM_* constants + } + return array($value, $bindingType); + } + + /** + * Create a new instance of a SQL query builder. + * + * @return Query\QueryBuilder + */ + public function createQueryBuilder() + { + return new Query\QueryBuilder($this); + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/ConnectionException.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/ConnectionException.php new file mode 100644 index 0000000..8c8f703 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/ConnectionException.php @@ -0,0 +1,54 @@ +. + */ + +namespace Doctrine\DBAL; + +/** + * Doctrine\DBAL\ConnectionException + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 4628 $ + * @author Jonathan H. Wage . + */ + +namespace Doctrine\DBAL\Connections; + + +use Doctrine\DBAL\Connection, + Doctrine\DBAL\Driver, + Doctrine\DBAL\Configuration, + Doctrine\Common\EventManager, + Doctrine\DBAL\Event\ConnectionEventArgs, + Doctrine\DBAL\Events; + +/** + * Master-Slave Connection + * + * Connection can be used with master-slave setups. + * + * Important for the understanding of this connection should be how and when + * it picks the slave or master. + * + * 1. Slave if master was never picked before and ONLY if 'getWrappedConnection' + * or 'executeQuery' is used. + * 2. Master picked when 'exec', 'executeUpdate', 'insert', 'delete', 'update', 'createSavepoint', + * 'releaseSavepoint', 'beginTransaction', 'rollback', 'commit', 'query' or + * 'prepare' is called. + * 3. If master was picked once during the lifetime of the connection it will always get picked afterwards. + * 4. One slave connection is randomly picked ONCE during a request. + * + * ATTENTION: You can write to the slave with this connection if you execute a write query without + * opening up a transaction. For example: + * + * $conn = DriverManager::getConnection(...); + * $conn->executeQuery("DELETE FROM table"); + * + * Be aware that Connection#executeQuery is a method specifically for READ + * operations only. + * + * This connection is limited to slave operations using the + * Connection#executeQuery operation only, because it wouldn't be compatible + * with the ORM or SchemaManager code otherwise. Both use all the other + * operations in a context where writes could happen to a slave, which makes + * this restricted approach necessary. + * + * You can manually connect to the master at any time by calling: + * + * $conn->connect('master'); + * + * Instantiation through the DriverManager looks like: + * + * @example + * + * $conn = DriverManager::getConnection(array( + * 'wrapperClass' => 'Doctrine\DBAL\Connections\MasterSlaveConnection', + * 'driver' => 'pdo_mysql', + * 'master' => array('user' => '', 'password' => '', 'host' => '', 'dbname' => ''), + * 'slaves' => array( + * array('user' => 'slave1', 'password', 'host' => '', 'dbname' => ''), + * array('user' => 'slave2', 'password', 'host' => '', 'dbname' => ''), + * ) + * )); + * + * You can also pass 'driverOptions' and any other documented option to each of this drivers to pass additional information. + * + * @author Lars Strojny + * @author Benjamin Eberlei + */ +class MasterSlaveConnection extends Connection +{ + /** + * Master and slave connection (one of the randomly picked slaves) + * + * @var Doctrine\DBAL\Driver\Connection[] + */ + protected $connections = array('master' => null, 'slave' => null); + + /** + * Create Master Slave Connection + * + * @param array $params + * @param Driver $driver + * @param Configuration $config + * @param EventManager $eventManager + */ + public function __construct(array $params, Driver $driver, Configuration $config = null, EventManager $eventManager = null) + { + if ( !isset($params['slaves']) || !isset($params['master']) ) { + throw new \InvalidArgumentException('master or slaves configuration missing'); + } + if ( count($params['slaves']) == 0 ) { + throw new \InvalidArgumentException('You have to configure at least one slaves.'); + } + + $params['master']['driver'] = $params['driver']; + foreach ($params['slaves'] as $slaveKey => $slave) { + $params['slaves'][$slaveKey]['driver'] = $params['driver']; + } + + parent::__construct($params, $driver, $config, $eventManager); + } + + /** + * Check if the connection is currently towards the master or not. + * + * @return bool + */ + public function isConnectedToMaster() + { + return $this->_conn !== null && $this->_conn === $this->connections['master']; + } + + /** + * {@inheritDoc} + */ + public function connect($connectionName = 'slave') + { + if ( $connectionName !== 'slave' && $connectionName !== 'master' ) { + throw new \InvalidArgumentException("Invalid option to connect(), only master or slave allowed."); + } + + $forceMasterAsSlave = false; + + if ($this->getTransactionNestingLevel() > 0) { + $connectionName = 'master'; + $forceMasterAsSlave = true; + } + + if ($this->connections[$connectionName]) { + if ($forceMasterAsSlave) { + $this->connections['slave'] = $this->_conn = $this->connections['master']; + } else { + $this->_conn = $this->connections[$connectionName]; + } + return false; + } + + if ($connectionName === 'master') { + /** Set slave connection to master to avoid invalid reads */ + if ($this->connections['slave']) { + unset($this->connections['slave']); + } + + $this->connections['master'] = $this->connections['slave'] = $this->_conn = $this->connectTo($connectionName); + } else { + $this->connections['slave'] = $this->_conn = $this->connectTo($connectionName); + } + + if ($this->_eventManager->hasListeners(Events::postConnect)) { + $eventArgs = new ConnectionEventArgs($this); + $this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs); + } + + return true; + } + + /** + * Connect to a specific connection + * + * @param string $connectionName + * @return Driver + */ + protected function connectTo($connectionName) + { + $params = $this->getParams(); + + $driverOptions = isset($params['driverOptions']) ? $params['driverOptions'] : array(); + + $connectionParams = $this->chooseConnectionConfiguration($connectionName, $params); + + $user = isset($connectionParams['user']) ? $connectionParams['user'] : null; + $password = isset($connectionParams['password']) ? $connectionParams['password'] : null; + + return $this->_driver->connect($connectionParams, $user, $password, $driverOptions); + } + + protected function chooseConnectionConfiguration($connectionName, $params) + { + if ($connectionName === 'master') { + return $params['master']; + } + + return $params['slaves'][array_rand($params['slaves'])]; + } + + /** + * {@inheritDoc} + */ + public function executeUpdate($query, array $params = array(), array $types = array()) + { + $this->connect('master'); + return parent::executeUpdate($query, $params, $types); + } + + /** + * {@inheritDoc} + */ + public function beginTransaction() + { + $this->connect('master'); + return parent::beginTransaction(); + } + + /** + * {@inheritDoc} + */ + public function commit() + { + $this->connect('master'); + return parent::commit(); + } + + /** + * {@inheritDoc} + */ + public function rollback() + { + $this->connect('master'); + return parent::rollback(); + } + + /** + * {@inheritDoc} + */ + public function delete($tableName, array $identifier) + { + $this->connect('master'); + return parent::delete($tableName, $identifier); + } + + /** + * {@inheritDoc} + */ + public function update($tableName, array $data, array $identifier, array $types = array()) + { + $this->connect('master'); + return parent::update($tableName, $data, $identifier, $types); + } + + /** + * {@inheritDoc} + */ + public function insert($tableName, array $data, array $types = array()) + { + $this->connect('master'); + return parent::insert($tableName, $data, $types); + } + + /** + * {@inheritDoc} + */ + public function exec($statement) + { + $this->connect('master'); + return parent::exec($statement); + } + + /** + * {@inheritDoc} + */ + public function createSavepoint($savepoint) + { + $this->connect('master'); + + return parent::createSavepoint($savepoint); + } + + /** + * {@inheritDoc} + */ + public function releaseSavepoint($savepoint) + { + $this->connect('master'); + + return parent::releaseSavepoint($savepoint); + } + + /** + * {@inheritDoc} + */ + public function rollbackSavepoint($savepoint) + { + $this->connect('master'); + + return parent::rollbackSavepoint($savepoint); + } + + public function query() + { + $this->connect('master'); + + $args = func_get_args(); + + $logger = $this->getConfiguration()->getSQLLogger(); + if ($logger) { + $logger->startQuery($args[0]); + } + + $statement = call_user_func_array(array($this->_conn, 'query'), $args); + + if ($logger) { + $logger->stopQuery(); + } + + return $statement; + } + + public function prepare($statement) + { + $this->connect('master'); + + return parent::prepare($statement); + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php new file mode 100644 index 0000000..9222e7e --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php @@ -0,0 +1,88 @@ +. + */ + +namespace Doctrine\DBAL; + +/** + * Driver interface. + * Interface that all DBAL drivers must implement. + * + * @since 2.0 + */ +interface Driver +{ + /** + * Attempts to create a connection with the database. + * + * @param array $params All connection parameters passed by the user. + * @param string $username The username to use when connecting. + * @param string $password The password to use when connecting. + * @param array $driverOptions The driver options to use when connecting. + * @return Doctrine\DBAL\Driver\Connection The database connection. + */ + public function connect(array $params, $username = null, $password = null, array $driverOptions = array()); + + /** + * Gets the DatabasePlatform instance that provides all the metadata about + * the platform this driver connects to. + * + * @return Doctrine\DBAL\Platforms\AbstractPlatform The database platform. + */ + public function getDatabasePlatform(); + + /** + * Gets the SchemaManager that can be used to inspect and change the underlying + * database schema of the platform this driver connects to. + * + * @param Doctrine\DBAL\Connection $conn + * @return Doctrine\DBAL\SchemaManager + */ + public function getSchemaManager(Connection $conn); + + /** + * Gets the name of the driver. + * + * @return string The name of the driver. + */ + public function getName(); + + /** + * Get the name of the database connected to for this driver. + * + * @param Doctrine\DBAL\Connection $conn + * @return string $database + */ + public function getDatabase(Connection $conn); +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Connection.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Connection.php new file mode 100644 index 0000000..c3f0d56 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Connection.php @@ -0,0 +1,42 @@ +. + */ + +namespace Doctrine\DBAL\Driver; + +/** + * Connection interface. + * Driver connections must implement this interface. + * + * This resembles (a subset of) the PDO interface. + * + * @since 2.0 + */ +interface Connection +{ + function prepare($prepareString); + function query(); + function quote($input, $type=\PDO::PARAM_STR); + function exec($statement); + function lastInsertId($name = null); + function beginTransaction(); + function commit(); + function rollBack(); + function errorCode(); + function errorInfo(); +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php new file mode 100644 index 0000000..c9d2fef --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php @@ -0,0 +1,115 @@ +. +*/ + +namespace Doctrine\DBAL\Driver\IBMDB2; + +class DB2Connection implements \Doctrine\DBAL\Driver\Connection +{ + private $_conn = null; + + public function __construct(array $params, $username, $password, $driverOptions = array()) + { + $isPersistant = (isset($params['persistent']) && $params['persistent'] == true); + + if ($isPersistant) { + $this->_conn = db2_pconnect($params['dbname'], $username, $password, $driverOptions); + } else { + $this->_conn = db2_connect($params['dbname'], $username, $password, $driverOptions); + } + if (!$this->_conn) { + throw new DB2Exception(db2_conn_errormsg()); + } + } + + public function prepare($sql) + { + $stmt = @db2_prepare($this->_conn, $sql); + if (!$stmt) { + throw new DB2Exception(db2_stmt_errormsg()); + } + return new DB2Statement($stmt); + } + + public function query() + { + $args = func_get_args(); + $sql = $args[0]; + $stmt = $this->prepare($sql); + $stmt->execute(); + return $stmt; + } + + public function quote($input, $type=\PDO::PARAM_STR) + { + $input = db2_escape_string($input); + if ($type == \PDO::PARAM_INT ) { + return $input; + } else { + return "'".$input."'"; + } + } + + public function exec($statement) + { + $stmt = $this->prepare($statement); + $stmt->execute(); + return $stmt->rowCount(); + } + + public function lastInsertId($name = null) + { + return db2_last_insert_id($this->_conn); + } + + public function beginTransaction() + { + db2_autocommit($this->_conn, DB2_AUTOCOMMIT_OFF); + } + + public function commit() + { + if (!db2_commit($this->_conn)) { + throw new DB2Exception(db2_conn_errormsg($this->_conn)); + } + db2_autocommit($this->_conn, DB2_AUTOCOMMIT_ON); + } + + public function rollBack() + { + if (!db2_rollback($this->_conn)) { + throw new DB2Exception(db2_conn_errormsg($this->_conn)); + } + db2_autocommit($this->_conn, DB2_AUTOCOMMIT_ON); + } + + public function errorCode() + { + return db2_conn_error($this->_conn); + } + + public function errorInfo() + { + return array( + 0 => db2_conn_errormsg($this->_conn), + 1 => $this->errorCode(), + ); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php new file mode 100644 index 0000000..d574b68 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php @@ -0,0 +1,111 @@ +. +*/ + +namespace Doctrine\DBAL\Driver\IBMDB2; + +use Doctrine\DBAL\Driver, + Doctrine\DBAL\Connection; + +/** + * IBM DB2 Driver + * + * @since 2.0 + * @author Benjamin Eberlei + */ +class DB2Driver implements Driver +{ + /** + * Attempts to create a connection with the database. + * + * @param array $params All connection parameters passed by the user. + * @param string $username The username to use when connecting. + * @param string $password The password to use when connecting. + * @param array $driverOptions The driver options to use when connecting. + * @return Doctrine\DBAL\Driver\Connection The database connection. + */ + public function connect(array $params, $username = null, $password = null, array $driverOptions = array()) + { + if ( ! isset($params['protocol'])) { + $params['protocol'] = 'TCPIP'; + } + + if ($params['host'] !== 'localhost' && $params['host'] != '127.0.0.1') { + // if the host isn't localhost, use extended connection params + $params['dbname'] = 'DRIVER={IBM DB2 ODBC DRIVER}' . + ';DATABASE=' . $params['dbname'] . + ';HOSTNAME=' . $params['host'] . + ';PROTOCOL=' . $params['protocol'] . + ';UID=' . $username . + ';PWD=' . $password .';'; + if (isset($params['port'])) { + $params['dbname'] .= 'PORT=' . $params['port']; + } + + $username = null; + $password = null; + } + + return new DB2Connection($params, $username, $password, $driverOptions); + } + + /** + * Gets the DatabasePlatform instance that provides all the metadata about + * the platform this driver connects to. + * + * @return Doctrine\DBAL\Platforms\AbstractPlatform The database platform. + */ + public function getDatabasePlatform() + { + return new \Doctrine\DBAL\Platforms\DB2Platform; + } + + /** + * Gets the SchemaManager that can be used to inspect and change the underlying + * database schema of the platform this driver connects to. + * + * @param Doctrine\DBAL\Connection $conn + * @return Doctrine\DBAL\SchemaManager + */ + public function getSchemaManager(Connection $conn) + { + return new \Doctrine\DBAL\Schema\DB2SchemaManager($conn); + } + + /** + * Gets the name of the driver. + * + * @return string The name of the driver. + */ + public function getName() + { + return 'ibm_db2'; + } + + /** + * Get the name of the database connected to for this driver. + * + * @param Doctrine\DBAL\Connection $conn + * @return string $database + */ + public function getDatabase(\Doctrine\DBAL\Connection $conn) + { + $params = $conn->getParams(); + return $params['dbname']; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Exception.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Exception.php new file mode 100644 index 0000000..7a6cc41 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Exception.php @@ -0,0 +1,27 @@ +. +*/ + +namespace Doctrine\DBAL\Driver\IBMDB2; + +class DB2Exception extends \Exception +{ + +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Statement.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Statement.php new file mode 100644 index 0000000..27da2ee --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Statement.php @@ -0,0 +1,215 @@ +. +*/ + +namespace Doctrine\DBAL\Driver\IBMDB2; + +use \Doctrine\DBAL\Driver\Statement; + +class DB2Statement implements \IteratorAggregate, Statement +{ + private $_stmt = null; + + private $_bindParam = array(); + + private $_defaultFetchStyle = \PDO::FETCH_BOTH; + + /** + * DB2_BINARY, DB2_CHAR, DB2_DOUBLE, or DB2_LONG + * @var array + */ + static private $_typeMap = array( + \PDO::PARAM_INT => DB2_LONG, + \PDO::PARAM_STR => DB2_CHAR, + ); + + public function __construct($stmt) + { + $this->_stmt = $stmt; + } + + /** + * {@inheritdoc} + */ + public function bindValue($param, $value, $type = null) + { + return $this->bindParam($param, $value, $type); + } + + /** + * {@inheritdoc} + */ + public function bindParam($column, &$variable, $type = null) + { + $this->_bindParam[$column] =& $variable; + + if ($type && isset(self::$_typeMap[$type])) { + $type = self::$_typeMap[$type]; + } else { + $type = DB2_CHAR; + } + + if (!db2_bind_param($this->_stmt, $column, "variable", DB2_PARAM_IN, $type)) { + throw new DB2Exception(db2_stmt_errormsg()); + } + return true; + } + + /** + * {@inheritdoc} + */ + public function closeCursor() + { + if (!$this->_stmt) { + return false; + } + + $this->_bindParam = array(); + db2_free_result($this->_stmt); + $ret = db2_free_stmt($this->_stmt); + $this->_stmt = false; + return $ret; + } + + /** + * {@inheritdoc} + */ + public function columnCount() + { + if (!$this->_stmt) { + return false; + } + return db2_num_fields($this->_stmt); + } + + /** + * {@inheritdoc} + */ + public function errorCode() + { + return db2_stmt_error(); + } + + /** + * {@inheritdoc} + */ + public function errorInfo() + { + return array( + 0 => db2_stmt_errormsg(), + 1 => db2_stmt_error(), + ); + } + + /** + * {@inheritdoc} + */ + public function execute($params = null) + { + if (!$this->_stmt) { + return false; + } + + /*$retval = true; + if ($params !== null) { + $retval = @db2_execute($this->_stmt, $params); + } else { + $retval = @db2_execute($this->_stmt); + }*/ + if ($params === null) { + ksort($this->_bindParam); + $params = array_values($this->_bindParam); + } + $retval = @db2_execute($this->_stmt, $params); + + if ($retval === false) { + throw new DB2Exception(db2_stmt_errormsg()); + } + return $retval; + } + + /** + * {@inheritdoc} + */ + public function setFetchMode($fetchStyle = \PDO::FETCH_BOTH, $arg2 = null, $arg3 = null) + { + $this->_defaultFetchStyle = $fetchStyle; + } + + /** + * {@inheritdoc} + */ + public function getIterator() + { + $data = $this->fetchAll($this->_defaultFetchStyle); + return new \ArrayIterator($data); + } + + /** + * {@inheritdoc} + */ + public function fetch($fetchStyle = null) + { + $fetchStyle = $fetchStyle ?: $this->_defaultFetchStyle; + switch ($fetchStyle) { + case \PDO::FETCH_BOTH: + return db2_fetch_both($this->_stmt); + case \PDO::FETCH_ASSOC: + return db2_fetch_assoc($this->_stmt); + case \PDO::FETCH_NUM: + return db2_fetch_array($this->_stmt); + default: + throw new DB2Exception("Given Fetch-Style " . $fetchStyle . " is not supported."); + } + } + + /** + * {@inheritdoc} + */ + public function fetchAll($fetchStyle = null) + { + $fetchStyle = $fetchStyle ?: $this->_defaultFetchStyle; + $rows = array(); + while ($row = $this->fetch($fetchStyle)) { + $rows[] = $row; + } + return $rows; + } + + /** + * {@inheritdoc} + */ + public function fetchColumn($columnIndex = 0) + { + $row = $this->fetch(\PDO::FETCH_NUM); + if ($row && isset($row[$columnIndex])) { + return $row[$columnIndex]; + } + return false; + } + + /** + * {@inheritdoc} + */ + public function rowCount() + { + return (@db2_num_rows($this->_stmt))?:0; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php new file mode 100644 index 0000000..b77de67 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php @@ -0,0 +1,69 @@ +. + */ + +namespace Doctrine\DBAL\Driver\Mysqli; + +use Doctrine\DBAL\Driver as DriverInterface; + +/** + * @author Kim Hemsø Rasmussen + */ +class Driver implements DriverInterface +{ + /** + * {@inheritdoc} + */ + public function connect(array $params, $username = null, $password = null, array $driverOptions = array()) + { + return new MysqliConnection($params, $username, $password, $driverOptions); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'mysqli'; + } + + /** + * {@inheritdoc} + */ + public function getSchemaManager(\Doctrine\DBAL\Connection $conn) + { + return new \Doctrine\DBAL\Schema\MySqlSchemaManager($conn); + } + + /** + * {@inheritdoc} + */ + public function getDatabasePlatform() + { + return new \Doctrine\DBAL\Platforms\MySqlPlatform(); + } + + /** + * {@inheritdoc} + */ + public function getDatabase(\Doctrine\DBAL\Connection $conn) + { + $params = $conn->getParams(); + return $params['dbname']; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php new file mode 100644 index 0000000..b69535b --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php @@ -0,0 +1,146 @@ +. + */ + +namespace Doctrine\DBAL\Driver\Mysqli; + +use Doctrine\DBAL\Driver\Connection as Connection; + +/** + * @author Kim Hemsø Rasmussen + */ +class MysqliConnection implements Connection +{ + /** + * @var \mysqli + */ + private $_conn; + + public function __construct(array $params, $username, $password, array $driverOptions = array()) + { + $port = isset($params['port']) ? $params['port'] : ini_get('mysqli.default_port'); + $socket = isset($params['unix_socket']) ? $params['unix_socket'] : ini_get('mysqli.default_socket'); + + $this->_conn = mysqli_init(); + if (!$this->_conn->real_connect($params['host'], $username, $password, $params['dbname'], $port, $socket)) { + throw new MysqliException($this->_conn->connect_error, $this->_conn->connect_errno); + } + + if (isset($params['charset'])) { + $this->_conn->set_charset($params['charset']); + } + } + + /** + * Retrieve mysqli native resource handle. + * + * Could be used if part of your application is not using DBAL + * + * @return mysqli + */ + public function getWrappedResourceHandle() + { + return $this->_conn; + } + + /** + * {@inheritdoc} + */ + public function prepare($prepareString) + { + return new MysqliStatement($this->_conn, $prepareString); + } + + /** + * {@inheritdoc} + */ + public function query() + { + $args = func_get_args(); + $sql = $args[0]; + $stmt = $this->prepare($sql); + $stmt->execute(); + return $stmt; + } + + /** + * {@inheritdoc} + */ + public function quote($input, $type=\PDO::PARAM_STR) + { + return "'". $this->_conn->escape_string($input) ."'"; + } + + /** + * {@inheritdoc} + */ + public function exec($statement) + { + $this->_conn->query($statement); + return $this->_conn->affected_rows; + } + + /** + * {@inheritdoc} + */ + public function lastInsertId($name = null) + { + return $this->_conn->insert_id; + } + + /** + * {@inheritdoc} + */ + public function beginTransaction() + { + $this->_conn->query('START TRANSACTION'); + return true; + } + + /** + * {@inheritdoc} + */ + public function commit() + { + return $this->_conn->commit(); + } + + /** + * {@inheritdoc}non-PHPdoc) + */ + public function rollBack() + { + return $this->_conn->rollback(); + } + + /** + * {@inheritdoc} + */ + public function errorCode() + { + return $this->_conn->errno; + } + + /** + * {@inheritdoc} + */ + public function errorInfo() + { + return $this->_conn->error; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliException.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliException.php new file mode 100644 index 0000000..e59a803 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliException.php @@ -0,0 +1,26 @@ +. +*/ + +namespace Doctrine\DBAL\Driver\Mysqli; + +/** + * @author Kim Hemsø Rasmussen + */ +class MysqliException extends \Exception +{} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php new file mode 100644 index 0000000..d7f9703 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php @@ -0,0 +1,335 @@ +. + */ + +namespace Doctrine\DBAL\Driver\Mysqli; + +use Doctrine\DBAL\Driver\Statement; +use PDO; + +/** + * @author Kim Hemsø Rasmussen + */ +class MysqliStatement implements \IteratorAggregate, Statement +{ + protected static $_paramTypeMap = array( + PDO::PARAM_STR => 's', + PDO::PARAM_BOOL => 'i', + PDO::PARAM_NULL => 's', + PDO::PARAM_INT => 'i', + PDO::PARAM_LOB => 's' // TODO Support LOB bigger then max package size. + ); + + protected $_conn; + protected $_stmt; + + /** + * @var null|false|array + */ + protected $_columnNames; + + /** + * @var null|array + */ + protected $_rowBindedValues; + + /** + * @var array + */ + protected $_bindedValues; + + /** + * Contains ref values for bindValue() + * + * @var array + */ + protected $_values = array(); + + protected $_defaultFetchStyle = PDO::FETCH_BOTH; + + public function __construct(\mysqli $conn, $prepareString) + { + $this->_conn = $conn; + $this->_stmt = $conn->prepare($prepareString); + if (false === $this->_stmt) { + throw new MysqliException($this->_conn->error, $this->_conn->errno); + } + + $paramCount = $this->_stmt->param_count; + if (0 < $paramCount) { + // Index 0 is types + // Need to init the string else php think we are trying to access it as a array. + $bindedValues = array(0 => str_repeat('s', $paramCount)); + $null = null; + for ($i = 1; $i < $paramCount; $i++) { + $bindedValues[] =& $null; + } + $this->_bindedValues = $bindedValues; + } + } + + /** + * {@inheritdoc} + */ + public function bindParam($column, &$variable, $type = null) + { + if (null === $type) { + $type = 's'; + } else { + if (isset(self::$_paramTypeMap[$type])) { + $type = self::$_paramTypeMap[$type]; + } else { + throw new MysqliException("Unkown type: '{$type}'"); + } + } + + $this->_bindedValues[$column] =& $variable; + $this->_bindedValues[0][$column - 1] = 's'; + return true; + } + + /** + * {@inheritdoc} + */ + public function bindValue($param, $value, $type = null) + { + if (null === $type) { + $type = 's'; + } else { + if (isset(self::$_paramTypeMap[$type])) { + $type = self::$_paramTypeMap[$type]; + } else { + throw new MysqliException("Unknown type: '{$type}'"); + } + } + + $this->_values[$param] = $value; + $this->_bindedValues[$param] =& $this->_values[$param]; + $this->_bindedValues[0][$param - 1] = 's'; + return true; + } + + /** + * {@inheritdoc} + */ + public function execute($params = null) + { + if (null !== $this->_bindedValues) { + if (null !== $params) { + if (!$this->_bindValues($params)) { + throw new MysqliException($this->_stmt->error, $this->_stmt->errno); + } + } else { + if (!call_user_func_array(array($this->_stmt, 'bind_param'), $this->_bindedValues)) { + throw new MysqliException($this->_stmt->error, $this->_stmt->errno); + } + } + } + + if (!$this->_stmt->execute()) { + throw new MysqliException($this->_stmt->error, $this->_stmt->errno); + } + + if (null === $this->_columnNames) { + $meta = $this->_stmt->result_metadata(); + if (false !== $meta) { + $columnNames = array(); + foreach ($meta->fetch_fields() as $col) { + $columnNames[] = $col->name; + } + $meta->free(); + + $this->_columnNames = $columnNames; + $this->_rowBindedValues = array_fill(0, count($columnNames), NULL); + + $refs = array(); + foreach ($this->_rowBindedValues as $key => &$value) { + $refs[$key] =& $value; + } + + if (!call_user_func_array(array($this->_stmt, 'bind_result'), $refs)) { + throw new MysqliException($this->_stmt->error, $this->_stmt->errno); + } + } else { + $this->_columnNames = false; + } + } + + // We have a result. + if (false !== $this->_columnNames) { + $this->_stmt->store_result(); + } + return true; + } + + /** + * Bind a array of values to bound parameters + * + * @param array $values + * @return boolean + */ + private function _bindValues($values) + { + $params = array(); + $types = str_repeat('s', count($values)); + $params[0] = $types; + + foreach ($values as &$v) { + $params[] =& $v; + } + return call_user_func_array(array($this->_stmt, 'bind_param'), $params); + } + + /** + * @return null|false|array + */ + private function _fetch() + { + $ret = $this->_stmt->fetch(); + + if (true === $ret) { + $values = array(); + foreach ($this->_rowBindedValues as $v) { + // Mysqli converts them to a scalar type it can fit in. + $values[] = null === $v ? null : (string)$v; + } + return $values; + } + return $ret; + } + + /** + * {@inheritdoc} + */ + public function fetch($fetchStyle = null) + { + $values = $this->_fetch(); + if (null === $values) { + return null; + } + + if (false === $values) { + throw new MysqliException($this->_stmt->error, $this->_stmt->errno); + } + + $fetchStyle = $fetchStyle ?: $this->_defaultFetchStyle; + + switch ($fetchStyle) { + case PDO::FETCH_NUM: + return $values; + + case PDO::FETCH_ASSOC: + return array_combine($this->_columnNames, $values); + + case PDO::FETCH_BOTH: + $ret = array_combine($this->_columnNames, $values); + $ret += $values; + return $ret; + + default: + throw new MysqliException("Unknown fetch type '{$fetchStyle}'"); + } + } + + /** + * {@inheritdoc} + */ + public function fetchAll($fetchStyle = null) + { + $fetchStyle = $fetchStyle ?: $this->_defaultFetchStyle; + + $a = array(); + while (($row = $this->fetch($fetchStyle)) !== null) { + $a[] = $row; + } + return $a; + } + + /** + * {@inheritdoc} + */ + public function fetchColumn($columnIndex = 0) + { + $row = $this->fetch(PDO::FETCH_NUM); + if (null === $row) { + return false; + } + return $row[$columnIndex]; + } + + /** + * {@inheritdoc} + */ + public function errorCode() + { + return $this->_stmt->errno; + } + + /** + * {@inheritdoc} + */ + public function errorInfo() + { + return $this->_stmt->error; + } + + /** + * {@inheritdoc} + */ + public function closeCursor() + { + $this->_stmt->free_result(); + return true; + } + + /** + * {@inheritdoc} + */ + public function rowCount() + { + if (false === $this->_columnNames) { + return $this->_stmt->affected_rows; + } + return $this->_stmt->num_rows; + } + + /** + * {@inheritdoc} + */ + public function columnCount() + { + return $this->_stmt->field_count; + } + + /** + * {@inheritdoc} + */ + public function setFetchMode($fetchMode = PDO::FETCH_BOTH, $arg2 = null, $arg3 = null) + { + $this->_defaultFetchStyle = $fetchMode; + } + + /** + * {@inheritdoc} + */ + public function getIterator() + { + $data = $this->fetchAll($this->_defaultFetchStyle); + return new \ArrayIterator($data); + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Driver.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Driver.php new file mode 100644 index 0000000..650ad9b --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Driver.php @@ -0,0 +1,95 @@ +. + */ + +namespace Doctrine\DBAL\Driver\OCI8; + +use Doctrine\DBAL\Platforms; + +/** + * A Doctrine DBAL driver for the Oracle OCI8 PHP extensions. + * + * @author Roman Borschel + * @since 2.0 + */ +class Driver implements \Doctrine\DBAL\Driver +{ + public function connect(array $params, $username = null, $password = null, array $driverOptions = array()) + { + return new OCI8Connection( + $username, + $password, + $this->_constructDsn($params), + isset($params['charset']) ? $params['charset'] : null, + isset($params['sessionMode']) ? $params['sessionMode'] : OCI_DEFAULT + ); + } + + /** + * Constructs the Oracle DSN. + * + * @return string The DSN. + */ + protected function _constructDsn(array $params) + { + $dsn = ''; + if (isset($params['host']) && $params['host'] != '') { + $dsn .= '(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)' . + '(HOST=' . $params['host'] . ')'; + + if (isset($params['port'])) { + $dsn .= '(PORT=' . $params['port'] . ')'; + } else { + $dsn .= '(PORT=1521)'; + } + + if (isset($params['service']) && $params['service'] == true) { + $dsn .= '))(CONNECT_DATA=(SERVICE_NAME=' . $params['dbname'] . ')))'; + } else { + $dsn .= '))(CONNECT_DATA=(SID=' . $params['dbname'] . ')))'; + } + } else { + $dsn .= $params['dbname']; + } + + return $dsn; + } + + public function getDatabasePlatform() + { + return new \Doctrine\DBAL\Platforms\OraclePlatform(); + } + + public function getSchemaManager(\Doctrine\DBAL\Connection $conn) + { + return new \Doctrine\DBAL\Schema\OracleSchemaManager($conn); + } + + public function getName() + { + return 'oci8'; + } + + public function getDatabase(\Doctrine\DBAL\Connection $conn) + { + $params = $conn->getParams(); + return $params['user']; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php new file mode 100644 index 0000000..f00ffaf --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php @@ -0,0 +1,172 @@ +. + */ + +namespace Doctrine\DBAL\Driver\OCI8; + +/** + * OCI8 implementation of the Connection interface. + * + * @since 2.0 + */ +class OCI8Connection implements \Doctrine\DBAL\Driver\Connection +{ + protected $_dbh; + + protected $_executeMode = OCI_COMMIT_ON_SUCCESS; + + /** + * Create a Connection to an Oracle Database using oci8 extension. + * + * @param string $username + * @param string $password + * @param string $db + */ + public function __construct($username, $password, $db, $charset = null, $sessionMode = OCI_DEFAULT) + { + if (!defined('OCI_NO_AUTO_COMMIT')) { + define('OCI_NO_AUTO_COMMIT', 0); + } + + $this->_dbh = @oci_connect($username, $password, $db, $charset, $sessionMode); + if (!$this->_dbh) { + throw OCI8Exception::fromErrorInfo(oci_error()); + } + } + + /** + * Create a non-executed prepared statement. + * + * @param string $prepareString + * @return OCI8Statement + */ + public function prepare($prepareString) + { + return new OCI8Statement($this->_dbh, $prepareString, $this); + } + + /** + * @param string $sql + * @return OCI8Statement + */ + public function query() + { + $args = func_get_args(); + $sql = $args[0]; + //$fetchMode = $args[1]; + $stmt = $this->prepare($sql); + $stmt->execute(); + return $stmt; + } + + /** + * Quote input value. + * + * @param mixed $input + * @param int $type PDO::PARAM* + * @return mixed + */ + public function quote($value, $type=\PDO::PARAM_STR) + { + if (is_int($value) || is_float($value)) { + return $value; + } + $value = str_replace("'", "''", $value); + return "'" . addcslashes($value, "\000\n\r\\\032") . "'"; + } + + /** + * + * @param string $statement + * @return int + */ + public function exec($statement) + { + $stmt = $this->prepare($statement); + $stmt->execute(); + return $stmt->rowCount(); + } + + public function lastInsertId($name = null) + { + //TODO: throw exception or support sequences? + } + + /** + * Return the current execution mode. + */ + public function getExecuteMode() + { + return $this->_executeMode; + } + + /** + * Start a transactiom + * + * Oracle has to explicitly set the autocommit mode off. That means + * after connection, a commit or rollback there is always automatically + * opened a new transaction. + * + * @return bool + */ + public function beginTransaction() + { + $this->_executeMode = OCI_NO_AUTO_COMMIT; + return true; + } + + /** + * @throws OCI8Exception + * @return bool + */ + public function commit() + { + if (!oci_commit($this->_dbh)) { + throw OCI8Exception::fromErrorInfo($this->errorInfo()); + } + $this->_executeMode = OCI_COMMIT_ON_SUCCESS; + return true; + } + + /** + * @throws OCI8Exception + * @return bool + */ + public function rollBack() + { + if (!oci_rollback($this->_dbh)) { + throw OCI8Exception::fromErrorInfo($this->errorInfo()); + } + $this->_executeMode = OCI_COMMIT_ON_SUCCESS; + return true; + } + + public function errorCode() + { + $error = oci_error($this->_dbh); + if ($error !== false) { + $error = $error['code']; + } + return $error; + } + + public function errorInfo() + { + return oci_error($this->_dbh); + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Exception.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Exception.php new file mode 100644 index 0000000..66fe615 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Exception.php @@ -0,0 +1,30 @@ +. +*/ + +namespace Doctrine\DBAL\Driver\OCI8; + +class OCI8Exception extends \Exception +{ + static public function fromErrorInfo($error) + { + return new self($error['message'], $error['code']); + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Statement.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Statement.php new file mode 100644 index 0000000..677b684 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Statement.php @@ -0,0 +1,258 @@ +. + */ + +namespace Doctrine\DBAL\Driver\OCI8; + +use PDO; +use IteratorAggregate; +use Doctrine\DBAL\Driver\Statement; + +/** + * The OCI8 implementation of the Statement interface. + * + * @since 2.0 + * @author Roman Borschel + */ +class OCI8Statement implements \IteratorAggregate, Statement +{ + /** Statement handle. */ + protected $_dbh; + protected $_sth; + protected $_conn; + protected static $_PARAM = ':param'; + protected static $fetchStyleMap = array( + PDO::FETCH_BOTH => OCI_BOTH, + PDO::FETCH_ASSOC => OCI_ASSOC, + PDO::FETCH_NUM => OCI_NUM, + PDO::PARAM_LOB => OCI_B_BLOB, + ); + protected $_defaultFetchStyle = PDO::FETCH_BOTH; + protected $_paramMap = array(); + + /** + * Creates a new OCI8Statement that uses the given connection handle and SQL statement. + * + * @param resource $dbh The connection handle. + * @param string $statement The SQL statement. + */ + public function __construct($dbh, $statement, OCI8Connection $conn) + { + list($statement, $paramMap) = self::convertPositionalToNamedPlaceholders($statement); + $this->_sth = oci_parse($dbh, $statement); + $this->_dbh = $dbh; + $this->_paramMap = $paramMap; + $this->_conn = $conn; + } + + /** + * Convert positional (?) into named placeholders (:param) + * + * Oracle does not support positional parameters, hence this method converts all + * positional parameters into artificially named parameters. Note that this conversion + * is not perfect. All question marks (?) in the original statement are treated as + * placeholders and converted to a named parameter. + * + * The algorithm uses a state machine with two possible states: InLiteral and NotInLiteral. + * Question marks inside literal strings are therefore handled correctly by this method. + * This comes at a cost, the whole sql statement has to be looped over. + * + * @todo extract into utility class in Doctrine\DBAL\Util namespace + * @todo review and test for lost spaces. we experienced missing spaces with oci8 in some sql statements. + * @param string $statement The SQL statement to convert. + * @return string + */ + static public function convertPositionalToNamedPlaceholders($statement) + { + $count = 1; + $inLiteral = false; // a valid query never starts with quotes + $stmtLen = strlen($statement); + $paramMap = array(); + for ($i = 0; $i < $stmtLen; $i++) { + if ($statement[$i] == '?' && !$inLiteral) { + // real positional parameter detected + $paramMap[$count] = ":param$count"; + $len = strlen($paramMap[$count]); + $statement = substr_replace($statement, ":param$count", $i, 1); + $i += $len-1; // jump ahead + $stmtLen = strlen($statement); // adjust statement length + ++$count; + } else if ($statement[$i] == "'" || $statement[$i] == '"') { + $inLiteral = ! $inLiteral; // switch state! + } + } + + return array($statement, $paramMap); + } + + /** + * {@inheritdoc} + */ + public function bindValue($param, $value, $type = null) + { + return $this->bindParam($param, $value, $type); + } + + /** + * {@inheritdoc} + */ + public function bindParam($column, &$variable, $type = null) + { + $column = isset($this->_paramMap[$column]) ? $this->_paramMap[$column] : $column; + + if ($type == \PDO::PARAM_LOB) { + $lob = oci_new_descriptor($this->_dbh, OCI_D_LOB); + $lob->writeTemporary($variable, OCI_TEMP_BLOB); + + return oci_bind_by_name($this->_sth, $column, $lob, -1, OCI_B_BLOB); + } else { + return oci_bind_by_name($this->_sth, $column, $variable); + } + } + + /** + * Closes the cursor, enabling the statement to be executed again. + * + * @return boolean Returns TRUE on success or FALSE on failure. + */ + public function closeCursor() + { + return oci_free_statement($this->_sth); + } + + /** + * {@inheritdoc} + */ + public function columnCount() + { + return oci_num_fields($this->_sth); + } + + /** + * {@inheritdoc} + */ + public function errorCode() + { + $error = oci_error($this->_sth); + if ($error !== false) { + $error = $error['code']; + } + return $error; + } + + /** + * {@inheritdoc} + */ + public function errorInfo() + { + return oci_error($this->_sth); + } + + /** + * {@inheritdoc} + */ + public function execute($params = null) + { + if ($params) { + $hasZeroIndex = array_key_exists(0, $params); + foreach ($params as $key => $val) { + if ($hasZeroIndex && is_numeric($key)) { + $this->bindValue($key + 1, $val); + } else { + $this->bindValue($key, $val); + } + } + } + + $ret = @oci_execute($this->_sth, $this->_conn->getExecuteMode()); + if ( ! $ret) { + throw OCI8Exception::fromErrorInfo($this->errorInfo()); + } + return $ret; + } + + /** + * {@inheritdoc} + */ + public function setFetchMode($fetchStyle = PDO::FETCH_BOTH, $arg2 = null, $arg3 = null) + { + $this->_defaultFetchStyle = $fetchStyle; + } + + /** + * {@inheritdoc} + */ + public function getIterator() + { + $data = $this->fetchAll($this->_defaultFetchStyle); + return new \ArrayIterator($data); + } + + /** + * {@inheritdoc} + */ + public function fetch($fetchStyle = null) + { + $fetchStyle = $fetchStyle ?: $this->_defaultFetchStyle; + if ( ! isset(self::$fetchStyleMap[$fetchStyle])) { + throw new \InvalidArgumentException("Invalid fetch style: " . $fetchStyle); + } + + return oci_fetch_array($this->_sth, self::$fetchStyleMap[$fetchStyle] | OCI_RETURN_NULLS | OCI_RETURN_LOBS); + } + + /** + * {@inheritdoc} + */ + public function fetchAll($fetchStyle = null) + { + $fetchStyle = $fetchStyle ?: $this->_defaultFetchStyle; + if ( ! isset(self::$fetchStyleMap[$fetchStyle])) { + throw new \InvalidArgumentException("Invalid fetch style: " . $fetchStyle); + } + + $result = array(); + if (self::$fetchStyleMap[$fetchStyle] === OCI_BOTH) { + while ($row = $this->fetch($fetchStyle)) { + $result[] = $row; + } + } else { + oci_fetch_all($this->_sth, $result, 0, -1, + self::$fetchStyleMap[$fetchStyle] | OCI_RETURN_NULLS | OCI_FETCHSTATEMENT_BY_ROW | OCI_RETURN_LOBS); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function fetchColumn($columnIndex = 0) + { + $row = oci_fetch_array($this->_sth, OCI_NUM | OCI_RETURN_NULLS | OCI_RETURN_LOBS); + return isset($row[$columnIndex]) ? $row[$columnIndex] : false; + } + + /** + * {@inheritdoc} + */ + public function rowCount() + { + return oci_num_rows($this->_sth); + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php new file mode 100644 index 0000000..f006807 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php @@ -0,0 +1,40 @@ +. + */ + +namespace Doctrine\DBAL\Driver; + +use \PDO; + +/** + * PDO implementation of the Connection interface. + * Used by all PDO-based drivers. + * + * @since 2.0 + */ +class PDOConnection extends PDO implements Connection +{ + public function __construct($dsn, $user = null, $password = null, array $options = null) + { + parent::__construct($dsn, $user, $password, $options); + $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('Doctrine\DBAL\Driver\PDOStatement', array())); + $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOIbm/Driver.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOIbm/Driver.php new file mode 100644 index 0000000..844f2ab --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOIbm/Driver.php @@ -0,0 +1,126 @@ +. +*/ + +namespace Doctrine\DBAL\Driver\PDOIbm; + +use Doctrine\DBAL\Connection; + +/** + * Driver for the PDO IBM extension + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 1.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class Driver implements \Doctrine\DBAL\Driver +{ + /** + * Attempts to establish a connection with the underlying driver. + * + * @param array $params + * @param string $username + * @param string $password + * @param array $driverOptions + * @return Doctrine\DBAL\Driver\Connection + */ + public function connect(array $params, $username = null, $password = null, array $driverOptions = array()) + { + $conn = new \Doctrine\DBAL\Driver\PDOConnection( + $this->_constructPdoDsn($params), + $username, + $password, + $driverOptions + ); + return $conn; + } + + /** + * Constructs the MySql PDO DSN. + * + * @return string The DSN. + */ + private function _constructPdoDsn(array $params) + { + $dsn = 'ibm:'; + if (isset($params['host'])) { + $dsn .= 'HOSTNAME=' . $params['host'] . ';'; + } + if (isset($params['port'])) { + $dsn .= 'PORT=' . $params['port'] . ';'; + } + $dsn .= 'PROTOCOL=TCPIP;'; + if (isset($params['dbname'])) { + $dsn .= 'DATABASE=' . $params['dbname'] . ';'; + } + + return $dsn; + } + + /** + * Gets the DatabasePlatform instance that provides all the metadata about + * the platform this driver connects to. + * + * @return Doctrine\DBAL\Platforms\AbstractPlatform The database platform. + */ + public function getDatabasePlatform() + { + return new \Doctrine\DBAL\Platforms\DB2Platform; + } + + /** + * Gets the SchemaManager that can be used to inspect and change the underlying + * database schema of the platform this driver connects to. + * + * @param Doctrine\DBAL\Connection $conn + * @return Doctrine\DBAL\SchemaManager + */ + public function getSchemaManager(Connection $conn) + { + return new \Doctrine\DBAL\Schema\DB2SchemaManager($conn); + } + + /** + * Gets the name of the driver. + * + * @return string The name of the driver. + */ + public function getName() + { + return 'pdo_ibm'; + } + + /** + * Get the name of the database connected to for this driver. + * + * @param Doctrine\DBAL\Connection $conn + * @return string $database + */ + public function getDatabase(\Doctrine\DBAL\Connection $conn) + { + $params = $conn->getParams(); + return $params['dbname']; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php new file mode 100644 index 0000000..cb2df85 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php @@ -0,0 +1,102 @@ +. + */ + +namespace Doctrine\DBAL\Driver\PDOMySql; + +use Doctrine\DBAL\Connection; + +/** + * PDO MySql driver. + * + * @since 2.0 + */ +class Driver implements \Doctrine\DBAL\Driver +{ + /** + * Attempts to establish a connection with the underlying driver. + * + * @param array $params + * @param string $username + * @param string $password + * @param array $driverOptions + * @return Doctrine\DBAL\Driver\Connection + */ + public function connect(array $params, $username = null, $password = null, array $driverOptions = array()) + { + $conn = new \Doctrine\DBAL\Driver\PDOConnection( + $this->_constructPdoDsn($params), + $username, + $password, + $driverOptions + ); + return $conn; + } + + /** + * Constructs the MySql PDO DSN. + * + * @return string The DSN. + */ + private function _constructPdoDsn(array $params) + { + $dsn = 'mysql:'; + if (isset($params['host']) && $params['host'] != '') { + $dsn .= 'host=' . $params['host'] . ';'; + } + if (isset($params['port'])) { + $dsn .= 'port=' . $params['port'] . ';'; + } + if (isset($params['dbname'])) { + $dsn .= 'dbname=' . $params['dbname'] . ';'; + } + if (isset($params['unix_socket'])) { + $dsn .= 'unix_socket=' . $params['unix_socket'] . ';'; + } + if (isset($params['charset'])) { + $dsn .= 'charset=' . $params['charset'] . ';'; + } + + return $dsn; + } + + public function getDatabasePlatform() + { + return new \Doctrine\DBAL\Platforms\MySqlPlatform(); + } + + public function getSchemaManager(\Doctrine\DBAL\Connection $conn) + { + return new \Doctrine\DBAL\Schema\MySqlSchemaManager($conn); + } + + public function getName() + { + return 'pdo_mysql'; + } + + public function getDatabase(\Doctrine\DBAL\Connection $conn) + { + $params = $conn->getParams(); + + if (isset($params['dbname'])) { + return $params['dbname']; + } + return $conn->query('SELECT DATABASE()')->fetchColumn(); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php new file mode 100644 index 0000000..1f007c1 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php @@ -0,0 +1,98 @@ +. + */ + +namespace Doctrine\DBAL\Driver\PDOOracle; + +use Doctrine\DBAL\Platforms; + +/** + * PDO Oracle driver + * + * WARNING: This driver gives us segfauls in our testsuites on CLOB and other + * stuff. PDO Oracle is not maintained by Oracle or anyone in the PHP community, + * which leads us to the recommendation to use the "oci8" driver to connect + * to Oracle instead. + */ +class Driver implements \Doctrine\DBAL\Driver +{ + public function connect(array $params, $username = null, $password = null, array $driverOptions = array()) + { + return new \Doctrine\DBAL\Driver\PDOConnection( + $this->_constructPdoDsn($params), + $username, + $password, + $driverOptions + ); + } + + /** + * Constructs the Oracle PDO DSN. + * + * @return string The DSN. + */ + private function _constructPdoDsn(array $params) + { + $dsn = 'oci:'; + if (isset($params['host'])) { + $dsn .= 'dbname=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)' . + '(HOST=' . $params['host'] . ')'; + + if (isset($params['port'])) { + $dsn .= '(PORT=' . $params['port'] . ')'; + } else { + $dsn .= '(PORT=1521)'; + } + + if (isset($params['service']) && $params['service'] == true) { + $dsn .= '))(CONNECT_DATA=(SERVICE_NAME=' . $params['dbname'] . ')))'; + } else { + $dsn .= '))(CONNECT_DATA=(SID=' . $params['dbname'] . ')))'; + } + } else { + $dsn .= 'dbname=' . $params['dbname']; + } + + if (isset($params['charset'])) { + $dsn .= ';charset=' . $params['charset']; + } + + return $dsn; + } + + public function getDatabasePlatform() + { + return new \Doctrine\DBAL\Platforms\OraclePlatform(); + } + + public function getSchemaManager(\Doctrine\DBAL\Connection $conn) + { + return new \Doctrine\DBAL\Schema\OracleSchemaManager($conn); + } + + public function getName() + { + return 'pdo_oracle'; + } + + public function getDatabase(\Doctrine\DBAL\Connection $conn) + { + $params = $conn->getParams(); + return $params['user']; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php new file mode 100644 index 0000000..247eb8f --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php @@ -0,0 +1,70 @@ +_constructPdoDsn($params), + $username, + $password, + $driverOptions + ); + } + + /** + * Constructs the Postgres PDO DSN. + * + * @return string The DSN. + */ + private function _constructPdoDsn(array $params) + { + $dsn = 'pgsql:'; + if (isset($params['host']) && $params['host'] != '') { + $dsn .= 'host=' . $params['host'] . ' '; + } + if (isset($params['port']) && $params['port'] != '') { + $dsn .= 'port=' . $params['port'] . ' '; + } + if (isset($params['dbname'])) { + $dsn .= 'dbname=' . $params['dbname'] . ' '; + } + + return $dsn; + } + + public function getDatabasePlatform() + { + return new \Doctrine\DBAL\Platforms\PostgreSqlPlatform(); + } + + public function getSchemaManager(\Doctrine\DBAL\Connection $conn) + { + return new \Doctrine\DBAL\Schema\PostgreSqlSchemaManager($conn); + } + + public function getName() + { + return 'pdo_pgsql'; + } + + public function getDatabase(\Doctrine\DBAL\Connection $conn) + { + $params = $conn->getParams(); + return $params['dbname']; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php new file mode 100644 index 0000000..e13526a --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php @@ -0,0 +1,116 @@ +. + */ + +namespace Doctrine\DBAL\Driver\PDOSqlite; + +/** + * The PDO Sqlite driver. + * + * @since 2.0 + */ +class Driver implements \Doctrine\DBAL\Driver +{ + /** + * @var array + */ + protected $_userDefinedFunctions = array( + 'sqrt' => array('callback' => array('Doctrine\DBAL\Platforms\SqlitePlatform', 'udfSqrt'), 'numArgs' => 1), + 'mod' => array('callback' => array('Doctrine\DBAL\Platforms\SqlitePlatform', 'udfMod'), 'numArgs' => 2), + 'locate' => array('callback' => array('Doctrine\DBAL\Platforms\SqlitePlatform', 'udfLocate'), 'numArgs' => -1), + ); + + /** + * Tries to establish a database connection to SQLite. + * + * @param array $params + * @param string $username + * @param string $password + * @param array $driverOptions + * @return Connection + */ + public function connect(array $params, $username = null, $password = null, array $driverOptions = array()) + { + if (isset($driverOptions['userDefinedFunctions'])) { + $this->_userDefinedFunctions = array_merge( + $this->_userDefinedFunctions, $driverOptions['userDefinedFunctions']); + unset($driverOptions['userDefinedFunctions']); + } + + $pdo = new \Doctrine\DBAL\Driver\PDOConnection( + $this->_constructPdoDsn($params), + $username, + $password, + $driverOptions + ); + + foreach ($this->_userDefinedFunctions AS $fn => $data) { + $pdo->sqliteCreateFunction($fn, $data['callback'], $data['numArgs']); + } + + return $pdo; + } + + /** + * Constructs the Sqlite PDO DSN. + * + * @return string The DSN. + * @override + */ + protected function _constructPdoDsn(array $params) + { + $dsn = 'sqlite:'; + if (isset($params['path'])) { + $dsn .= $params['path']; + } else if (isset($params['memory'])) { + $dsn .= ':memory:'; + } + + return $dsn; + } + + /** + * Gets the database platform that is relevant for this driver. + */ + public function getDatabasePlatform() + { + return new \Doctrine\DBAL\Platforms\SqlitePlatform(); + } + + /** + * Gets the schema manager that is relevant for this driver. + * + * @param Doctrine\DBAL\Connection $conn + * @return Doctrine\DBAL\Schema\SqliteSchemaManager + */ + public function getSchemaManager(\Doctrine\DBAL\Connection $conn) + { + return new \Doctrine\DBAL\Schema\SqliteSchemaManager($conn); + } + + public function getName() + { + return 'pdo_sqlite'; + } + + public function getDatabase(\Doctrine\DBAL\Connection $conn) + { + $params = $conn->getParams(); + return isset($params['path']) ? $params['path'] : null; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Connection.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Connection.php new file mode 100644 index 0000000..ba8aaf0 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Connection.php @@ -0,0 +1,45 @@ +. + */ + +namespace Doctrine\DBAL\Driver\PDOSqlsrv; + +/** + * Sqlsrv Connection implementation. + * + * @since 2.0 + */ +class Connection extends \Doctrine\DBAL\Driver\PDOConnection implements \Doctrine\DBAL\Driver\Connection +{ + /** + * @override + */ + public function quote($value, $type=\PDO::PARAM_STR) + { + $val = parent::quote($value, $type); + + // Fix for a driver version terminating all values with null byte + if (strpos($val, "\0") !== false) { + $val = substr($val, 0, -1); + } + + return $val; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php new file mode 100644 index 0000000..d3c6bf1 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php @@ -0,0 +1,88 @@ +. + */ + +namespace Doctrine\DBAL\Driver\PDOSqlsrv; + +/** + * The PDO-based Sqlsrv driver. + * + * @since 2.0 + */ +class Driver implements \Doctrine\DBAL\Driver +{ + public function connect(array $params, $username = null, $password = null, array $driverOptions = array()) + { + return new Connection( + $this->_constructPdoDsn($params), + $username, + $password, + $driverOptions + ); + } + + /** + * Constructs the Sqlsrv PDO DSN. + * + * @return string The DSN. + */ + private function _constructPdoDsn(array $params) + { + $dsn = 'sqlsrv:server='; + + if (isset($params['host'])) { + $dsn .= $params['host']; + } + + if (isset($params['port']) && !empty($params['port'])) { + $dsn .= ',' . $params['port']; + } + + if (isset($params['dbname'])) {; + $dsn .= ';Database=' . $params['dbname']; + } + + if (isset($params['MultipleActiveResultSets'])) { + $dsn .= '; MultipleActiveResultSets=' . ($params['MultipleActiveResultSets'] ? 'true' : 'false'); + } + + return $dsn; + } + + + public function getDatabasePlatform() + { + return new \Doctrine\DBAL\Platforms\SQLServer2008Platform(); + } + + public function getSchemaManager(\Doctrine\DBAL\Connection $conn) + { + return new \Doctrine\DBAL\Schema\SQLServerSchemaManager($conn); + } + + public function getName() + { + return 'pdo_sqlsrv'; + } + + public function getDatabase(\Doctrine\DBAL\Connection $conn) + { + $params = $conn->getParams(); + return $params['dbname']; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php new file mode 100644 index 0000000..6456af7 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php @@ -0,0 +1,50 @@ +. + */ + +namespace Doctrine\DBAL\Driver; + +/** + * The PDO implementation of the Statement interface. + * Used by all PDO-based drivers. + * + * @since 2.0 + */ +class PDOStatement extends \PDOStatement implements Statement +{ + private function __construct() {} + + public function setFetchMode($fetchStyle, $arg2 = null, $arg3 = null) + { + // This thin wrapper is necessary to shield against the weird signature + // of PDOStatement::setFetchMode(): even if the second and third + // parameters are optional, PHP will not let us remove it from this + // declaration. + if ($arg2 === null && $arg3 === null) { + return parent::setFetchMode($fetchStyle); + } + + if ($arg3 === null) { + return parent::setFetchMode($fetchStyle, $arg2); + } + + return parent::setFetchMode($fetchStyle, $arg2, $arg3); + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/ResultStatement.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/ResultStatement.php new file mode 100644 index 0000000..ef5eb02 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/ResultStatement.php @@ -0,0 +1,113 @@ +. + */ + +namespace Doctrine\DBAL\Driver; + +use PDO; + +/** + * Interface for the reading part of a prepare statement only. + * + * @author Benjamin Eberlei + */ +interface ResultStatement extends \Traversable +{ + /** + * Closes the cursor, enabling the statement to be executed again. + * + * @return boolean Returns TRUE on success or FALSE on failure. + */ + function closeCursor(); + + + /** + * columnCount + * Returns the number of columns in the result set + * + * @return integer Returns the number of columns in the result set represented + * by the PDOStatement object. If there is no result set, + * this method should return 0. + */ + function columnCount(); + + /** + * setFetchMode + * Set the fetch mode to use while iterating this statement. + * + * @param integer $fetchStyle + */ + function setFetchMode($fetchStyle, $arg2 = null, $arg3 = null); + + /** + * fetch + * + * @see Query::HYDRATE_* constants + * @param integer $fetchStyle Controls how the next row will be returned to the caller. + * This value must be one of the Query::HYDRATE_* constants, + * defaulting to Query::HYDRATE_BOTH + * + * @param integer $cursorOrientation For a PDOStatement object representing a scrollable cursor, + * this value determines which row will be returned to the caller. + * This value must be one of the Query::HYDRATE_ORI_* constants, defaulting to + * Query::HYDRATE_ORI_NEXT. To request a scrollable cursor for your + * PDOStatement object, + * you must set the PDO::ATTR_CURSOR attribute to Doctrine::CURSOR_SCROLL when you + * prepare the SQL statement with Doctrine_Adapter_Interface->prepare(). + * + * @param integer $cursorOffset For a PDOStatement object representing a scrollable cursor for which the + * $cursorOrientation parameter is set to Query::HYDRATE_ORI_ABS, this value specifies + * the absolute number of the row in the result set that shall be fetched. + * + * For a PDOStatement object representing a scrollable cursor for + * which the $cursorOrientation parameter is set to Query::HYDRATE_ORI_REL, this value + * specifies the row to fetch relative to the cursor position before + * PDOStatement->fetch() was called. + * + * @return mixed + */ + function fetch($fetchStyle = PDO::FETCH_BOTH); + + /** + * Returns an array containing all of the result set rows + * + * @param integer $fetchStyle Controls how the next row will be returned to the caller. + * This value must be one of the Query::HYDRATE_* constants, + * defaulting to Query::HYDRATE_BOTH + * + * @param integer $columnIndex Returns the indicated 0-indexed column when the value of $fetchStyle is + * Query::HYDRATE_COLUMN. Defaults to 0. + * + * @return array + */ + function fetchAll($fetchStyle = PDO::FETCH_BOTH); + + /** + * fetchColumn + * Returns a single column from the next row of a + * result set or FALSE if there are no more rows. + * + * @param integer $columnIndex 0-indexed number of the column you wish to retrieve from the row. If no + * value is supplied, PDOStatement->fetchColumn() + * fetches the first column. + * + * @return string returns a single column in the next row of a result set. + */ + function fetchColumn($columnIndex = 0); +} + diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Statement.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Statement.php new file mode 100644 index 0000000..d417833 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Statement.php @@ -0,0 +1,124 @@ +. + */ + +namespace Doctrine\DBAL\Driver; + +use \PDO; + +/** + * Statement interface. + * Drivers must implement this interface. + * + * This resembles (a subset of) the PDOStatement interface. + * + * @author Konsta Vesterinen + * @author Roman Borschel + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + */ +interface Statement extends ResultStatement +{ + /** + * Binds a value to a corresponding named or positional + * placeholder in the SQL statement that was used to prepare the statement. + * + * @param mixed $param Parameter identifier. For a prepared statement using named placeholders, + * this will be a parameter name of the form :name. For a prepared statement + * using question mark placeholders, this will be the 1-indexed position of the parameter + * + * @param mixed $value The value to bind to the parameter. + * @param integer $type Explicit data type for the parameter using the PDO::PARAM_* constants. + * + * @return boolean Returns TRUE on success or FALSE on failure. + */ + function bindValue($param, $value, $type = null); + + /** + * Binds a PHP variable to a corresponding named or question mark placeholder in the + * SQL statement that was use to prepare the statement. Unlike PDOStatement->bindValue(), + * the variable is bound as a reference and will only be evaluated at the time + * that PDOStatement->execute() is called. + * + * Most parameters are input parameters, that is, parameters that are + * used in a read-only fashion to build up the query. Some drivers support the invocation + * of stored procedures that return data as output parameters, and some also as input/output + * parameters that both send in data and are updated to receive it. + * + * @param mixed $param Parameter identifier. For a prepared statement using named placeholders, + * this will be a parameter name of the form :name. For a prepared statement + * using question mark placeholders, this will be the 1-indexed position of the parameter + * + * @param mixed $variable Name of the PHP variable to bind to the SQL statement parameter. + * + * @param integer $type Explicit data type for the parameter using the PDO::PARAM_* constants. To return + * an INOUT parameter from a stored procedure, use the bitwise OR operator to set the + * PDO::PARAM_INPUT_OUTPUT bits for the data_type parameter. + * @return boolean Returns TRUE on success or FALSE on failure. + */ + function bindParam($column, &$variable, $type = null); + + /** + * errorCode + * Fetch the SQLSTATE associated with the last operation on the statement handle + * + * @see Doctrine_Adapter_Interface::errorCode() + * @return string error code string + */ + function errorCode(); + + /** + * errorInfo + * Fetch extended error information associated with the last operation on the statement handle + * + * @see Doctrine_Adapter_Interface::errorInfo() + * @return array error info array + */ + function errorInfo(); + + /** + * Executes a prepared statement + * + * If the prepared statement included parameter markers, you must either: + * call PDOStatement->bindParam() to bind PHP variables to the parameter markers: + * bound variables pass their value as input and receive the output value, + * if any, of their associated parameter markers or pass an array of input-only + * parameter values + * + * + * @param array $params An array of values with as many elements as there are + * bound parameters in the SQL statement being executed. + * @return boolean Returns TRUE on success or FALSE on failure. + */ + function execute($params = null); + + /** + * rowCount + * rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement + * executed by the corresponding object. + * + * If the last SQL statement executed by the associated Statement object was a SELECT statement, + * some databases may return the number of rows returned by that statement. However, + * this behaviour is not guaranteed for all databases and should not be + * relied on for portable applications. + * + * @return integer Returns the number of rows. + */ + function rowCount(); +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/DriverManager.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/DriverManager.php new file mode 100644 index 0000000..b670ee5 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/DriverManager.php @@ -0,0 +1,165 @@ +. + */ + +namespace Doctrine\DBAL; + +use Doctrine\Common\EventManager; + +/** + * Factory for creating Doctrine\DBAL\Connection instances. + * + * @author Roman Borschel + * @since 2.0 + */ +final class DriverManager +{ + /** + * List of supported drivers and their mappings to the driver classes. + * + * @var array + * @todo REMOVE. Users should directly supply class names instead. + */ + private static $_driverMap = array( + 'pdo_mysql' => 'Doctrine\DBAL\Driver\PDOMySql\Driver', + 'pdo_sqlite' => 'Doctrine\DBAL\Driver\PDOSqlite\Driver', + 'pdo_pgsql' => 'Doctrine\DBAL\Driver\PDOPgSql\Driver', + 'pdo_oci' => 'Doctrine\DBAL\Driver\PDOOracle\Driver', + 'oci8' => 'Doctrine\DBAL\Driver\OCI8\Driver', + 'ibm_db2' => 'Doctrine\DBAL\Driver\IBMDB2\DB2Driver', + 'pdo_ibm' => 'Doctrine\DBAL\Driver\PDOIbm\Driver', + 'pdo_sqlsrv' => 'Doctrine\DBAL\Driver\PDOSqlsrv\Driver', + 'mysqli' => 'Doctrine\DBAL\Driver\Mysqli\Driver', + ); + + /** Private constructor. This class cannot be instantiated. */ + private function __construct() { } + + /** + * Creates a connection object based on the specified parameters. + * This method returns a Doctrine\DBAL\Connection which wraps the underlying + * driver connection. + * + * $params must contain at least one of the following. + * + * Either 'driver' with one of the following values: + * pdo_mysql + * pdo_sqlite + * pdo_pgsql + * pdo_oracle + * pdo_sqlsrv + * + * OR 'driverClass' that contains the full class name (with namespace) of the + * driver class to instantiate. + * + * Other (optional) parameters: + * + * user (string): + * The username to use when connecting. + * + * password (string): + * The password to use when connecting. + * + * driverOptions (array): + * Any additional driver-specific options for the driver. These are just passed + * through to the driver. + * + * pdo: + * You can pass an existing PDO instance through this parameter. The PDO + * instance will be wrapped in a Doctrine\DBAL\Connection. + * + * wrapperClass: + * You may specify a custom wrapper class through the 'wrapperClass' + * parameter but this class MUST inherit from Doctrine\DBAL\Connection. + * + * driverClass: + * The driver class to use. + * + * @param array $params The parameters. + * @param Doctrine\DBAL\Configuration The configuration to use. + * @param Doctrine\Common\EventManager The event manager to use. + * @return Doctrine\DBAL\Connection + */ + public static function getConnection( + array $params, + Configuration $config = null, + EventManager $eventManager = null) + { + // create default config and event manager, if not set + if ( ! $config) { + $config = new Configuration(); + } + if ( ! $eventManager) { + $eventManager = new EventManager(); + } + + // check for existing pdo object + if (isset($params['pdo']) && ! $params['pdo'] instanceof \PDO) { + throw DBALException::invalidPdoInstance(); + } else if (isset($params['pdo'])) { + $params['pdo']->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); + $params['driver'] = 'pdo_' . $params['pdo']->getAttribute(\PDO::ATTR_DRIVER_NAME); + } else { + self::_checkParams($params); + } + if (isset($params['driverClass'])) { + $className = $params['driverClass']; + } else { + $className = self::$_driverMap[$params['driver']]; + } + + $driver = new $className(); + + $wrapperClass = 'Doctrine\DBAL\Connection'; + if (isset($params['wrapperClass'])) { + if (is_subclass_of($params['wrapperClass'], $wrapperClass)) { + $wrapperClass = $params['wrapperClass']; + } else { + throw DBALException::invalidWrapperClass($params['wrapperClass']); + } + } + + return new $wrapperClass($params, $driver, $config, $eventManager); + } + + /** + * Checks the list of parameters. + * + * @param array $params + */ + private static function _checkParams(array $params) + { + // check existance of mandatory parameters + + // driver + if ( ! isset($params['driver']) && ! isset($params['driverClass'])) { + throw DBALException::driverRequired(); + } + + // check validity of parameters + + // driver + if ( isset($params['driver']) && ! isset(self::$_driverMap[$params['driver']])) { + throw DBALException::unknownDriver($params['driver'], array_keys(self::$_driverMap)); + } + + if (isset($params['driverClass']) && ! in_array('Doctrine\DBAL\Driver', class_implements($params['driverClass'], true))) { + throw DBALException::invalidDriverClass($params['driverClass']); + } + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/ConnectionEventArgs.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/ConnectionEventArgs.php new file mode 100644 index 0000000..ce80ecd --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/ConnectionEventArgs.php @@ -0,0 +1,79 @@ +. +*/ + +namespace Doctrine\DBAL\Event; + +use Doctrine\Common\EventArgs, + Doctrine\DBAL\Connection; + +/** + * Event Arguments used when a Driver connection is established inside Doctrine\DBAL\Connection. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 1.0 + * @version $Revision$ + * @author Benjamin Eberlei + */ +class ConnectionEventArgs extends EventArgs +{ + /** + * @var Connection + */ + private $_connection = null; + + public function __construct(Connection $connection) + { + $this->_connection = $connection; + } + + /** + * @return Doctrine\DBAL\Connection + */ + public function getConnection() + { + return $this->_connection; + } + + /** + * @return Doctrine\DBAL\Driver + */ + public function getDriver() + { + return $this->_connection->getDriver(); + } + + /** + * @return Doctrine\DBAL\Platforms\AbstractPlatform + */ + public function getDatabasePlatform() + { + return $this->_connection->getDatabasePlatform(); + } + + /** + * @return Doctrine\DBAL\Schema\AbstractSchemaManager + */ + public function getSchemaManager() + { + return $this->_connection->getSchemaManager(); + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/MysqlSessionInit.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/MysqlSessionInit.php new file mode 100644 index 0000000..a9718d5 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/MysqlSessionInit.php @@ -0,0 +1,74 @@ +. +*/ + +namespace Doctrine\DBAL\Event\Listeners; + +use Doctrine\DBAL\Event\ConnectionEventArgs; +use Doctrine\DBAL\Events; +use Doctrine\Common\EventSubscriber; + +/** + * MySQL Session Init Event Subscriber which allows to set the Client Encoding of the Connection + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 1.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @deprecated Use "charset" option to PDO MySQL Connection instead. + */ +class MysqlSessionInit implements EventSubscriber +{ + /** + * @var string + */ + private $_charset; + + /** + * @var string + */ + private $_collation; + + /** + * Configure Charset and Collation options of MySQL Client for each Connection + * + * @param string $charset + * @param string $collation + */ + public function __construct($charset = 'utf8', $collation = false) + { + $this->_charset = $charset; + $this->_collation = $collation; + } + + /** + * @param ConnectionEventArgs $args + * @return void + */ + public function postConnect(ConnectionEventArgs $args) + { + $collation = ($this->_collation) ? " COLLATE ".$this->_collation : ""; + $args->getConnection()->executeUpdate("SET NAMES ".$this->_charset . $collation); + } + + public function getSubscribedEvents() + { + return array(Events::postConnect); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/OracleSessionInit.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/OracleSessionInit.php new file mode 100644 index 0000000..7f5caa3 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/OracleSessionInit.php @@ -0,0 +1,79 @@ +. +*/ + +namespace Doctrine\DBAL\Event\Listeners; + +use Doctrine\DBAL\Event\ConnectionEventArgs; +use Doctrine\DBAL\Events; +use Doctrine\Common\EventSubscriber; + +/** + * Should be used when Oracle Server default enviroment does not match the Doctrine requirements. + * + * The following enviroment variables are required for the Doctrine default date format: + * + * NLS_TIME_FORMAT="HH24:MI:SS" + * NLS_DATE_FORMAT="YYYY-MM-DD HH24:MI:SS" + * NLS_TIMESTAMP_FORMAT="YYYY-MM-DD HH24:MI:SS" + * NLS_TIMESTAMP_TZ_FORMAT="YYYY-MM-DD HH24:MI:SS TZH:TZM" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.0 + * @author Benjamin Eberlei + */ +class OracleSessionInit implements EventSubscriber +{ + protected $_defaultSessionVars = array( + 'NLS_TIME_FORMAT' => "HH24:MI:SS", + 'NLS_DATE_FORMAT' => "YYYY-MM-DD HH24:MI:SS", + 'NLS_TIMESTAMP_FORMAT' => "YYYY-MM-DD HH24:MI:SS", + 'NLS_TIMESTAMP_TZ_FORMAT' => "YYYY-MM-DD HH24:MI:SS TZH:TZM", + ); + + /** + * @param array $oracleSessionVars + */ + public function __construct(array $oracleSessionVars = array()) + { + $this->_defaultSessionVars = array_merge($this->_defaultSessionVars, $oracleSessionVars); + } + + /** + * @param ConnectionEventArgs $args + * @return void + */ + public function postConnect(ConnectionEventArgs $args) + { + if (count($this->_defaultSessionVars)) { + array_change_key_case($this->_defaultSessionVars, \CASE_UPPER); + $vars = array(); + foreach ($this->_defaultSessionVars AS $option => $value) { + $vars[] = $option." = '".$value."'"; + } + $sql = "ALTER SESSION SET ".implode(" ", $vars); + $args->getConnection()->executeUpdate($sql); + } + } + + public function getSubscribedEvents() + { + return array(Events::postConnect); + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/SQLSessionInit.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/SQLSessionInit.php new file mode 100644 index 0000000..670a61e --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/SQLSessionInit.php @@ -0,0 +1,63 @@ +. +*/ + +namespace Doctrine\DBAL\Event\Listeners; + +use Doctrine\DBAL\Event\ConnectionEventArgs; +use Doctrine\DBAL\Events; +use Doctrine\Common\EventSubscriber; + +/** + * Session init listener for executing a single SQL statement right after a connection is opened. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.2 + * @author Benjamin Eberlei + */ +class SQLSessionInit implements EventSubscriber +{ + /** + * @var string + */ + protected $sql; + + /** + * @param string $sql + */ + public function __construct($sql) + { + $this->sql = $sql; + } + + /** + * @param ConnectionEventArgs $args + * @return void + */ + public function postConnect(ConnectionEventArgs $args) + { + $conn = $args->getConnection(); + $conn->exec($this->sql); + } + + public function getSubscribedEvents() + { + return array(Events::postConnect); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableAddColumnEventArgs.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableAddColumnEventArgs.php new file mode 100644 index 0000000..453f942 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableAddColumnEventArgs.php @@ -0,0 +1,114 @@ +. +*/ + +namespace Doctrine\DBAL\Event; + +use Doctrine\DBAL\Platforms\AbstractPlatform, + Doctrine\DBAL\Schema\Column, + Doctrine\DBAL\Schema\TableDiff; + +/** + * Event Arguments used when SQL queries for adding table columns are generated inside Doctrine\DBAL\Platform\*Platform. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.2 + * @author Jan Sorgalla + */ +class SchemaAlterTableAddColumnEventArgs extends SchemaEventArgs +{ + /** + * @var \Doctrine\DBAL\Schema\Column + */ + private $_column = null; + + /** + * @var \Doctrine\DBAL\Schema\TableDiff + */ + private $_tableDiff = null; + + /** + * @var \Doctrine\DBAL\Platforms\AbstractPlatform + */ + private $_platform = null; + + /** + * @var array + */ + private $_sql = array(); + + /** + * @param \Doctrine\DBAL\Schema\Column $column + * @param \Doctrine\DBAL\Schema\TableDiff $tableDiff + * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform + */ + public function __construct(Column $column, TableDiff $tableDiff, AbstractPlatform $platform) + { + $this->_column = $column; + $this->_tableDiff = $tableDiff; + $this->_platform = $platform; + } + + /** + * @return \Doctrine\DBAL\Schema\Column + */ + public function getColumn() + { + return $this->_column; + } + + /** + * @return \Doctrine\DBAL\Schema\TableDiff + */ + public function getTableDiff() + { + return $this->_tableDiff; + } + + /** + * @return \Doctrine\DBAL\Platforms\AbstractPlatform + */ + public function getPlatform() + { + return $this->_platform; + } + + /** + * @param string|array $sql + * @return \Doctrine\DBAL\Event\SchemaAlterTableAddColumnEventArgs + */ + public function addSql($sql) + { + if (is_array($sql)) { + $this->_sql = array_merge($this->_sql, $sql); + } else { + $this->_sql[] = $sql; + } + + return $this; + } + + /** + * @return array + */ + public function getSql() + { + return $this->_sql; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableChangeColumnEventArgs.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableChangeColumnEventArgs.php new file mode 100644 index 0000000..180fbee --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableChangeColumnEventArgs.php @@ -0,0 +1,114 @@ +. +*/ + +namespace Doctrine\DBAL\Event; + +use Doctrine\DBAL\Platforms\AbstractPlatform, + Doctrine\DBAL\Schema\ColumnDiff, + Doctrine\DBAL\Schema\TableDiff; + +/** + * Event Arguments used when SQL queries for changing table columns are generated inside Doctrine\DBAL\Platform\*Platform. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.2 + * @author Jan Sorgalla + */ +class SchemaAlterTableChangeColumnEventArgs extends SchemaEventArgs +{ + /** + * @var \Doctrine\DBAL\Schema\ColumnDiff + */ + private $_columnDiff = null; + + /** + * @var \Doctrine\DBAL\Schema\TableDiff + */ + private $_tableDiff = null; + + /** + * @var \Doctrine\DBAL\Platforms\AbstractPlatform + */ + private $_platform = null; + + /** + * @var array + */ + private $_sql = array(); + + /** + * @param \Doctrine\DBAL\Schema\ColumnDiff $columnDiff + * @param \Doctrine\DBAL\Schema\TableDiff $tableDiff + * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform + */ + public function __construct(ColumnDiff $columnDiff, TableDiff $tableDiff, AbstractPlatform $platform) + { + $this->_columnDiff = $columnDiff; + $this->_tableDiff = $tableDiff; + $this->_platform = $platform; + } + + /** + * @return \Doctrine\DBAL\Schema\ColumnDiff + */ + public function getColumnDiff() + { + return $this->_columnDiff; + } + + /** + * @return \Doctrine\DBAL\Schema\TableDiff + */ + public function getTableDiff() + { + return $this->_tableDiff; + } + + /** + * @return \Doctrine\DBAL\Platforms\AbstractPlatform + */ + public function getPlatform() + { + return $this->_platform; + } + + /** + * @param string|array $sql + * @return \Doctrine\DBAL\Event\SchemaAlterTableChangeColumnEventArgs + */ + public function addSql($sql) + { + if (is_array($sql)) { + $this->_sql = array_merge($this->_sql, $sql); + } else { + $this->_sql[] = $sql; + } + + return $this; + } + + /** + * @return array + */ + public function getSql() + { + return $this->_sql; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableEventArgs.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableEventArgs.php new file mode 100644 index 0000000..0f9a0a5 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableEventArgs.php @@ -0,0 +1,99 @@ +. +*/ + +namespace Doctrine\DBAL\Event; + +use Doctrine\DBAL\Platforms\AbstractPlatform, + Doctrine\DBAL\Schema\Column, + Doctrine\DBAL\Schema\TableDiff; + +/** + * Event Arguments used when SQL queries for creating tables are generated inside Doctrine\DBAL\Platform\*Platform. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.2 + * @author Jan Sorgalla + */ +class SchemaAlterTableEventArgs extends SchemaEventArgs +{ + /** + * @var \Doctrine\DBAL\Schema\TableDiff + */ + private $_tableDiff = null; + + /** + * @var \Doctrine\DBAL\Platforms\AbstractPlatform + */ + private $_platform = null; + + /** + * @var array + */ + private $_sql = array(); + + /** + * @param \Doctrine\DBAL\Schema\TableDiff $tableDiff + * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform + */ + public function __construct(TableDiff $tableDiff, AbstractPlatform $platform) + { + $this->_tableDiff = $tableDiff; + $this->_platform = $platform; + } + + /** + * @return \Doctrine\DBAL\Schema\TableDiff + */ + public function getTableDiff() + { + return $this->_tableDiff; + } + + /** + * @return \Doctrine\DBAL\Platforms\AbstractPlatform + */ + public function getPlatform() + { + return $this->_platform; + } + + /** + * @param string|array $sql + * @return \Doctrine\DBAL\Event\SchemaAlterTableEventArgs + */ + public function addSql($sql) + { + if (is_array($sql)) { + $this->_sql = array_merge($this->_sql, $sql); + } else { + $this->_sql[] = $sql; + } + + return $this; + } + + /** + * @return array + */ + public function getSql() + { + return $this->_sql; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRemoveColumnEventArgs.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRemoveColumnEventArgs.php new file mode 100644 index 0000000..b64bbc1 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRemoveColumnEventArgs.php @@ -0,0 +1,114 @@ +. +*/ + +namespace Doctrine\DBAL\Event; + +use Doctrine\DBAL\Platforms\AbstractPlatform, + Doctrine\DBAL\Schema\Column, + Doctrine\DBAL\Schema\TableDiff; + +/** + * Event Arguments used when SQL queries for removing table columns are generated inside Doctrine\DBAL\Platform\*Platform. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.2 + * @author Jan Sorgalla + */ +class SchemaAlterTableRemoveColumnEventArgs extends SchemaEventArgs +{ + /** + * @var \Doctrine\DBAL\Schema\Column + */ + private $_column = null; + + /** + * @var \Doctrine\DBAL\Schema\TableDiff + */ + private $_tableDiff = null; + + /** + * @var \Doctrine\DBAL\Platforms\AbstractPlatform + */ + private $_platform = null; + + /** + * @var array + */ + private $_sql = array(); + + /** + * @param \Doctrine\DBAL\Schema\Column $column + * @param \Doctrine\DBAL\Schema\TableDiff $tableDiff + * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform + */ + public function __construct(Column $column, TableDiff $tableDiff, AbstractPlatform $platform) + { + $this->_column = $column; + $this->_tableDiff = $tableDiff; + $this->_platform = $platform; + } + + /** + * @return \Doctrine\DBAL\Schema\Column + */ + public function getColumn() + { + return $this->_column; + } + + /** + * @return \Doctrine\DBAL\Schema\TableDiff + */ + public function getTableDiff() + { + return $this->_tableDiff; + } + + /** + * @return \Doctrine\DBAL\Platforms\AbstractPlatform + */ + public function getPlatform() + { + return $this->_platform; + } + + /** + * @param string|array $sql + * @return \Doctrine\DBAL\Event\SchemaAlterTableRemoveColumnEventArgs + */ + public function addSql($sql) + { + if (is_array($sql)) { + $this->_sql = array_merge($this->_sql, $sql); + } else { + $this->_sql[] = $sql; + } + + return $this; + } + + /** + * @return array + */ + public function getSql() + { + return $this->_sql; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRenameColumnEventArgs.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRenameColumnEventArgs.php new file mode 100644 index 0000000..4b9a88b --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRenameColumnEventArgs.php @@ -0,0 +1,129 @@ +. +*/ + +namespace Doctrine\DBAL\Event; + +use Doctrine\DBAL\Platforms\AbstractPlatform, + Doctrine\DBAL\Schema\Column, + Doctrine\DBAL\Schema\TableDiff; + +/** + * Event Arguments used when SQL queries for renaming table columns are generated inside Doctrine\DBAL\Platform\*Platform. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.2 + * @author Jan Sorgalla + */ +class SchemaAlterTableRenameColumnEventArgs extends SchemaEventArgs +{ + /** + * @var string + */ + private $_oldColumnName = null; + + /** + * @var \Doctrine\DBAL\Schema\Column + */ + private $_column = null; + + /** + * @var \Doctrine\DBAL\Schema\TableDiff + */ + private $_tableDiff = null; + + /** + * @var \Doctrine\DBAL\Platforms\AbstractPlatform + */ + private $_platform = null; + + /** + * @var array + */ + private $_sql = array(); + + /** + * @param string $oldColumnName + * @param \Doctrine\DBAL\Schema\Column $column + * @param \Doctrine\DBAL\Schema\TableDiff $tableDiff + * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform + */ + public function __construct($oldColumnName, Column $column, TableDiff $tableDiff, AbstractPlatform $platform) + { + $this->_oldColumnName = $oldColumnName; + $this->_column = $column; + $this->_tableDiff = $tableDiff; + $this->_platform = $platform; + } + + /** + * @return string + */ + public function getOldColumnName() + { + return $this->_oldColumnName; + } + + /** + * @return \Doctrine\DBAL\Schema\Column + */ + public function getColumn() + { + return $this->_column; + } + + /** + * @return \Doctrine\DBAL\Schema\TableDiff + */ + public function getTableDiff() + { + return $this->_tableDiff; + } + + /** + * @return \Doctrine\DBAL\Platforms\AbstractPlatform + */ + public function getPlatform() + { + return $this->_platform; + } + + /** + * @param string|array $sql + * @return \Doctrine\DBAL\Event\SchemaAlterTableRenameColumnEventArgs + */ + public function addSql($sql) + { + if (is_array($sql)) { + $this->_sql = array_merge($this->_sql, $sql); + } else { + $this->_sql[] = $sql; + } + + return $this; + } + + /** + * @return array + */ + public function getSql() + { + return $this->_sql; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaColumnDefinitionEventArgs.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaColumnDefinitionEventArgs.php new file mode 100644 index 0000000..4cde46c --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaColumnDefinitionEventArgs.php @@ -0,0 +1,137 @@ +. +*/ + +namespace Doctrine\DBAL\Event; + +use Doctrine\DBAL\Connection, + Doctrine\DBAL\Schema\Column; + +/** + * Event Arguments used when the portable column definition is generated inside Doctrine\DBAL\Schema\AbstractSchemaManager. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.2 + * @author Jan Sorgalla + */ +class SchemaColumnDefinitionEventArgs extends SchemaEventArgs +{ + /** + * @var \Doctrine\DBAL\Schema\Column + */ + private $_column = null; + + /** + * Raw column data as fetched from the database + * + * @var array + */ + private $_tableColumn = null; + + /** + * @var string + */ + private $_table = null; + + /** + * @var string + */ + private $_database = null; + + /** + * @var \Doctrine\DBAL\Connection + */ + private $_connection = null; + + /** + * @param array $tableColumn + * @param string $table + * @param string $database + * @param \Doctrine\DBAL\Connection $conn + */ + public function __construct(array $tableColumn, $table, $database, Connection $connection) + { + $this->_tableColumn = $tableColumn; + $this->_table = $table; + $this->_database = $database; + $this->_connection = $connection; + } + + /** + * Allows to clear the column which means the column will be excluded from + * tables column list. + * + * @param null|\Doctrine\DBAL\Schema\Column $column + * @return SchemaColumnDefinitionEventArgs + */ + public function setColumn(Column $column = null) + { + $this->_column = $column; + + return $this; + } + + /** + * @return \Doctrine\DBAL\Schema\Column + */ + public function getColumn() + { + return $this->_column; + } + + /** + * @return array + */ + public function getTableColumn() + { + return $this->_tableColumn; + } + + /** + * @return string + */ + public function getTable() + { + return $this->_table; + } + + /** + * @return string + */ + public function getDatabase() + { + return $this->_database; + } + + /** + * @return \Doctrine\DBAL\Connection + */ + public function getConnection() + { + return $this->_connection; + } + + /** + * @return \Doctrine\DBAL\Platforms\AbstractPlatform + */ + public function getDatabasePlatform() + { + return $this->_connection->getDatabasePlatform(); + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableColumnEventArgs.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableColumnEventArgs.php new file mode 100644 index 0000000..5e9a440 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableColumnEventArgs.php @@ -0,0 +1,114 @@ +. +*/ + +namespace Doctrine\DBAL\Event; + +use Doctrine\DBAL\Platforms\AbstractPlatform, + Doctrine\DBAL\Schema\Column, + Doctrine\DBAL\Schema\Table; + +/** + * Event Arguments used when SQL queries for creating table columns are generated inside Doctrine\DBAL\Platform\AbstractPlatform. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.2 + * @author Jan Sorgalla + */ +class SchemaCreateTableColumnEventArgs extends SchemaEventArgs +{ + /** + * @var \Doctrine\DBAL\Schema\Column + */ + private $_column = null; + + /** + * @var \Doctrine\DBAL\Schema\Table + */ + private $_table = null; + + /** + * @var \Doctrine\DBAL\Platforms\AbstractPlatform + */ + private $_platform = null; + + /** + * @var array + */ + private $_sql = array(); + + /** + * @param \Doctrine\DBAL\Schema\Column $column + * @param \Doctrine\DBAL\Schema\Table $table + * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform + */ + public function __construct(Column $column, Table $table, AbstractPlatform $platform) + { + $this->_column = $column; + $this->_table = $table; + $this->_platform = $platform; + } + + /** + * @return \Doctrine\DBAL\Schema\Column + */ + public function getColumn() + { + return $this->_column; + } + + /** + * @return \Doctrine\DBAL\Schema\Table + */ + public function getTable() + { + return $this->_table; + } + + /** + * @return \Doctrine\DBAL\Platforms\AbstractPlatform + */ + public function getPlatform() + { + return $this->_platform; + } + + /** + * @param string|array $sql + * @return \Doctrine\DBAL\Event\SchemaCreateTableColumnEventArgs + */ + public function addSql($sql) + { + if (is_array($sql)) { + $this->_sql = array_merge($this->_sql, $sql); + } else { + $this->_sql[] = $sql; + } + + return $this; + } + + /** + * @return array + */ + public function getSql() + { + return $this->_sql; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableEventArgs.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableEventArgs.php new file mode 100644 index 0000000..138981c --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableEventArgs.php @@ -0,0 +1,128 @@ +. +*/ + +namespace Doctrine\DBAL\Event; + +use Doctrine\DBAL\Platforms\AbstractPlatform, + Doctrine\DBAL\Schema\Table; + +/** + * Event Arguments used when SQL queries for creating tables are generated inside Doctrine\DBAL\Platform\AbstractPlatform. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.2 + * @author Jan Sorgalla + */ +class SchemaCreateTableEventArgs extends SchemaEventArgs +{ + /** + * @var \Doctrine\DBAL\Schema\Table + */ + private $_table = null; + + /** + * @var array + */ + private $_columns = null; + + /** + * @var array + */ + private $_options = null; + + /** + * @var \Doctrine\DBAL\Platforms\AbstractPlatform + */ + private $_platform = null; + + /** + * @var array + */ + private $_sql = array(); + + /** + * @param \Doctrine\DBAL\Schema\Table $table + * @param array $columns + * @param array $options + * @param Doctrine\DBAL\Platforms\AbstractPlatform $platform + */ + public function __construct(Table $table, array $columns, array $options, AbstractPlatform $platform) + { + $this->_table = $table; + $this->_columns = $columns; + $this->_options = $options; + $this->_platform = $platform; + } + + /** + * @return \Doctrine\DBAL\Schema\Table + */ + public function getTable() + { + return $this->_table; + } + + /** + * @return array + */ + public function getColumns() + { + return $this->_columns; + } + + /** + * @return array + */ + public function getOptions() + { + return $this->_options; + } + + /** + * @return \Doctrine\DBAL\Platforms\AbstractPlatform + */ + public function getPlatform() + { + return $this->_platform; + } + + /** + * @param string|array $sql + * @return \Doctrine\DBAL\Event\SchemaCreateTableEventArgs + */ + public function addSql($sql) + { + if (is_array($sql)) { + $this->_sql = array_merge($this->_sql, $sql); + } else { + $this->_sql[] = $sql; + } + + return $this; + } + + /** + * @return array + */ + public function getSql() + { + return $this->_sql; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaDropTableEventArgs.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaDropTableEventArgs.php new file mode 100644 index 0000000..ebd2163 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaDropTableEventArgs.php @@ -0,0 +1,98 @@ +. +*/ + +namespace Doctrine\DBAL\Event; + +use Doctrine\DBAL\Platforms\AbstractPlatform, + Doctrine\DBAL\Schema\Table; + +/** + * Event Arguments used when the SQL query for dropping tables are generated inside Doctrine\DBAL\Platform\AbstractPlatform. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.2 + * @author Jan Sorgalla + */ +class SchemaDropTableEventArgs extends SchemaEventArgs +{ + /** + * @var string|\Doctrine\DBAL\Schema\Table + */ + private $_table = null; + + /** + * @var \Doctrine\DBAL\Platforms\AbstractPlatform + */ + private $_platform = null; + + /** + * @var string + */ + private $_sql = null; + + /** + * @param string|\Doctrine\DBAL\Schema\Table $table + * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform + */ + public function __construct($table, AbstractPlatform $platform) + { + if (!$table instanceof Table && !is_string($table)) { + throw new \InvalidArgumentException('SchemaCreateTableEventArgs expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.'); + } + + $this->_table = $table; + $this->_platform = $platform; + } + + /** + * @return string|\Doctrine\DBAL\Schema\Table + */ + public function getTable() + { + return $this->_table; + } + + /** + * @return \Doctrine\DBAL\Platforms\AbstractPlatform + */ + public function getPlatform() + { + return $this->_platform; + } + + /** + * @param string $sql + * @return \Doctrine\DBAL\Event\SchemaDropTableEventArgs + */ + public function setSql($sql) + { + $this->_sql = $sql; + + return $this; + } + + /** + * @return string + */ + public function getSql() + { + return $this->_sql; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaEventArgs.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaEventArgs.php new file mode 100644 index 0000000..8181225 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaEventArgs.php @@ -0,0 +1,56 @@ +. +*/ + +namespace Doctrine\DBAL\Event; + +use Doctrine\Common\EventArgs; + +/** + * Base class for schema related events. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.2 + * @author Jan Sorgalla + */ +class SchemaEventArgs extends EventArgs +{ + /** + * @var boolean + */ + private $_preventDefault = false; + + /** + * @return \Doctrine\DBAL\Event\SchemaEventArgs + */ + public function preventDefault() + { + $this->_preventDefault = true; + + return $this; + } + + /** + * @return boolean + */ + public function isDefaultPrevented() + { + return $this->_preventDefault; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaIndexDefinitionEventArgs.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaIndexDefinitionEventArgs.php new file mode 100644 index 0000000..9eb95af --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaIndexDefinitionEventArgs.php @@ -0,0 +1,122 @@ +. +*/ + +namespace Doctrine\DBAL\Event; + +use Doctrine\DBAL\Connection, + Doctrine\DBAL\Schema\Index; + +/** + * Event Arguments used when the portable index definition is generated inside Doctrine\DBAL\Schema\AbstractSchemaManager. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.2 + * @author Jan Sorgalla + */ +class SchemaIndexDefinitionEventArgs extends SchemaEventArgs +{ + /** + * @var \Doctrine\DBAL\Schema\Index + */ + private $_index = null; + + /** + * Raw index data as fetched from the database + * + * @var array + */ + private $_tableIndex = null; + + /** + * @var string + */ + private $_table = null; + + /** + * @var \Doctrine\DBAL\Connection + */ + private $_connection = null; + + /** + * @param array $tableIndex + * @param string $table + * @param \Doctrine\DBAL\Connection $conn + */ + public function __construct(array $tableIndex, $table, Connection $connection) + { + $this->_tableIndex = $tableIndex; + $this->_table = $table; + $this->_connection = $connection; + } + + /** + * Allows to clear the index which means the index will be excluded from + * tables index list. + * + * @param null|\Doctrine\DBAL\Schema\Index $index + * @return SchemaIndexDefinitionEventArgs + */ + public function setIndex(Index $index = null) + { + $this->_index = $index; + + return $this; + } + + /** + * @return \Doctrine\DBAL\Schema\Index + */ + public function getIndex() + { + return $this->_index; + } + + /** + * @return array + */ + public function getTableIndex() + { + return $this->_tableIndex; + } + + /** + * @return string + */ + public function getTable() + { + return $this->_table; + } + + /** + * @return \Doctrine\DBAL\Connection + */ + public function getConnection() + { + return $this->_connection; + } + + /** + * @return \Doctrine\DBAL\Platforms\AbstractPlatform + */ + public function getDatabasePlatform() + { + return $this->_connection->getDatabasePlatform(); + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Events.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Events.php new file mode 100644 index 0000000..25e31f0 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Events.php @@ -0,0 +1,48 @@ +. + */ + +namespace Doctrine\DBAL; + +/** + * Container for all DBAL events. + * + * This class cannot be instantiated. + * + * @author Roman Borschel + * @since 2.0 + */ +final class Events +{ + private function __construct() {} + + const postConnect = 'postConnect'; + + const onSchemaCreateTable = 'onSchemaCreateTable'; + const onSchemaCreateTableColumn = 'onSchemaCreateTableColumn'; + const onSchemaDropTable = 'onSchemaDropTable'; + const onSchemaAlterTable = 'onSchemaAlterTable'; + const onSchemaAlterTableAddColumn = 'onSchemaAlterTableAddColumn'; + const onSchemaAlterTableRemoveColumn = 'onSchemaAlterTableRemoveColumn'; + const onSchemaAlterTableChangeColumn = 'onSchemaAlterTableChangeColumn'; + const onSchemaAlterTableRenameColumn = 'onSchemaAlterTableRenameColumn'; + const onSchemaColumnDefinition = 'onSchemaColumnDefinition'; + const onSchemaIndexDefinition = 'onSchemaIndexDefinition'; +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/LockMode.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/LockMode.php new file mode 100644 index 0000000..dff96de --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/LockMode.php @@ -0,0 +1,42 @@ +. +*/ + +namespace Doctrine\DBAL; + +/** + * Contains all DBAL LockModes + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 1.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Roman Borschel + */ +class LockMode +{ + const NONE = 0; + const OPTIMISTIC = 1; + const PESSIMISTIC_READ = 2; + const PESSIMISTIC_WRITE = 4; + + final private function __construct() { } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/DebugStack.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/DebugStack.php new file mode 100644 index 0000000..7dca159 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/DebugStack.php @@ -0,0 +1,67 @@ +. + */ + +namespace Doctrine\DBAL\Logging; + +/** + * Includes executed SQLs in a Debug Stack + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class DebugStack implements SQLLogger +{ + /** @var array $queries Executed SQL queries. */ + public $queries = array(); + + /** @var boolean $enabled If Debug Stack is enabled (log queries) or not. */ + public $enabled = true; + + public $start = null; + + public $currentQuery = 0; + + /** + * {@inheritdoc} + */ + public function startQuery($sql, array $params = null, array $types = null) + { + if ($this->enabled) { + $this->start = microtime(true); + $this->queries[++$this->currentQuery] = array('sql' => $sql, 'params' => $params, 'types' => $types, 'executionMS' => 0); + } + } + + /** + * {@inheritdoc} + */ + public function stopQuery() + { + $this->queries[$this->currentQuery]['executionMS'] = microtime(true) - $this->start; + } +} + diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/EchoSQLLogger.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/EchoSQLLogger.php new file mode 100644 index 0000000..2c3caf2 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/EchoSQLLogger.php @@ -0,0 +1,61 @@ +. + */ + +namespace Doctrine\DBAL\Logging; + +/** + * A SQL logger that logs to the standard output using echo/var_dump. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class EchoSQLLogger implements SQLLogger +{ + /** + * {@inheritdoc} + */ + public function startQuery($sql, array $params = null, array $types = null) + { + echo $sql . PHP_EOL; + + if ($params) { + var_dump($params); + } + + if ($types) { + var_dump($types); + } + } + + /** + * {@inheritdoc} + */ + public function stopQuery() + { + + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/LoggerChain.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/LoggerChain.php new file mode 100644 index 0000000..0711c9b --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/LoggerChain.php @@ -0,0 +1,64 @@ +. + */ + +namespace Doctrine\DBAL\Logging; + +/** + * Chains multiple SQLLogger + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.2 + * @author Christophe Coevoet + */ +class LoggerChain implements SQLLogger +{ + private $loggers = array(); + + /** + * Adds a logger in the chain + * + * @param SQLLogger $logger + */ + public function addLogger(SQLLogger $logger) + { + $this->loggers[] = $logger; + } + + /** + * {@inheritdoc} + */ + public function startQuery($sql, array $params = null, array $types = null) + { + foreach ($this->loggers as $logger) { + $logger->startQuery($sql, $params, $types); + } + } + + /** + * {@inheritdoc} + */ + public function stopQuery() + { + foreach ($this->loggers as $logger) { + $logger->stopQuery(); + } + } +} + diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/SQLLogger.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/SQLLogger.php new file mode 100644 index 0000000..6fccb6a --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/SQLLogger.php @@ -0,0 +1,54 @@ +. + */ + +namespace Doctrine\DBAL\Logging; + +/** + * Interface for SQL loggers. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +interface SQLLogger +{ + /** + * Logs a SQL statement somewhere. + * + * @param string $sql The SQL to be executed. + * @param array $params The SQL parameters. + * @param array $types The SQL parameter types. + * @return void + */ + public function startQuery($sql, array $params = null, array $types = null); + + /** + * Mark the last started query as stopped. This can be used for timing of queries. + * + * @return void + */ + public function stopQuery(); +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php new file mode 100644 index 0000000..7f5024d --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php @@ -0,0 +1,2645 @@ +. + */ + +namespace Doctrine\DBAL\Platforms; + +use Doctrine\DBAL\DBALException, + Doctrine\DBAL\Connection, + Doctrine\DBAL\Types, + Doctrine\DBAL\Schema\Table, + Doctrine\DBAL\Schema\Index, + Doctrine\DBAL\Schema\ForeignKeyConstraint, + Doctrine\DBAL\Schema\TableDiff, + Doctrine\DBAL\Schema\Column, + Doctrine\DBAL\Schema\ColumnDiff, + Doctrine\DBAL\Types\Type, + Doctrine\DBAL\Events, + Doctrine\Common\EventManager, + Doctrine\DBAL\Event\SchemaCreateTableEventArgs, + Doctrine\DBAL\Event\SchemaCreateTableColumnEventArgs, + Doctrine\DBAL\Event\SchemaDropTableEventArgs, + Doctrine\DBAL\Event\SchemaAlterTableEventArgs, + Doctrine\DBAL\Event\SchemaAlterTableAddColumnEventArgs, + Doctrine\DBAL\Event\SchemaAlterTableRemoveColumnEventArgs, + Doctrine\DBAL\Event\SchemaAlterTableChangeColumnEventArgs, + Doctrine\DBAL\Event\SchemaAlterTableRenameColumnEventArgs; + +/** + * Base class for all DatabasePlatforms. The DatabasePlatforms are the central + * point of abstraction of platform-specific behaviors, features and SQL dialects. + * They are a passive source of information. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Lukas Smith (PEAR MDB2 library) + * @author Benjamin Eberlei + * @todo Remove any unnecessary methods. + */ +abstract class AbstractPlatform +{ + /** + * @var int + */ + const CREATE_INDEXES = 1; + + /** + * @var int + */ + const CREATE_FOREIGNKEYS = 2; + + /** + * @var int + */ + const TRIM_UNSPECIFIED = 0; + + /** + * @var int + */ + const TRIM_LEADING = 1; + + /** + * @var int + */ + const TRIM_TRAILING = 2; + + /** + * @var int + */ + const TRIM_BOTH = 3; + + /** + * @var array + */ + protected $doctrineTypeMapping = null; + + /** + * Contains a list of all columns that should generate parseable column comments for type-detection + * in reverse engineering scenarios. + * + * @var array + */ + protected $doctrineTypeComments = null; + + /** + * @var Doctrine\Common\EventManager + */ + protected $_eventManager; + + /** + * Constructor. + */ + public function __construct() {} + + /** + * Sets the EventManager used by the Platform. + * + * @param \Doctrine\Common\EventManager + */ + public function setEventManager(EventManager $eventManager) + { + $this->_eventManager = $eventManager; + } + + /** + * Gets the EventManager used by the Platform. + * + * @return \Doctrine\Common\EventManager + */ + public function getEventManager() + { + return $this->_eventManager; + } + + /** + * Gets the SQL snippet that declares a boolean column. + * + * @param array $columnDef + * @return string + */ + abstract public function getBooleanTypeDeclarationSQL(array $columnDef); + + /** + * Gets the SQL snippet that declares a 4 byte integer column. + * + * @param array $columnDef + * @return string + */ + abstract public function getIntegerTypeDeclarationSQL(array $columnDef); + + /** + * Gets the SQL snippet that declares an 8 byte integer column. + * + * @param array $columnDef + * @return string + */ + abstract public function getBigIntTypeDeclarationSQL(array $columnDef); + + /** + * Gets the SQL snippet that declares a 2 byte integer column. + * + * @param array $columnDef + * @return string + */ + abstract public function getSmallIntTypeDeclarationSQL(array $columnDef); + + /** + * Gets the SQL snippet that declares common properties of an integer column. + * + * @param array $columnDef + * @return string + */ + abstract protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef); + + /** + * Lazy load Doctrine Type Mappings + * + * @return void + */ + abstract protected function initializeDoctrineTypeMappings(); + + /** + * Gets the SQL snippet used to declare a VARCHAR column type. + * + * @param array $field + */ + public function getVarcharTypeDeclarationSQL(array $field) + { + if ( !isset($field['length'])) { + $field['length'] = $this->getVarcharDefaultLength(); + } + + $fixed = (isset($field['fixed'])) ? $field['fixed'] : false; + + if ($field['length'] > $this->getVarcharMaxLength()) { + return $this->getClobTypeDeclarationSQL($field); + } else { + return $this->getVarcharTypeDeclarationSQLSnippet($field['length'], $fixed); + } + } + + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) + { + throw DBALException::notSupported('VARCHARs not supported by Platform.'); + } + + /** + * Gets the SQL snippet used to declare a CLOB column type. + * + * @param array $field + */ + abstract public function getClobTypeDeclarationSQL(array $field); + + /** + * Gets the SQL Snippet used to declare a BLOB column type. + */ + abstract public function getBlobTypeDeclarationSQL(array $field); + + /** + * Gets the name of the platform. + * + * @return string + */ + abstract public function getName(); + + /** + * Register a doctrine type to be used in conjunction with a column type of this platform. + * + * @param string $dbType + * @param string $doctrineType + */ + public function registerDoctrineTypeMapping($dbType, $doctrineType) + { + if ($this->doctrineTypeMapping === null) { + $this->initializeDoctrineTypeMappings(); + } + + if (!Types\Type::hasType($doctrineType)) { + throw DBALException::typeNotFound($doctrineType); + } + + $dbType = strtolower($dbType); + $this->doctrineTypeMapping[$dbType] = $doctrineType; + } + + /** + * Get the Doctrine type that is mapped for the given database column type. + * + * @param string $dbType + * @return string + */ + public function getDoctrineTypeMapping($dbType) + { + if ($this->doctrineTypeMapping === null) { + $this->initializeDoctrineTypeMappings(); + } + + $dbType = strtolower($dbType); + if (isset($this->doctrineTypeMapping[$dbType])) { + return $this->doctrineTypeMapping[$dbType]; + } else { + throw new \Doctrine\DBAL\DBALException("Unknown database type ".$dbType." requested, " . get_class($this) . " may not support it."); + } + } + + /** + * Check if a database type is currently supported by this platform. + * + * @param string $dbType + * @return bool + */ + public function hasDoctrineTypeMappingFor($dbType) + { + if ($this->doctrineTypeMapping === null) { + $this->initializeDoctrineTypeMappings(); + } + + $dbType = strtolower($dbType); + return isset($this->doctrineTypeMapping[$dbType]); + } + + /** + * Initialize the Doctrine Type comments instance variable for in_array() checks. + * + * @return void + */ + protected function initializeCommentedDoctrineTypes() + { + $this->doctrineTypeComments = array(Type::TARRAY, Type::OBJECT); + } + + /** + * Is it necessary for the platform to add a parsable type comment to allow reverse engineering the given type? + * + * @param Type $doctrineType + * @return bool + */ + public function isCommentedDoctrineType(Type $doctrineType) + { + if ($this->doctrineTypeComments === null) { + $this->initializeCommentedDoctrineTypes(); + } + + return in_array($doctrineType->getName(), $this->doctrineTypeComments); + } + + /** + * Mark this type as to be commented in ALTER TABLE and CREATE TABLE statements. + * + * @param Type $doctrineType + * @return void + */ + public function markDoctrineTypeCommented(Type $doctrineType) + { + if ($this->doctrineTypeComments === null) { + $this->initializeCommentedDoctrineTypes(); + } + $this->doctrineTypeComments[] = $doctrineType->getName(); + } + + /** + * Get the comment to append to a column comment that helps parsing this type in reverse engineering. + * + * @param Type $doctrineType + * @return string + */ + public function getDoctrineTypeComment(Type $doctrineType) + { + return '(DC2Type:' . $doctrineType->getName() . ')'; + } + + /** + * Return the comment of a passed column modified by potential doctrine type comment hints. + * + * @param Column $column + * @return string + */ + protected function getColumnComment(Column $column) + { + $comment = $column->getComment(); + if ($this->isCommentedDoctrineType($column->getType())) { + $comment .= $this->getDoctrineTypeComment($column->getType()); + } + return $comment; + } + + /** + * Gets the character used for identifier quoting. + * + * @return string + */ + public function getIdentifierQuoteCharacter() + { + return '"'; + } + + /** + * Gets the string portion that starts an SQL comment. + * + * @return string + */ + public function getSqlCommentStartString() + { + return "--"; + } + + /** + * Gets the string portion that ends an SQL comment. + * + * @return string + */ + public function getSqlCommentEndString() + { + return "\n"; + } + + /** + * Gets the maximum length of a varchar field. + * + * @return integer + */ + public function getVarcharMaxLength() + { + return 4000; + } + + /** + * Gets the default length of a varchar field. + * + * @return integer + */ + public function getVarcharDefaultLength() + { + return 255; + } + + /** + * Gets all SQL wildcard characters of the platform. + * + * @return array + */ + public function getWildcards() + { + return array('%', '_'); + } + + /** + * Returns the regular expression operator. + * + * @return string + */ + public function getRegexpExpression() + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Returns global unique identifier + * + * @return string to get global unique identifier + */ + public function getGuidExpression() + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Returns the average value of a column + * + * @param string $column the column to use + * @return string generated sql including an AVG aggregate function + */ + public function getAvgExpression($column) + { + return 'AVG(' . $column . ')'; + } + + /** + * Returns the number of rows (without a NULL value) of a column + * + * If a '*' is used instead of a column the number of selected rows + * is returned. + * + * @param string|integer $column the column to use + * @return string generated sql including a COUNT aggregate function + */ + public function getCountExpression($column) + { + return 'COUNT(' . $column . ')'; + } + + /** + * Returns the highest value of a column + * + * @param string $column the column to use + * @return string generated sql including a MAX aggregate function + */ + public function getMaxExpression($column) + { + return 'MAX(' . $column . ')'; + } + + /** + * Returns the lowest value of a column + * + * @param string $column the column to use + * @return string + */ + public function getMinExpression($column) + { + return 'MIN(' . $column . ')'; + } + + /** + * Returns the total sum of a column + * + * @param string $column the column to use + * @return string + */ + public function getSumExpression($column) + { + return 'SUM(' . $column . ')'; + } + + // scalar functions + + /** + * Returns the md5 sum of a field. + * + * Note: Not SQL92, but common functionality + * + * @return string + */ + public function getMd5Expression($column) + { + return 'MD5(' . $column . ')'; + } + + /** + * Returns the length of a text field. + * + * @param string $expression1 + * @param string $expression2 + * @return string + */ + public function getLengthExpression($column) + { + return 'LENGTH(' . $column . ')'; + } + + /** + * Rounds a numeric field to the number of decimals specified. + * + * @param string $expression1 + * @param string $expression2 + * @return string + */ + public function getRoundExpression($column, $decimals = 0) + { + return 'ROUND(' . $column . ', ' . $decimals . ')'; + } + + /** + * Returns the remainder of the division operation + * $expression1 / $expression2. + * + * @param string $expression1 + * @param string $expression2 + * @return string + */ + public function getModExpression($expression1, $expression2) + { + return 'MOD(' . $expression1 . ', ' . $expression2 . ')'; + } + + /** + * Trim a string, leading/trailing/both and with a given char which defaults to space. + * + * @param string $str + * @param int $pos + * @param string $char has to be quoted already + * @return string + */ + public function getTrimExpression($str, $pos = self::TRIM_UNSPECIFIED, $char = false) + { + $posStr = ''; + $trimChar = ($char != false) ? $char . ' FROM ' : ''; + + if ($pos == self::TRIM_LEADING) { + $posStr = 'LEADING '.$trimChar; + } else if($pos == self::TRIM_TRAILING) { + $posStr = 'TRAILING '.$trimChar; + } else if($pos == self::TRIM_BOTH) { + $posStr = 'BOTH '.$trimChar; + } + + return 'TRIM(' . $posStr . $str . ')'; + } + + /** + * rtrim + * returns the string $str with proceeding space characters removed + * + * @param string $str literal string or column name + * @return string + */ + public function getRtrimExpression($str) + { + return 'RTRIM(' . $str . ')'; + } + + /** + * ltrim + * returns the string $str with leading space characters removed + * + * @param string $str literal string or column name + * @return string + */ + public function getLtrimExpression($str) + { + return 'LTRIM(' . $str . ')'; + } + + /** + * upper + * Returns the string $str with all characters changed to + * uppercase according to the current character set mapping. + * + * @param string $str literal string or column name + * @return string + */ + public function getUpperExpression($str) + { + return 'UPPER(' . $str . ')'; + } + + /** + * lower + * Returns the string $str with all characters changed to + * lowercase according to the current character set mapping. + * + * @param string $str literal string or column name + * @return string + */ + public function getLowerExpression($str) + { + return 'LOWER(' . $str . ')'; + } + + /** + * returns the position of the first occurrence of substring $substr in string $str + * + * @param string $substr literal string to find + * @param string $str literal string + * @param int $pos position to start at, beginning of string by default + * @return integer + */ + public function getLocateExpression($str, $substr, $startPos = false) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Returns the current system date. + * + * @return string + */ + public function getNowExpression() + { + return 'NOW()'; + } + + /** + * return string to call a function to get a substring inside an SQL statement + * + * Note: Not SQL92, but common functionality. + * + * SQLite only supports the 2 parameter variant of this function + * + * @param string $value an sql string literal or column name/alias + * @param integer $from where to start the substring portion + * @param integer $len the substring portion length + * @return string + */ + public function getSubstringExpression($value, $from, $len = null) + { + if ($len === null) + return 'SUBSTRING(' . $value . ' FROM ' . $from . ')'; + else { + return 'SUBSTRING(' . $value . ' FROM ' . $from . ' FOR ' . $len . ')'; + } + } + + /** + * Returns a series of strings concatinated + * + * concat() accepts an arbitrary number of parameters. Each parameter + * must contain an expression + * + * @param string $arg1, $arg2 ... $argN strings that will be concatinated. + * @return string + */ + public function getConcatExpression() + { + return join(' || ' , func_get_args()); + } + + /** + * Returns the SQL for a logical not. + * + * Example: + * + * $q = new Doctrine_Query(); + * $e = $q->expr; + * $q->select('*')->from('table') + * ->where($e->eq('id', $e->not('null')); + * + * + * @return string a logical expression + */ + public function getNotExpression($expression) + { + return 'NOT(' . $expression . ')'; + } + + /** + * Returns the SQL to check if a value is one in a set of + * given values. + * + * in() accepts an arbitrary number of parameters. The first parameter + * must always specify the value that should be matched against. Successive + * must contain a logical expression or an array with logical expressions. + * These expressions will be matched against the first parameter. + * + * @param string $column the value that should be matched against + * @param string|array(string) values that will be matched against $column + * @return string logical expression + */ + public function getInExpression($column, $values) + { + if ( ! is_array($values)) { + $values = array($values); + } + $values = $this->getIdentifiers($values); + + if (count($values) == 0) { + throw \InvalidArgumentException('Values must not be empty.'); + } + return $column . ' IN (' . implode(', ', $values) . ')'; + } + + /** + * Returns SQL that checks if a expression is null. + * + * @param string $expression the expression that should be compared to null + * @return string logical expression + */ + public function getIsNullExpression($expression) + { + return $expression . ' IS NULL'; + } + + /** + * Returns SQL that checks if a expression is not null. + * + * @param string $expression the expression that should be compared to null + * @return string logical expression + */ + public function getIsNotNullExpression($expression) + { + return $expression . ' IS NOT NULL'; + } + + /** + * Returns SQL that checks if an expression evaluates to a value between + * two values. + * + * The parameter $expression is checked if it is between $value1 and $value2. + * + * Note: There is a slight difference in the way BETWEEN works on some databases. + * http://www.w3schools.com/sql/sql_between.asp. If you want complete database + * independence you should avoid using between(). + * + * @param string $expression the value to compare to + * @param string $value1 the lower value to compare with + * @param string $value2 the higher value to compare with + * @return string logical expression + */ + public function getBetweenExpression($expression, $value1, $value2) + { + return $expression . ' BETWEEN ' .$value1 . ' AND ' . $value2; + } + + public function getAcosExpression($value) + { + return 'ACOS(' . $value . ')'; + } + + public function getSinExpression($value) + { + return 'SIN(' . $value . ')'; + } + + public function getPiExpression() + { + return 'PI()'; + } + + public function getCosExpression($value) + { + return 'COS(' . $value . ')'; + } + + /** + * Calculate the difference in days between the two passed dates. + * + * Computes diff = date1 - date2 + * + * @param string $date1 + * @param string $date2 + * @return string + */ + public function getDateDiffExpression($date1, $date2) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Add the number of given days to a date. + * + * @param string $date + * @param int $days + * @return string + */ + public function getDateAddDaysExpression($date, $days) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Substract the number of given days to a date. + * + * @param string $date + * @param int $days + * @return string + */ + public function getDateSubDaysExpression($date, $days) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Add the number of given months to a date. + * + * @param string $date + * @param int $months + * @return string + */ + public function getDateAddMonthExpression($date, $months) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Substract the number of given months to a date. + * + * @param string $date + * @param int $months + * @return string + */ + public function getDateSubMonthExpression($date, $months) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Gets SQL bit AND comparison expression + * + * @param string $value1 + * @param string $value2 + * @return string + */ + public function getBitAndComparisonExpression($value1, $value2) + { + return '(' . $value1 . ' & ' . $value2 . ')'; + } + + /** + * Gets SQL bit OR comparison expression + * + * @param string $value1 + * @param string $value2 + * @return string + */ + public function getBitOrComparisonExpression($value1, $value2) + { + return '(' . $value1 . ' | ' . $value2 . ')'; + } + + public function getForUpdateSQL() + { + return 'FOR UPDATE'; + } + + /** + * Honors that some SQL vendors such as MsSql use table hints for locking instead of the ANSI SQL FOR UPDATE specification. + * + * @param string $fromClause + * @param int $lockMode + * @return string + */ + public function appendLockHint($fromClause, $lockMode) + { + return $fromClause; + } + + /** + * Get the sql snippet to append to any SELECT statement which locks rows in shared read lock. + * + * This defaults to the ASNI SQL "FOR UPDATE", which is an exclusive lock (Write). Some database + * vendors allow to lighten this constraint up to be a real read lock. + * + * @return string + */ + public function getReadLockSQL() + { + return $this->getForUpdateSQL(); + } + + /** + * Get the SQL snippet to append to any SELECT statement which obtains an exclusive lock on the rows. + * + * The semantics of this lock mode should equal the SELECT .. FOR UPDATE of the ASNI SQL standard. + * + * @return string + */ + public function getWriteLockSQL() + { + return $this->getForUpdateSQL(); + } + + public function getDropDatabaseSQL($database) + { + return 'DROP DATABASE ' . $database; + } + + /** + * Drop a Table + * + * @throws \InvalidArgumentException + * @param Table|string $table + * @return string + */ + public function getDropTableSQL($table) + { + $tableArg = $table; + + if ($table instanceof \Doctrine\DBAL\Schema\Table) { + $table = $table->getQuotedName($this); + } else if(!is_string($table)) { + throw new \InvalidArgumentException('getDropTableSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.'); + } + + if (null !== $this->_eventManager && $this->_eventManager->hasListeners(Events::onSchemaDropTable)) { + $eventArgs = new SchemaDropTableEventArgs($tableArg, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaDropTable, $eventArgs); + + if ($eventArgs->isDefaultPrevented()) { + return $eventArgs->getSql(); + } + } + + return 'DROP TABLE ' . $table; + } + + /** + * Get SQL to safely drop a temporary table WITHOUT implicitly committing an open transaction. + * + * @param Table|string $table + * @return string + */ + public function getDropTemporaryTableSQL($table) + { + return $this->getDropTableSQL($table); + } + + /** + * Drop index from a table + * + * @param Index|string $name + * @param string|Table $table + * @return string + */ + public function getDropIndexSQL($index, $table=null) + { + if($index instanceof \Doctrine\DBAL\Schema\Index) { + $index = $index->getQuotedName($this); + } else if(!is_string($index)) { + throw new \InvalidArgumentException('AbstractPlatform::getDropIndexSQL() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.'); + } + + return 'DROP INDEX ' . $index; + } + + /** + * Get drop constraint sql + * + * @param \Doctrine\DBAL\Schema\Constraint $constraint + * @param string|Table $table + * @return string + */ + public function getDropConstraintSQL($constraint, $table) + { + if ($constraint instanceof \Doctrine\DBAL\Schema\Constraint) { + $constraint = $constraint->getQuotedName($this); + } + + if ($table instanceof \Doctrine\DBAL\Schema\Table) { + $table = $table->getQuotedName($this); + } + + return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $constraint; + } + + /** + * @param ForeignKeyConstraint|string $foreignKey + * @param Table|string $table + * @return string + */ + public function getDropForeignKeySQL($foreignKey, $table) + { + if ($foreignKey instanceof \Doctrine\DBAL\Schema\ForeignKeyConstraint) { + $foreignKey = $foreignKey->getQuotedName($this); + } + + if ($table instanceof \Doctrine\DBAL\Schema\Table) { + $table = $table->getQuotedName($this); + } + + return 'ALTER TABLE ' . $table . ' DROP FOREIGN KEY ' . $foreignKey; + } + + /** + * Gets the SQL statement(s) to create a table with the specified name, columns and constraints + * on this platform. + * + * @param string $table The name of the table. + * @param int $createFlags + * @return array The sequence of SQL statements. + */ + public function getCreateTableSQL(Table $table, $createFlags=self::CREATE_INDEXES) + { + if ( ! is_int($createFlags)) { + throw new \InvalidArgumentException("Second argument of AbstractPlatform::getCreateTableSQL() has to be integer."); + } + + if (count($table->getColumns()) == 0) { + throw DBALException::noColumnsSpecifiedForTable($table->getName()); + } + + $tableName = $table->getQuotedName($this); + $options = $table->getOptions(); + $options['uniqueConstraints'] = array(); + $options['indexes'] = array(); + $options['primary'] = array(); + + if (($createFlags&self::CREATE_INDEXES) > 0) { + foreach ($table->getIndexes() AS $index) { + /* @var $index Index */ + if ($index->isPrimary()) { + $options['primary'] = $index->getColumns(); + } else { + $options['indexes'][$index->getName()] = $index; + } + } + } + + $columnSql = array(); + $columns = array(); + foreach ($table->getColumns() AS $column) { + /* @var \Doctrine\DBAL\Schema\Column $column */ + + if (null !== $this->_eventManager && $this->_eventManager->hasListeners(Events::onSchemaCreateTableColumn)) { + $eventArgs = new SchemaCreateTableColumnEventArgs($column, $table, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaCreateTableColumn, $eventArgs); + + $columnSql = array_merge($columnSql, $eventArgs->getSql()); + + if ($eventArgs->isDefaultPrevented()) { + continue; + } + } + + $columnData = array(); + $columnData['name'] = $column->getQuotedName($this); + $columnData['type'] = $column->getType(); + $columnData['length'] = $column->getLength(); + $columnData['notnull'] = $column->getNotNull(); + $columnData['fixed'] = $column->getFixed(); + $columnData['unique'] = false; // TODO: what do we do about this? + $columnData['version'] = ($column->hasPlatformOption("version"))?$column->getPlatformOption('version'):false; + if(strtolower($columnData['type']) == "string" && $columnData['length'] === null) { + $columnData['length'] = 255; + } + $columnData['unsigned'] = $column->getUnsigned(); + $columnData['precision'] = $column->getPrecision(); + $columnData['scale'] = $column->getScale(); + $columnData['default'] = $column->getDefault(); + $columnData['columnDefinition'] = $column->getColumnDefinition(); + $columnData['autoincrement'] = $column->getAutoincrement(); + $columnData['comment'] = $this->getColumnComment($column); + + if(in_array($column->getName(), $options['primary'])) { + $columnData['primary'] = true; + } + + $columns[$columnData['name']] = $columnData; + } + + if (($createFlags&self::CREATE_FOREIGNKEYS) > 0) { + $options['foreignKeys'] = array(); + foreach ($table->getForeignKeys() AS $fkConstraint) { + $options['foreignKeys'][] = $fkConstraint; + } + } + + if (null !== $this->_eventManager && $this->_eventManager->hasListeners(Events::onSchemaCreateTable)) { + $eventArgs = new SchemaCreateTableEventArgs($table, $columns, $options, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaCreateTable, $eventArgs); + + if ($eventArgs->isDefaultPrevented()) { + return array_merge($eventArgs->getSql(), $columnSql); + } + } + + $sql = $this->_getCreateTableSQL($tableName, $columns, $options); + if ($this->supportsCommentOnStatement()) { + foreach ($table->getColumns() AS $column) { + if ($this->getColumnComment($column)) { + $sql[] = $this->getCommentOnColumnSQL($tableName, $column->getName(), $this->getColumnComment($column)); + } + } + } + + return array_merge($sql, $columnSql); + } + + public function getCommentOnColumnSQL($tableName, $columnName, $comment) + { + return "COMMENT ON COLUMN " . $tableName . "." . $columnName . " IS '" . $comment . "'"; + } + + /** + * @param string $tableName + * @param array $columns + * @param array $options + * @return array + */ + protected function _getCreateTableSQL($tableName, array $columns, array $options = array()) + { + $columnListSql = $this->getColumnDeclarationListSQL($columns); + + if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) { + foreach ($options['uniqueConstraints'] as $name => $definition) { + $columnListSql .= ', ' . $this->getUniqueConstraintDeclarationSQL($name, $definition); + } + } + + if (isset($options['primary']) && ! empty($options['primary'])) { + $columnListSql .= ', PRIMARY KEY(' . implode(', ', array_unique(array_values($options['primary']))) . ')'; + } + + if (isset($options['indexes']) && ! empty($options['indexes'])) { + foreach($options['indexes'] as $index => $definition) { + $columnListSql .= ', ' . $this->getIndexDeclarationSQL($index, $definition); + } + } + + $query = 'CREATE TABLE ' . $tableName . ' (' . $columnListSql; + + $check = $this->getCheckDeclarationSQL($columns); + if ( ! empty($check)) { + $query .= ', ' . $check; + } + $query .= ')'; + + $sql[] = $query; + + if (isset($options['foreignKeys'])) { + foreach ((array) $options['foreignKeys'] AS $definition) { + $sql[] = $this->getCreateForeignKeySQL($definition, $tableName); + } + } + + return $sql; + } + + public function getCreateTemporaryTableSnippetSQL() + { + return "CREATE TEMPORARY TABLE"; + } + + /** + * Gets the SQL to create a sequence on this platform. + * + * @param \Doctrine\DBAL\Schema\Sequence $sequence + * @throws DBALException + */ + public function getCreateSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Gets the SQL statement to change a sequence on this platform. + * + * @param \Doctrine\DBAL\Schema\Sequence $sequence + * @return string + */ + public function getAlterSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Gets the SQL to create a constraint on a table on this platform. + * + * @param Constraint $constraint + * @param string|Table $table + * @return string + */ + public function getCreateConstraintSQL(\Doctrine\DBAL\Schema\Constraint $constraint, $table) + { + if ($table instanceof \Doctrine\DBAL\Schema\Table) { + $table = $table->getQuotedName($this); + } + + $query = 'ALTER TABLE ' . $table . ' ADD CONSTRAINT ' . $constraint->getQuotedName($this); + + $columns = array(); + foreach ($constraint->getColumns() as $column) { + $columns[] = $column; + } + $columnList = '('. implode(', ', $columns) . ')'; + + $referencesClause = ''; + if ($constraint instanceof \Doctrine\DBAL\Schema\Index) { + if($constraint->isPrimary()) { + $query .= ' PRIMARY KEY'; + } elseif ($constraint->isUnique()) { + $query .= ' UNIQUE'; + } else { + throw new \InvalidArgumentException( + 'Can only create primary or unique constraints, no common indexes with getCreateConstraintSQL().' + ); + } + } else if ($constraint instanceof \Doctrine\DBAL\Schema\ForeignKeyConstraint) { + $query .= ' FOREIGN KEY'; + + $foreignColumns = array(); + foreach ($constraint->getForeignColumns() AS $column) { + $foreignColumns[] = $column; + } + + $referencesClause = ' REFERENCES '.$constraint->getForeignTableName(). ' ('.implode(', ', $foreignColumns).')'; + } + $query .= ' '.$columnList.$referencesClause; + + return $query; + } + + /** + * Gets the SQL to create an index on a table on this platform. + * + * @param Index $index + * @param string|Table $table name of the table on which the index is to be created + * @return string + */ + public function getCreateIndexSQL(Index $index, $table) + { + if ($table instanceof Table) { + $table = $table->getQuotedName($this); + } + $name = $index->getQuotedName($this); + $columns = $index->getColumns(); + + if (count($columns) == 0) { + throw new \InvalidArgumentException("Incomplete definition. 'columns' required."); + } + + if ($index->isPrimary()) { + return $this->getCreatePrimaryKeySQL($index, $table); + } else { + $type = ''; + if ($index->isUnique()) { + $type = 'UNIQUE '; + } + + $query = 'CREATE ' . $type . 'INDEX ' . $name . ' ON ' . $table; + $query .= ' (' . $this->getIndexFieldDeclarationListSQL($columns) . ')'; + } + + return $query; + } + + /** + * Get SQL to create an unnamed primary key constraint. + * + * @param Index $index + * @param string|Table $table + * @return string + */ + public function getCreatePrimaryKeySQL(Index $index, $table) + { + return 'ALTER TABLE ' . $table . ' ADD PRIMARY KEY (' . $this->getIndexFieldDeclarationListSQL($index->getColumns()) . ')'; + } + + /** + * Quotes a string so that it can be safely used as a table or column name, + * even if it is a reserved word of the platform. This also detects identifier + * chains seperated by dot and quotes them independently. + * + * NOTE: Just because you CAN use quoted identifiers doesn't mean + * you SHOULD use them. In general, they end up causing way more + * problems than they solve. + * + * @param string $str identifier name to be quoted + * @return string quoted identifier string + */ + public function quoteIdentifier($str) + { + if (strpos($str, ".") !== false) { + $parts = array_map(array($this, "quoteIdentifier"), explode(".", $str)); + return implode(".", $parts); + } + + return $this->quoteSingleIdentifier($str); + } + + /** + * Quote a single identifier (no dot chain seperation) + * + * @param string $str + * @return string + */ + public function quoteSingleIdentifier($str) + { + $c = $this->getIdentifierQuoteCharacter(); + + return $c . str_replace($c, $c.$c, $str) . $c; + } + + /** + * Create a new foreign key + * + * @param ForeignKeyConstraint $foreignKey ForeignKey instance + * @param string|Table $table name of the table on which the foreign key is to be created + * @return string + */ + public function getCreateForeignKeySQL(ForeignKeyConstraint $foreignKey, $table) + { + if ($table instanceof \Doctrine\DBAL\Schema\Table) { + $table = $table->getQuotedName($this); + } + + $query = 'ALTER TABLE ' . $table . ' ADD ' . $this->getForeignKeyDeclarationSQL($foreignKey); + + return $query; + } + + /** + * Gets the sql statements for altering an existing table. + * + * The method returns an array of sql statements, since some platforms need several statements. + * + * @param TableDiff $diff + * @return array + */ + public function getAlterTableSQL(TableDiff $diff) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * @param Column $column + * @param TableDiff $diff + * @param array $columnSql + */ + protected function onSchemaAlterTableAddColumn(Column $column, TableDiff $diff, &$columnSql) + { + if (null === $this->_eventManager) { + return false; + } + + if (!$this->_eventManager->hasListeners(Events::onSchemaAlterTableAddColumn)) { + return false; + } + + $eventArgs = new SchemaAlterTableAddColumnEventArgs($column, $diff, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaAlterTableAddColumn, $eventArgs); + + $columnSql = array_merge($columnSql, $eventArgs->getSql()); + + return $eventArgs->isDefaultPrevented(); + } + + /** + * @param Column $column + * @param TableDiff $diff + * @param array $columnSql + */ + protected function onSchemaAlterTableRemoveColumn(Column $column, TableDiff $diff, &$columnSql) + { + if (null === $this->_eventManager) { + return false; + } + + if (!$this->_eventManager->hasListeners(Events::onSchemaAlterTableRemoveColumn)) { + return false; + } + + $eventArgs = new SchemaAlterTableRemoveColumnEventArgs($column, $diff, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaAlterTableRemoveColumn, $eventArgs); + + $columnSql = array_merge($columnSql, $eventArgs->getSql()); + + return $eventArgs->isDefaultPrevented(); + } + + /** + * @param ColumnDiff $columnDiff + * @param TableDiff $diff + * @param array $columnSql + */ + protected function onSchemaAlterTableChangeColumn(ColumnDiff $columnDiff, TableDiff $diff, &$columnSql) + { + if (null === $this->_eventManager) { + return false; + } + + if (!$this->_eventManager->hasListeners(Events::onSchemaAlterTableChangeColumn)) { + return false; + } + + $eventArgs = new SchemaAlterTableChangeColumnEventArgs($columnDiff, $diff, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaAlterTableChangeColumn, $eventArgs); + + $columnSql = array_merge($columnSql, $eventArgs->getSql()); + + return $eventArgs->isDefaultPrevented(); + } + + /** + * @param string $oldColumnName + * @param Column $column + * @param TableDiff $diff + * @param array $columnSql + */ + protected function onSchemaAlterTableRenameColumn($oldColumnName, Column $column, TableDiff $diff, &$columnSql) + { + if (null === $this->_eventManager) { + return false; + } + + if (!$this->_eventManager->hasListeners(Events::onSchemaAlterTableRenameColumn)) { + return false; + } + + $eventArgs = new SchemaAlterTableRenameColumnEventArgs($oldColumnName, $column, $diff, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaAlterTableRenameColumn, $eventArgs); + + $columnSql = array_merge($columnSql, $eventArgs->getSql()); + + return $eventArgs->isDefaultPrevented(); + } + /** + * @param TableDiff $diff + * @param array $columnSql + */ + protected function onSchemaAlterTable(TableDiff $diff, &$sql) + { + if (null === $this->_eventManager) { + return false; + } + + if (!$this->_eventManager->hasListeners(Events::onSchemaAlterTable)) { + return false; + } + + $eventArgs = new SchemaAlterTableEventArgs($diff, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaAlterTable, $eventArgs); + + $sql = array_merge($sql, $eventArgs->getSql()); + + return $eventArgs->isDefaultPrevented(); + } + + protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff) + { + $tableName = $diff->name; + + $sql = array(); + if ($this->supportsForeignKeyConstraints()) { + foreach ($diff->removedForeignKeys AS $foreignKey) { + $sql[] = $this->getDropForeignKeySQL($foreignKey, $tableName); + } + foreach ($diff->changedForeignKeys AS $foreignKey) { + $sql[] = $this->getDropForeignKeySQL($foreignKey, $tableName); + } + } + + foreach ($diff->removedIndexes AS $index) { + $sql[] = $this->getDropIndexSQL($index, $tableName); + } + foreach ($diff->changedIndexes AS $index) { + $sql[] = $this->getDropIndexSQL($index, $tableName); + } + + return $sql; + } + + protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff) + { + if ($diff->newName !== false) { + $tableName = $diff->newName; + } else { + $tableName = $diff->name; + } + + $sql = array(); + if ($this->supportsForeignKeyConstraints()) { + foreach ($diff->addedForeignKeys AS $foreignKey) { + $sql[] = $this->getCreateForeignKeySQL($foreignKey, $tableName); + } + foreach ($diff->changedForeignKeys AS $foreignKey) { + $sql[] = $this->getCreateForeignKeySQL($foreignKey, $tableName); + } + } + + foreach ($diff->addedIndexes AS $index) { + $sql[] = $this->getCreateIndexSQL($index, $tableName); + } + foreach ($diff->changedIndexes AS $index) { + $sql[] = $this->getCreateIndexSQL($index, $tableName); + } + + return $sql; + } + + /** + * Common code for alter table statement generation that updates the changed Index and Foreign Key definitions. + * + * @param TableDiff $diff + * @return array + */ + protected function _getAlterTableIndexForeignKeySQL(TableDiff $diff) + { + return array_merge($this->getPreAlterTableIndexForeignKeySQL($diff), $this->getPostAlterTableIndexForeignKeySQL($diff)); + } + + /** + * Get declaration of a number of fields in bulk + * + * @param array $fields a multidimensional associative array. + * The first dimension determines the field name, while the second + * dimension is keyed with the name of the properties + * of the field being declared as array indexes. Currently, the types + * of supported field properties are as follows: + * + * length + * Integer value that determines the maximum length of the text + * field. If this argument is missing the field should be + * declared to have the longest length allowed by the DBMS. + * + * default + * Text value to be used as default for this field. + * + * notnull + * Boolean flag that indicates whether this field is constrained + * to not be set to null. + * charset + * Text value with the default CHARACTER SET for this field. + * collation + * Text value with the default COLLATION for this field. + * unique + * unique constraint + * + * @return string + */ + public function getColumnDeclarationListSQL(array $fields) + { + $queryFields = array(); + foreach ($fields as $fieldName => $field) { + $query = $this->getColumnDeclarationSQL($fieldName, $field); + $queryFields[] = $query; + } + return implode(', ', $queryFields); + } + + /** + * Obtain DBMS specific SQL code portion needed to declare a generic type + * field to be used in statements like CREATE TABLE. + * + * @param string $name name the field to be declared. + * @param array $field associative array with the name of the properties + * of the field being declared as array indexes. Currently, the types + * of supported field properties are as follows: + * + * length + * Integer value that determines the maximum length of the text + * field. If this argument is missing the field should be + * declared to have the longest length allowed by the DBMS. + * + * default + * Text value to be used as default for this field. + * + * notnull + * Boolean flag that indicates whether this field is constrained + * to not be set to null. + * charset + * Text value with the default CHARACTER SET for this field. + * collation + * Text value with the default COLLATION for this field. + * unique + * unique constraint + * check + * column check constraint + * columnDefinition + * a string that defines the complete column + * + * @return string DBMS specific SQL code portion that should be used to declare the column. + */ + public function getColumnDeclarationSQL($name, array $field) + { + if (isset($field['columnDefinition'])) { + $columnDef = $this->getCustomTypeDeclarationSQL($field); + } else { + $default = $this->getDefaultValueDeclarationSQL($field); + + $charset = (isset($field['charset']) && $field['charset']) ? + ' ' . $this->getColumnCharsetDeclarationSQL($field['charset']) : ''; + + $collation = (isset($field['collation']) && $field['collation']) ? + ' ' . $this->getColumnCollationDeclarationSQL($field['collation']) : ''; + + $notnull = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : ''; + + $unique = (isset($field['unique']) && $field['unique']) ? + ' ' . $this->getUniqueFieldDeclarationSQL() : ''; + + $check = (isset($field['check']) && $field['check']) ? + ' ' . $field['check'] : ''; + + $typeDecl = $field['type']->getSqlDeclaration($field, $this); + $columnDef = $typeDecl . $charset . $default . $notnull . $unique . $check . $collation; + } + + if ($this->supportsInlineColumnComments() && isset($field['comment']) && $field['comment']) { + $columnDef .= " COMMENT '" . $field['comment'] . "'"; + } + + return $name . ' ' . $columnDef; + } + + /** + * Gets the SQL snippet that declares a floating point column of arbitrary precision. + * + * @param array $columnDef + * @return string + */ + public function getDecimalTypeDeclarationSQL(array $columnDef) + { + $columnDef['precision'] = ( ! isset($columnDef['precision']) || empty($columnDef['precision'])) + ? 10 : $columnDef['precision']; + $columnDef['scale'] = ( ! isset($columnDef['scale']) || empty($columnDef['scale'])) + ? 0 : $columnDef['scale']; + + return 'NUMERIC(' . $columnDef['precision'] . ', ' . $columnDef['scale'] . ')'; + } + + /** + * Obtain DBMS specific SQL code portion needed to set a default value + * declaration to be used in statements like CREATE TABLE. + * + * @param array $field field definition array + * @return string DBMS specific SQL code portion needed to set a default value + */ + public function getDefaultValueDeclarationSQL($field) + { + $default = empty($field['notnull']) ? ' DEFAULT NULL' : ''; + + if (isset($field['default'])) { + $default = " DEFAULT '".$field['default']."'"; + if (isset($field['type'])) { + if (in_array((string)$field['type'], array("Integer", "BigInteger", "SmallInteger"))) { + $default = " DEFAULT ".$field['default']; + } else if ((string)$field['type'] == 'DateTime' && $field['default'] == $this->getCurrentTimestampSQL()) { + $default = " DEFAULT ".$this->getCurrentTimestampSQL(); + + } else if ((string) $field['type'] == 'Boolean') { + $default = " DEFAULT '" . $this->convertBooleans($field['default']) . "'"; + } + } + } + return $default; + } + + /** + * Obtain DBMS specific SQL code portion needed to set a CHECK constraint + * declaration to be used in statements like CREATE TABLE. + * + * @param array $definition check definition + * @return string DBMS specific SQL code portion needed to set a CHECK constraint + */ + public function getCheckDeclarationSQL(array $definition) + { + $constraints = array(); + foreach ($definition as $field => $def) { + if (is_string($def)) { + $constraints[] = 'CHECK (' . $def . ')'; + } else { + if (isset($def['min'])) { + $constraints[] = 'CHECK (' . $field . ' >= ' . $def['min'] . ')'; + } + + if (isset($def['max'])) { + $constraints[] = 'CHECK (' . $field . ' <= ' . $def['max'] . ')'; + } + } + } + + return implode(', ', $constraints); + } + + /** + * Obtain DBMS specific SQL code portion needed to set a unique + * constraint declaration to be used in statements like CREATE TABLE. + * + * @param string $name name of the unique constraint + * @param Index $index index definition + * @return string DBMS specific SQL code portion needed + * to set a constraint + */ + public function getUniqueConstraintDeclarationSQL($name, Index $index) + { + if (count($index->getColumns()) == 0) { + throw \InvalidArgumentException("Incomplete definition. 'columns' required."); + } + + return 'CONSTRAINT ' . $name . ' UNIQUE (' + . $this->getIndexFieldDeclarationListSQL($index->getColumns()) + . ')'; + } + + /** + * Obtain DBMS specific SQL code portion needed to set an index + * declaration to be used in statements like CREATE TABLE. + * + * @param string $name name of the index + * @param Index $index index definition + * @return string DBMS specific SQL code portion needed to set an index + */ + public function getIndexDeclarationSQL($name, Index $index) + { + $type = ''; + + if($index->isUnique()) { + $type = 'UNIQUE '; + } + + if (count($index->getColumns()) == 0) { + throw \InvalidArgumentException("Incomplete definition. 'columns' required."); + } + + return $type . 'INDEX ' . $name . ' (' + . $this->getIndexFieldDeclarationListSQL($index->getColumns()) + . ')'; + } + + /** + * getCustomTypeDeclarationSql + * Obtail SQL code portion needed to create a custom column, + * e.g. when a field has the "columnDefinition" keyword. + * Only "AUTOINCREMENT" and "PRIMARY KEY" are added if appropriate. + * + * @return string + */ + public function getCustomTypeDeclarationSQL(array $columnDef) + { + return $columnDef['columnDefinition']; + } + + /** + * getIndexFieldDeclarationList + * Obtain DBMS specific SQL code portion needed to set an index + * declaration to be used in statements like CREATE TABLE. + * + * @return string + */ + public function getIndexFieldDeclarationListSQL(array $fields) + { + $ret = array(); + foreach ($fields as $field => $definition) { + if (is_array($definition)) { + $ret[] = $field; + } else { + $ret[] = $definition; + } + } + return implode(', ', $ret); + } + + /** + * A method to return the required SQL string that fits between CREATE ... TABLE + * to create the table as a temporary table. + * + * Should be overridden in driver classes to return the correct string for the + * specific database type. + * + * The default is to return the string "TEMPORARY" - this will result in a + * SQL error for any database that does not support temporary tables, or that + * requires a different SQL command from "CREATE TEMPORARY TABLE". + * + * @return string The string required to be placed between "CREATE" and "TABLE" + * to generate a temporary table, if possible. + */ + public function getTemporaryTableSQL() + { + return 'TEMPORARY'; + } + + /** + * Some vendors require temporary table names to be qualified specially. + * + * @param string $tableName + * @return string + */ + public function getTemporaryTableName($tableName) + { + return $tableName; + } + + /** + * Get sql query to show a list of database. + * + * @return string + */ + public function getShowDatabasesSQL() + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Obtain DBMS specific SQL code portion needed to set the FOREIGN KEY constraint + * of a field declaration to be used in statements like CREATE TABLE. + * + * @param array $definition an associative array with the following structure: + * name optional constraint name + * + * local the local field(s) + * + * foreign the foreign reference field(s) + * + * foreignTable the name of the foreign table + * + * onDelete referential delete action + * + * onUpdate referential update action + * + * deferred deferred constraint checking + * + * The onDelete and onUpdate keys accept the following values: + * + * CASCADE: Delete or update the row from the parent table and automatically delete or + * update the matching rows in the child table. Both ON DELETE CASCADE and ON UPDATE CASCADE are supported. + * Between two tables, you should not define several ON UPDATE CASCADE clauses that act on the same column + * in the parent table or in the child table. + * + * SET NULL: Delete or update the row from the parent table and set the foreign key column or columns in the + * child table to NULL. This is valid only if the foreign key columns do not have the NOT NULL qualifier + * specified. Both ON DELETE SET NULL and ON UPDATE SET NULL clauses are supported. + * + * NO ACTION: In standard SQL, NO ACTION means no action in the sense that an attempt to delete or update a primary + * key value is not allowed to proceed if there is a related foreign key value in the referenced table. + * + * RESTRICT: Rejects the delete or update operation for the parent table. NO ACTION and RESTRICT are the same as + * omitting the ON DELETE or ON UPDATE clause. + * + * SET DEFAULT + * + * @return string DBMS specific SQL code portion needed to set the FOREIGN KEY constraint + * of a field declaration. + */ + public function getForeignKeyDeclarationSQL(ForeignKeyConstraint $foreignKey) + { + $sql = $this->getForeignKeyBaseDeclarationSQL($foreignKey); + $sql .= $this->getAdvancedForeignKeyOptionsSQL($foreignKey); + + return $sql; + } + + /** + * Return the FOREIGN KEY query section dealing with non-standard options + * as MATCH, INITIALLY DEFERRED, ON UPDATE, ... + * + * @param ForeignKeyConstraint $foreignKey foreign key definition + * @return string + */ + public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey) + { + $query = ''; + if ($this->supportsForeignKeyOnUpdate() && $foreignKey->hasOption('onUpdate')) { + $query .= ' ON UPDATE ' . $this->getForeignKeyReferentialActionSQL($foreignKey->getOption('onUpdate')); + } + if ($foreignKey->hasOption('onDelete')) { + $query .= ' ON DELETE ' . $this->getForeignKeyReferentialActionSQL($foreignKey->getOption('onDelete')); + } + return $query; + } + + /** + * returns given referential action in uppercase if valid, otherwise throws + * an exception + * + * @throws Doctrine_Exception_Exception if unknown referential action given + * @param string $action foreign key referential action + * @param string foreign key referential action in uppercase + */ + public function getForeignKeyReferentialActionSQL($action) + { + $upper = strtoupper($action); + switch ($upper) { + case 'CASCADE': + case 'SET NULL': + case 'NO ACTION': + case 'RESTRICT': + case 'SET DEFAULT': + return $upper; + break; + default: + throw new \InvalidArgumentException('Invalid foreign key action: ' . $upper); + } + } + + /** + * Obtain DBMS specific SQL code portion needed to set the FOREIGN KEY constraint + * of a field declaration to be used in statements like CREATE TABLE. + * + * @param ForeignKeyConstraint $foreignKey + * @return string + */ + public function getForeignKeyBaseDeclarationSQL(ForeignKeyConstraint $foreignKey) + { + $sql = ''; + if (strlen($foreignKey->getName())) { + $sql .= 'CONSTRAINT ' . $foreignKey->getQuotedName($this) . ' '; + } + $sql .= 'FOREIGN KEY ('; + + if (count($foreignKey->getLocalColumns()) == 0) { + throw new \InvalidArgumentException("Incomplete definition. 'local' required."); + } + if (count($foreignKey->getForeignColumns()) == 0) { + throw new \InvalidArgumentException("Incomplete definition. 'foreign' required."); + } + if (strlen($foreignKey->getForeignTableName()) == 0) { + throw new \InvalidArgumentException("Incomplete definition. 'foreignTable' required."); + } + + $sql .= implode(', ', $foreignKey->getLocalColumns()) + . ') REFERENCES ' + . $foreignKey->getForeignTableName() . ' (' + . implode(', ', $foreignKey->getForeignColumns()) . ')'; + + return $sql; + } + + /** + * Obtain DBMS specific SQL code portion needed to set the UNIQUE constraint + * of a field declaration to be used in statements like CREATE TABLE. + * + * @return string DBMS specific SQL code portion needed to set the UNIQUE constraint + * of a field declaration. + */ + public function getUniqueFieldDeclarationSQL() + { + return 'UNIQUE'; + } + + /** + * Obtain DBMS specific SQL code portion needed to set the CHARACTER SET + * of a field declaration to be used in statements like CREATE TABLE. + * + * @param string $charset name of the charset + * @return string DBMS specific SQL code portion needed to set the CHARACTER SET + * of a field declaration. + */ + public function getColumnCharsetDeclarationSQL($charset) + { + return ''; + } + + /** + * Obtain DBMS specific SQL code portion needed to set the COLLATION + * of a field declaration to be used in statements like CREATE TABLE. + * + * @param string $collation name of the collation + * @return string DBMS specific SQL code portion needed to set the COLLATION + * of a field declaration. + */ + public function getColumnCollationDeclarationSQL($collation) + { + return ''; + } + + /** + * Whether the platform prefers sequences for ID generation. + * Subclasses should override this method to return TRUE if they prefer sequences. + * + * @return boolean + */ + public function prefersSequences() + { + return false; + } + + /** + * Whether the platform prefers identity columns (eg. autoincrement) for ID generation. + * Subclasses should override this method to return TRUE if they prefer identity columns. + * + * @return boolean + */ + public function prefersIdentityColumns() + { + return false; + } + + /** + * Some platforms need the boolean values to be converted. + * + * The default conversion in this implementation converts to integers (false => 0, true => 1). + * + * @param mixed $item + */ + public function convertBooleans($item) + { + if (is_array($item)) { + foreach ($item as $k => $value) { + if (is_bool($value)) { + $item[$k] = (int) $value; + } + } + } else if (is_bool($item)) { + $item = (int) $item; + } + return $item; + } + + /** + * Gets the SQL statement specific for the platform to set the charset. + * + * This function is MySQL specific and required by + * {@see \Doctrine\DBAL\Connection::setCharset($charset)} + * + * @param string $charset + * @return string + */ + public function getSetCharsetSQL($charset) + { + return "SET NAMES '".$charset."'"; + } + + /** + * Gets the SQL specific for the platform to get the current date. + * + * @return string + */ + public function getCurrentDateSQL() + { + return 'CURRENT_DATE'; + } + + /** + * Gets the SQL specific for the platform to get the current time. + * + * @return string + */ + public function getCurrentTimeSQL() + { + return 'CURRENT_TIME'; + } + + /** + * Gets the SQL specific for the platform to get the current timestamp + * + * @return string + */ + public function getCurrentTimestampSQL() + { + return 'CURRENT_TIMESTAMP'; + } + + /** + * Get sql for transaction isolation level Connection constant + * + * @param integer $level + */ + protected function _getTransactionIsolationLevelSQL($level) + { + switch ($level) { + case Connection::TRANSACTION_READ_UNCOMMITTED: + return 'READ UNCOMMITTED'; + case Connection::TRANSACTION_READ_COMMITTED: + return 'READ COMMITTED'; + case Connection::TRANSACTION_REPEATABLE_READ: + return 'REPEATABLE READ'; + case Connection::TRANSACTION_SERIALIZABLE: + return 'SERIALIZABLE'; + default: + throw new \InvalidArgumentException('Invalid isolation level:' . $level); + } + } + + public function getListDatabasesSQL() + { + throw DBALException::notSupported(__METHOD__); + } + + public function getListSequencesSQL($database) + { + throw DBALException::notSupported(__METHOD__); + } + + public function getListTableConstraintsSQL($table) + { + throw DBALException::notSupported(__METHOD__); + } + + public function getListTableColumnsSQL($table, $database = null) + { + throw DBALException::notSupported(__METHOD__); + } + + public function getListTablesSQL() + { + throw DBALException::notSupported(__METHOD__); + } + + public function getListUsersSQL() + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Get the SQL to list all views of a database or user. + * + * @param string $database + * @return string + */ + public function getListViewsSQL($database) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Get the list of indexes for the current database. + * + * The current database parameter is optional but will always be passed + * when using the SchemaManager API and is the database the given table is in. + * + * Attention: Some platforms only support currentDatabase when they + * are connected with that database. Cross-database information schema + * requests may be impossible. + * + * @param string $table + * @param string $currentDatabase + */ + public function getListTableIndexesSQL($table, $currentDatabase = null) + { + throw DBALException::notSupported(__METHOD__); + } + + public function getListTableForeignKeysSQL($table) + { + throw DBALException::notSupported(__METHOD__); + } + + public function getCreateViewSQL($name, $sql) + { + throw DBALException::notSupported(__METHOD__); + } + + public function getDropViewSQL($name) + { + throw DBALException::notSupported(__METHOD__); + } + + public function getDropSequenceSQL($sequence) + { + throw DBALException::notSupported(__METHOD__); + } + + public function getSequenceNextValSQL($sequenceName) + { + throw DBALException::notSupported(__METHOD__); + } + + public function getCreateDatabaseSQL($database) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Get sql to set the transaction isolation level + * + * @param integer $level + */ + public function getSetTransactionIsolationSQL($level) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Obtain DBMS specific SQL to be used to create datetime fields in + * statements like CREATE TABLE + * + * @param array $fieldDeclaration + * @return string + */ + public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Obtain DBMS specific SQL to be used to create datetime with timezone offset fields. + * + * @param array $fieldDeclaration + */ + public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration) + { + return $this->getDateTimeTypeDeclarationSQL($fieldDeclaration); + } + + + /** + * Obtain DBMS specific SQL to be used to create date fields in statements + * like CREATE TABLE. + * + * @param array $fieldDeclaration + * @return string + */ + public function getDateTypeDeclarationSQL(array $fieldDeclaration) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Obtain DBMS specific SQL to be used to create time fields in statements + * like CREATE TABLE. + * + * @param array $fieldDeclaration + * @return string + */ + public function getTimeTypeDeclarationSQL(array $fieldDeclaration) + { + throw DBALException::notSupported(__METHOD__); + } + + public function getFloatDeclarationSQL(array $fieldDeclaration) + { + return 'DOUBLE PRECISION'; + } + + /** + * Gets the default transaction isolation level of the platform. + * + * @return integer The default isolation level. + * @see Doctrine\DBAL\Connection\TRANSACTION_* constants. + */ + public function getDefaultTransactionIsolationLevel() + { + return Connection::TRANSACTION_READ_COMMITTED; + } + + /* supports*() methods */ + + /** + * Whether the platform supports sequences. + * + * @return boolean + */ + public function supportsSequences() + { + return false; + } + + /** + * Whether the platform supports identity columns. + * Identity columns are columns that recieve an auto-generated value from the + * database on insert of a row. + * + * @return boolean + */ + public function supportsIdentityColumns() + { + return false; + } + + /** + * Whether the platform supports indexes. + * + * @return boolean + */ + public function supportsIndexes() + { + return true; + } + + public function supportsAlterTable() + { + return true; + } + + /** + * Whether the platform supports transactions. + * + * @return boolean + */ + public function supportsTransactions() + { + return true; + } + + /** + * Whether the platform supports savepoints. + * + * @return boolean + */ + public function supportsSavepoints() + { + return true; + } + + /** + * Whether the platform supports releasing savepoints. + * + * @return boolean + */ + public function supportsReleaseSavepoints() + { + return $this->supportsSavepoints(); + } + + /** + * Whether the platform supports primary key constraints. + * + * @return boolean + */ + public function supportsPrimaryConstraints() + { + return true; + } + + /** + * Does the platform supports foreign key constraints? + * + * @return boolean + */ + public function supportsForeignKeyConstraints() + { + return true; + } + + /** + * Does this platform supports onUpdate in foreign key constraints? + * + * @return bool + */ + public function supportsForeignKeyOnUpdate() + { + return ($this->supportsForeignKeyConstraints() && true); + } + + /** + * Whether the platform supports database schemas. + * + * @return boolean + */ + public function supportsSchemas() + { + return false; + } + + /** + * Can this platform emulate schemas? + * + * Platforms that either support or emulate schemas don't automatically + * filter a schema for the namespaced elements in {@link + * AbstractManager#createSchema}. + * + * @return bool + */ + public function canEmulateSchemas() + { + return false; + } + + /** + * Some databases don't allow to create and drop databases at all or only with certain tools. + * + * @return bool + */ + public function supportsCreateDropDatabase() + { + return true; + } + + /** + * Whether the platform supports getting the affected rows of a recent + * update/delete type query. + * + * @return boolean + */ + public function supportsGettingAffectedRows() + { + return true; + } + + /** + * Does this plaform support to add inline column comments as postfix. + * + * @return bool + */ + public function supportsInlineColumnComments() + { + return false; + } + + /** + * Does this platform support the propriortary synatx "COMMENT ON asset" + * + * @return bool + */ + public function supportsCommentOnStatement() + { + return false; + } + + public function getIdentityColumnNullInsertSQL() + { + return ""; + } + + /** + * Gets the format string, as accepted by the date() function, that describes + * the format of a stored datetime value of this platform. + * + * @return string The format string. + */ + public function getDateTimeFormatString() + { + return 'Y-m-d H:i:s'; + } + + /** + * Gets the format string, as accepted by the date() function, that describes + * the format of a stored datetime with timezone value of this platform. + * + * @return string The format string. + */ + public function getDateTimeTzFormatString() + { + return 'Y-m-d H:i:s'; + } + + /** + * Gets the format string, as accepted by the date() function, that describes + * the format of a stored date value of this platform. + * + * @return string The format string. + */ + public function getDateFormatString() + { + return 'Y-m-d'; + } + + /** + * Gets the format string, as accepted by the date() function, that describes + * the format of a stored time value of this platform. + * + * @return string The format string. + */ + public function getTimeFormatString() + { + return 'H:i:s'; + } + + /** + * Modify limit query + * + * @param string $query + * @param int $limit + * @param int $offset + * @return string + */ + final public function modifyLimitQuery($query, $limit, $offset = null) + { + if ( $limit !== null) { + $limit = (int)$limit; + } + + if ( $offset !== null) { + $offset = (int)$offset; + + if ($offset < 0) { + throw new DBALException("LIMIT argument offset=$offset is not valid"); + } + if ( $offset > 0 && ! $this->supportsLimitOffset()) { + throw new DBALException(sprintf("Platform %s does not support offset values in limit queries.", $this->getName())); + } + } + + return $this->doModifyLimitQuery($query, $limit, $offset); + } + + /** + * @param string $query + * @param int $limit + * @param int $offset + * @return string + */ + protected function doModifyLimitQuery($query, $limit, $offset) + { + if ( $limit !== null) { + $query .= ' LIMIT ' . $limit; + } + + if ( $offset !== null) { + $query .= ' OFFSET ' . $offset; + } + + return $query; + } + + /** + * Does the database platform support offsets in modify limit clauses? + * + * @return bool + */ + public function supportsLimitOffset() + { + return true; + } + + /** + * Gets the character casing of a column in an SQL result set of this platform. + * + * @param string $column The column name for which to get the correct character casing. + * @return string The column name in the character casing used in SQL result sets. + */ + public function getSQLResultCasing($column) + { + return $column; + } + + /** + * Makes any fixes to a name of a schema element (table, sequence, ...) that are required + * by restrictions of the platform, like a maximum length. + * + * @param string $schemaName + * @return string + */ + public function fixSchemaElementName($schemaElementName) + { + return $schemaElementName; + } + + /** + * Maximum length of any given databse identifier, like tables or column names. + * + * @return int + */ + public function getMaxIdentifierLength() + { + return 63; + } + + /** + * Get the insert sql for an empty insert statement + * + * @param string $tableName + * @param string $identifierColumnName + * @return string $sql + */ + public function getEmptyIdentityInsertSQL($tableName, $identifierColumnName) + { + return 'INSERT INTO ' . $tableName . ' (' . $identifierColumnName . ') VALUES (null)'; + } + + /** + * Generate a Truncate Table SQL statement for a given table. + * + * Cascade is not supported on many platforms but would optionally cascade the truncate by + * following the foreign keys. + * + * @param string $tableName + * @param bool $cascade + * @return string + */ + public function getTruncateTableSQL($tableName, $cascade = false) + { + return 'TRUNCATE '.$tableName; + } + + /** + * This is for test reasons, many vendors have special requirements for dummy statements. + * + * @return string + */ + public function getDummySelectSQL() + { + return 'SELECT 1'; + } + + /** + * Generate SQL to create a new savepoint + * + * @param string $savepoint + * @return string + */ + public function createSavePoint($savepoint) + { + return 'SAVEPOINT ' . $savepoint; + } + + /** + * Generate SQL to release a savepoint + * + * @param string $savepoint + * @return string + */ + public function releaseSavePoint($savepoint) + { + return 'RELEASE SAVEPOINT ' . $savepoint; + } + + /** + * Generate SQL to rollback a savepoint + * + * @param string $savepoint + * @return string + */ + public function rollbackSavePoint($savepoint) + { + return 'ROLLBACK TO SAVEPOINT ' . $savepoint; + } + + /** + * Return the keyword list instance of this platform. + * + * Throws exception if no keyword list is specified. + * + * @throws DBALException + * @return KeywordList + */ + final public function getReservedKeywordsList() + { + $class = $this->getReservedKeywordsClass(); + $keywords = new $class; + if (!$keywords instanceof \Doctrine\DBAL\Platforms\Keywords\KeywordList) { + throw DBALException::notSupported(__METHOD__); + } + return $keywords; + } + + /** + * The class name of the reserved keywords list. + * + * @return string + */ + protected function getReservedKeywordsClass() + { + throw DBALException::notSupported(__METHOD__); + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DB2Platform.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DB2Platform.php new file mode 100644 index 0000000..198be83 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DB2Platform.php @@ -0,0 +1,587 @@ +. +*/ + +namespace Doctrine\DBAL\Platforms; + +use Doctrine\DBAL\DBALException; +use Doctrine\DBAL\Schema\Index; +use Doctrine\DBAL\Schema\TableDiff; + +class DB2Platform extends AbstractPlatform +{ + /** + * Gets the SQL Snippet used to declare a BLOB column type. + */ + public function getBlobTypeDeclarationSQL(array $field) + { + throw DBALException::notSupported(__METHOD__); + } + + public function initializeDoctrineTypeMappings() + { + $this->doctrineTypeMapping = array( + 'smallint' => 'smallint', + 'bigint' => 'bigint', + 'integer' => 'integer', + 'time' => 'time', + 'date' => 'date', + 'varchar' => 'string', + 'character' => 'string', + 'clob' => 'text', + 'decimal' => 'decimal', + 'double' => 'float', + 'real' => 'float', + 'timestamp' => 'datetime', + ); + } + + /** + * Gets the SQL snippet used to declare a VARCHAR column type. + * + * @param array $field + */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) + { + return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)') + : ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)'); + } + + /** + * Gets the SQL snippet used to declare a CLOB column type. + * + * @param array $field + */ + public function getClobTypeDeclarationSQL(array $field) + { + // todo clob(n) with $field['length']; + return 'CLOB(1M)'; + } + + /** + * Gets the name of the platform. + * + * @return string + */ + public function getName() + { + return 'db2'; + } + + + /** + * Gets the SQL snippet that declares a boolean column. + * + * @param array $columnDef + * @return string + */ + public function getBooleanTypeDeclarationSQL(array $columnDef) + { + return 'SMALLINT'; + } + + /** + * Gets the SQL snippet that declares a 4 byte integer column. + * + * @param array $columnDef + * @return string + */ + public function getIntegerTypeDeclarationSQL(array $columnDef) + { + return 'INTEGER' . $this->_getCommonIntegerTypeDeclarationSQL($columnDef); + } + + /** + * Gets the SQL snippet that declares an 8 byte integer column. + * + * @param array $columnDef + * @return string + */ + public function getBigIntTypeDeclarationSQL(array $columnDef) + { + return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($columnDef); + } + + /** + * Gets the SQL snippet that declares a 2 byte integer column. + * + * @param array $columnDef + * @return string + */ + public function getSmallIntTypeDeclarationSQL(array $columnDef) + { + return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($columnDef); + } + + /** + * Gets the SQL snippet that declares common properties of an integer column. + * + * @param array $columnDef + * @return string + */ + protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef) + { + $autoinc = ''; + if ( ! empty($columnDef['autoincrement'])) { + $autoinc = ' GENERATED BY DEFAULT AS IDENTITY'; + } + return $autoinc; + } + + /** + * Obtain DBMS specific SQL to be used to create datetime fields in + * statements like CREATE TABLE + * + * @param array $fieldDeclaration + * @return string + */ + public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) + { + if (isset($fieldDeclaration['version']) && $fieldDeclaration['version'] == true) { + return "TIMESTAMP(0) WITH DEFAULT"; + } + + return 'TIMESTAMP(0)'; + } + + /** + * Obtain DBMS specific SQL to be used to create date fields in statements + * like CREATE TABLE. + * + * @param array $fieldDeclaration + * @return string + */ + public function getDateTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATE'; + } + + /** + * Obtain DBMS specific SQL to be used to create time fields in statements + * like CREATE TABLE. + * + * @param array $fieldDeclaration + * @return string + */ + public function getTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'TIME'; + } + + public function getListDatabasesSQL() + { + throw DBALException::notSupported(__METHOD__); + } + + public function getListSequencesSQL($database) + { + throw DBALException::notSupported(__METHOD__); + } + + public function getListTableConstraintsSQL($table) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * This code fragment is originally from the Zend_Db_Adapter_Db2 class. + * + * @license New BSD License + * @param string $table + * @return string + */ + public function getListTableColumnsSQL($table, $database = null) + { + return "SELECT DISTINCT c.tabschema, c.tabname, c.colname, c.colno, + c.typename, c.default, c.nulls, c.length, c.scale, + c.identity, tc.type AS tabconsttype, k.colseq + FROM syscat.columns c + LEFT JOIN (syscat.keycoluse k JOIN syscat.tabconst tc + ON (k.tabschema = tc.tabschema + AND k.tabname = tc.tabname + AND tc.type = 'P')) + ON (c.tabschema = k.tabschema + AND c.tabname = k.tabname + AND c.colname = k.colname) + WHERE UPPER(c.tabname) = UPPER('" . $table . "') ORDER BY c.colno"; + } + + public function getListTablesSQL() + { + return "SELECT NAME FROM SYSIBM.SYSTABLES WHERE TYPE = 'T'"; + } + + public function getListUsersSQL() + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Get the SQL to list all views of a database or user. + * + * @param string $database + * @return string + */ + public function getListViewsSQL($database) + { + return "SELECT NAME, TEXT FROM SYSIBM.SYSVIEWS"; + } + + public function getListTableIndexesSQL($table, $currentDatabase = null) + { + return "SELECT NAME, COLNAMES, UNIQUERULE FROM SYSIBM.SYSINDEXES WHERE TBNAME = UPPER('" . $table . "')"; + } + + public function getListTableForeignKeysSQL($table) + { + return "SELECT TBNAME, RELNAME, REFTBNAME, DELETERULE, UPDATERULE, FKCOLNAMES, PKCOLNAMES ". + "FROM SYSIBM.SYSRELS WHERE TBNAME = UPPER('".$table."')"; + } + + public function getCreateViewSQL($name, $sql) + { + return "CREATE VIEW ".$name." AS ".$sql; + } + + public function getDropViewSQL($name) + { + return "DROP VIEW ".$name; + } + + public function getDropSequenceSQL($sequence) + { + throw DBALException::notSupported(__METHOD__); + } + + public function getSequenceNextValSQL($sequenceName) + { + throw DBALException::notSupported(__METHOD__); + } + + public function getCreateDatabaseSQL($database) + { + return "CREATE DATABASE ".$database; + } + + public function getDropDatabaseSQL($database) + { + return "DROP DATABASE ".$database.";"; + } + + public function supportsCreateDropDatabase() + { + return false; + } + + /** + * Whether the platform supports releasing savepoints. + * + * @return boolean + */ + public function supportsReleaseSavepoints() + { + return false; + } + + /** + * Gets the SQL specific for the platform to get the current date. + * + * @return string + */ + public function getCurrentDateSQL() + { + return 'VALUES CURRENT DATE'; + } + + /** + * Gets the SQL specific for the platform to get the current time. + * + * @return string + */ + public function getCurrentTimeSQL() + { + return 'VALUES CURRENT TIME'; + } + + /** + * Gets the SQL specific for the platform to get the current timestamp + * + * @return string + */ + + public function getCurrentTimestampSQL() + { + return "VALUES CURRENT TIMESTAMP"; + } + + /** + * Obtain DBMS specific SQL code portion needed to set an index + * declaration to be used in statements like CREATE TABLE. + * + * @param string $name name of the index + * @param Index $index index definition + * @return string DBMS specific SQL code portion needed to set an index + */ + public function getIndexDeclarationSQL($name, Index $index) + { + return $this->getUniqueConstraintDeclarationSQL($name, $index); + } + + /** + * @param string $tableName + * @param array $columns + * @param array $options + * @return array + */ + protected function _getCreateTableSQL($tableName, array $columns, array $options = array()) + { + $indexes = array(); + if (isset($options['indexes'])) { + $indexes = $options['indexes']; + } + $options['indexes'] = array(); + + $sqls = parent::_getCreateTableSQL($tableName, $columns, $options); + + foreach ($indexes as $index => $definition) { + $sqls[] = $this->getCreateIndexSQL($definition, $tableName); + } + return $sqls; + } + + /** + * Gets the SQL to alter an existing table. + * + * @param TableDiff $diff + * @return array + */ + public function getAlterTableSQL(TableDiff $diff) + { + $sql = array(); + $columnSql = array(); + + $queryParts = array(); + foreach ($diff->addedColumns AS $fieldName => $column) { + if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { + continue; + } + + $queryParts[] = 'ADD COLUMN ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); + } + + foreach ($diff->removedColumns AS $column) { + if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) { + continue; + } + + $queryParts[] = 'DROP COLUMN ' . $column->getQuotedName($this); + } + + foreach ($diff->changedColumns AS $columnDiff) { + if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { + continue; + } + + /* @var $columnDiff Doctrine\DBAL\Schema\ColumnDiff */ + $column = $columnDiff->column; + $queryParts[] = 'ALTER ' . ($columnDiff->oldColumnName) . ' ' + . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); + } + + foreach ($diff->renamedColumns AS $oldColumnName => $column) { + if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { + continue; + } + + $queryParts[] = 'RENAME ' . $oldColumnName . ' TO ' . $column->getQuotedName($this); + } + + $tableSql = array(); + + if (!$this->onSchemaAlterTable($diff, $tableSql)) { + if (count($queryParts) > 0) { + $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . implode(" ", $queryParts); + } + + $sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff)); + + if ($diff->newName !== false) { + $sql[] = 'RENAME TABLE TO ' . $diff->newName; + } + } + + return array_merge($sql, $tableSql, $columnSql); + } + + public function getDefaultValueDeclarationSQL($field) + { + if (isset($field['notnull']) && $field['notnull'] && !isset($field['default'])) { + if (in_array((string)$field['type'], array("Integer", "BigInteger", "SmallInteger"))) { + $field['default'] = 0; + } else if((string)$field['type'] == "DateTime") { + $field['default'] = "00-00-00 00:00:00"; + } else if ((string)$field['type'] == "Date") { + $field['default'] = "00-00-00"; + } else if((string)$field['type'] == "Time") { + $field['default'] = "00:00:00"; + } else { + $field['default'] = ''; + } + } + + unset($field['default']); // @todo this needs fixing + if (isset($field['version']) && $field['version']) { + if ((string)$field['type'] != "DateTime") { + $field['default'] = "1"; + } + } + + return parent::getDefaultValueDeclarationSQL($field); + } + + /** + * Get the insert sql for an empty insert statement + * + * @param string $tableName + * @param string $identifierColumnName + * @return string $sql + */ + public function getEmptyIdentityInsertSQL($tableName, $identifierColumnName) + { + return 'INSERT INTO ' . $tableName . ' (' . $identifierColumnName . ') VALUES (DEFAULT)'; + } + + public function getCreateTemporaryTableSnippetSQL() + { + return "DECLARE GLOBAL TEMPORARY TABLE"; + } + + /** + * DB2 automatically moves temporary tables into the SESSION. schema. + * + * @param string $tableName + * @return string + */ + public function getTemporaryTableName($tableName) + { + return "SESSION." . $tableName; + } + + protected function doModifyLimitQuery($query, $limit, $offset = null) + { + if ($limit === null && $offset === null) { + return $query; + } + + $limit = (int)$limit; + $offset = (int)(($offset)?:0); + + // Todo OVER() needs ORDER BY data! + $sql = 'SELECT db22.* FROM (SELECT ROW_NUMBER() OVER() AS DC_ROWNUM, db21.* '. + 'FROM (' . $query . ') db21) db22 WHERE db22.DC_ROWNUM BETWEEN ' . ($offset+1) .' AND ' . ($offset+$limit); + return $sql; + } + + /** + * returns the position of the first occurrence of substring $substr in string $str + * + * @param string $substr literal string to find + * @param string $str literal string + * @param int $pos position to start at, beginning of string by default + * @return integer + */ + public function getLocateExpression($str, $substr, $startPos = false) + { + if ($startPos == false) { + return 'LOCATE(' . $substr . ', ' . $str . ')'; + } else { + return 'LOCATE(' . $substr . ', ' . $str . ', '.$startPos.')'; + } + } + + /** + * return string to call a function to get a substring inside an SQL statement + * + * Note: Not SQL92, but common functionality. + * + * SQLite only supports the 2 parameter variant of this function + * + * @param string $value an sql string literal or column name/alias + * @param integer $from where to start the substring portion + * @param integer $len the substring portion length + * @return string + */ + public function getSubstringExpression($value, $from, $len = null) + { + if ($len === null) + return 'SUBSTR(' . $value . ', ' . $from . ')'; + else { + return 'SUBSTR(' . $value . ', ' . $from . ', ' . $len . ')'; + } + } + + public function supportsIdentityColumns() + { + return true; + } + + public function prefersIdentityColumns() + { + return true; + } + + /** + * Gets the character casing of a column in an SQL result set of this platform. + * + * DB2 returns all column names in SQL result sets in uppercase. + * + * @param string $column The column name for which to get the correct character casing. + * @return string The column name in the character casing used in SQL result sets. + */ + public function getSQLResultCasing($column) + { + return strtoupper($column); + } + + public function getForUpdateSQL() + { + return ' WITH RR USE AND KEEP UPDATE LOCKS'; + } + + public function getDummySelectSQL() + { + return 'SELECT 1 FROM sysibm.sysdummy1'; + } + + /** + * DB2 supports savepoints, but they work semantically different than on other vendor platforms. + * + * TODO: We have to investigate how to get DB2 up and running with savepoints. + * + * @return bool + */ + public function supportsSavepoints() + { + return false; + } + + protected function getReservedKeywordsClass() + { + return 'Doctrine\DBAL\Platforms\Keywords\DB2Keywords'; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/DB2Keywords.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/DB2Keywords.php new file mode 100644 index 0000000..4b77cac --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/DB2Keywords.php @@ -0,0 +1,438 @@ +. + */ + + +namespace Doctrine\DBAL\Platforms\Keywords; + +/** + * DB2 Keywords + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.0 + * @author Benjamin Eberlei + */ +class DB2Keywords extends KeywordList +{ + public function getName() + { + return 'DB2'; + } + + protected function getKeywords() + { + return array( + 'ACTIVATE', + 'ADD', + 'AFTER', + 'ALIAS', + 'ALL', + 'ALLOCATE', + 'DOCUMENT', + 'DOUBLE', + 'DROP', + 'DSSIZE', + 'DYNAMIC', + 'EACH', + 'LOCK', + 'LOCKMAX', + 'LOCKSIZE', + 'LONG', + 'LOOP', + 'MAINTAINED', + 'ROUND_CEILING', + 'ROUND_DOWN', + 'ROUND_FLOOR', + 'ROUND_HALF_DOWN', + 'ROUND_HALF_EVEN', + 'ROUND_HALF_UP', + 'ALLOW', + 'ALTER', + 'AND', + 'ANY', + 'AS', + 'ASENSITIVE', + 'ASSOCIATE', + 'ASUTIME', + 'AT', + 'ATTRIBUTES', + 'AUDIT', + 'AUTHORIZATION', + 'AUX', + 'AUXILIARY', + 'BEFORE', + 'BEGIN', + 'BETWEEN', + 'BINARY', + 'BUFFERPOOL', + 'BY', + 'CACHE', + 'CALL', + 'CALLED', + 'CAPTURE', + 'CARDINALITY', + 'CASCADED', + 'CASE', + 'CAST', + 'CCSID', + 'CHAR', + 'CHARACTER', + 'CHECK', + 'CLONE', + 'CLOSE', + 'CLUSTER', + 'COLLECTION', + 'COLLID', + 'COLUMN', + 'COMMENT', + 'COMMIT', + 'CONCAT', + 'CONDITION', + 'CONNECT', + 'CONNECTION', + 'CONSTRAINT', + 'CONTAINS', + 'CONTINUE', + 'COUNT', + 'COUNT_BIG', + 'CREATE', + 'CROSS', + 'CURRENT', + 'CURRENT_DATE', + 'CURRENT_LC_CTYPE', + 'CURRENT_PATH', + 'CURRENT_SCHEMA', + 'CURRENT_SERVER', + 'CURRENT_TIME', + 'CURRENT_TIMESTAMP', + 'CURRENT_TIMEZONE', + 'CURRENT_USER', + 'CURSOR', + 'CYCLE', + 'DATA', + 'DATABASE', + 'DATAPARTITIONNAME', + 'DATAPARTITIONNUM', + 'EDITPROC', + 'ELSE', + 'ELSEIF', + 'ENABLE', + 'ENCODING', + 'ENCRYPTION', + 'END', + 'END-EXEC', + 'ENDING', + 'ERASE', + 'ESCAPE', + 'EVERY', + 'EXCEPT', + 'EXCEPTION', + 'EXCLUDING', + 'EXCLUSIVE', + 'EXECUTE', + 'EXISTS', + 'EXIT', + 'EXPLAIN', + 'EXTERNAL', + 'EXTRACT', + 'FENCED', + 'FETCH', + 'FIELDPROC', + 'FILE', + 'FINAL', + 'FOR', + 'FOREIGN', + 'FREE', + 'FROM', + 'FULL', + 'FUNCTION', + 'GENERAL', + 'GENERATED', + 'GET', + 'GLOBAL', + 'GO', + 'GOTO', + 'GRANT', + 'GRAPHIC', + 'GROUP', + 'HANDLER', + 'HASH', + 'HASHED_VALUE', + 'HAVING', + 'HINT', + 'HOLD', + 'HOUR', + 'HOURS', + 'IDENTITY', + 'IF', + 'IMMEDIATE', + 'IN', + 'INCLUDING', + 'INCLUSIVE', + 'INCREMENT', + 'INDEX', + 'INDICATOR', + 'INF', + 'INFINITY', + 'INHERIT', + 'INNER', + 'INOUT', + 'INSENSITIVE', + 'INSERT', + 'INTEGRITY', + 'MATERIALIZED', + 'MAXVALUE', + 'MICROSECOND', + 'MICROSECONDS', + 'MINUTE', + 'MINUTES', + 'MINVALUE', + 'MODE', + 'MODIFIES', + 'MONTH', + 'MONTHS', + 'NAN', + 'NEW', + 'NEW_TABLE', + 'NEXTVAL', + 'NO', + 'NOCACHE', + 'NOCYCLE', + 'NODENAME', + 'NODENUMBER', + 'NOMAXVALUE', + 'NOMINVALUE', + 'NONE', + 'NOORDER', + 'NORMALIZED', + 'NOT', + 'NULL', + 'NULLS', + 'NUMPARTS', + 'OBID', + 'OF', + 'OLD', + 'OLD_TABLE', + 'ON', + 'OPEN', + 'OPTIMIZATION', + 'OPTIMIZE', + 'OPTION', + 'OR', + 'ORDER', + 'OUT', + 'OUTER', + 'OVER', + 'OVERRIDING', + 'PACKAGE', + 'PADDED', + 'PAGESIZE', + 'PARAMETER', + 'PART', + 'PARTITION', + 'PARTITIONED', + 'PARTITIONING', + 'PARTITIONS', + 'PASSWORD', + 'PATH', + 'PIECESIZE', + 'PLAN', + 'POSITION', + 'PRECISION', + 'PREPARE', + 'PREVVAL', + 'PRIMARY', + 'PRIQTY', + 'PRIVILEGES', + 'PROCEDURE', + 'PROGRAM', + 'PSID', + 'ROUND_UP', + 'ROUTINE', + 'ROW', + 'ROW_NUMBER', + 'ROWNUMBER', + 'ROWS', + 'ROWSET', + 'RRN', + 'RUN', + 'SAVEPOINT', + 'SCHEMA', + 'SCRATCHPAD', + 'SCROLL', + 'SEARCH', + 'SECOND', + 'SECONDS', + 'SECQTY', + 'SECURITY', + 'SELECT', + 'SENSITIVE', + 'SEQUENCE', + 'SESSION', + 'SESSION_USER', + 'SET', + 'SIGNAL', + 'SIMPLE', + 'SNAN', + 'SOME', + 'SOURCE', + 'SPECIFIC', + 'SQL', + 'SQLID', + 'STACKED', + 'STANDARD', + 'START', + 'STARTING', + 'STATEMENT', + 'STATIC', + 'STATMENT', + 'STAY', + 'STOGROUP', + 'STORES', + 'STYLE', + 'SUBSTRING', + 'SUMMARY', + 'SYNONYM', + 'SYSFUN', + 'SYSIBM', + 'SYSPROC', + 'SYSTEM', + 'SYSTEM_USER', + 'TABLE', + 'TABLESPACE', + 'THEN', + 'TIME', + 'TIMESTAMP', + 'TO', + 'TRANSACTION', + 'TRIGGER', + 'TRIM', + 'TRUNCATE', + 'TYPE', + 'UNDO', + 'UNION', + 'UNIQUE', + 'UNTIL', + 'UPDATE', + 'DATE', + 'DAY', + 'DAYS', + 'DB2GENERAL', + 'DB2GENRL', + 'DB2SQL', + 'DBINFO', + 'DBPARTITIONNAME', + 'DBPARTITIONNUM', + 'DEALLOCATE', + 'DECLARE', + 'DEFAULT', + 'DEFAULTS', + 'DEFINITION', + 'DELETE', + 'DENSE_RANK', + 'DENSERANK', + 'DESCRIBE', + 'DESCRIPTOR', + 'DETERMINISTIC', + 'DIAGNOSTICS', + 'DISABLE', + 'DISALLOW', + 'DISCONNECT', + 'DISTINCT', + 'DO', + 'INTERSECT', + 'PUBLIC', + 'USAGE', + 'INTO', + 'QUERY', + 'USER', + 'IS', + 'QUERYNO', + 'USING', + 'ISOBID', + 'RANGE', + 'VALIDPROC', + 'ISOLATION', + 'RANK', + 'VALUE', + 'ITERATE', + 'READ', + 'VALUES', + 'JAR', + 'READS', + 'VARIABLE', + 'JAVA', + 'RECOVERY', + 'VARIANT', + 'JOIN', + 'REFERENCES', + 'VCAT', + 'KEEP', + 'REFERENCING', + 'VERSION', + 'KEY', + 'REFRESH', + 'VIEW', + 'LABEL', + 'RELEASE', + 'VOLATILE', + 'LANGUAGE', + 'RENAME', + 'VOLUMES', + 'LATERAL', + 'REPEAT', + 'WHEN', + 'LC_CTYPE', + 'RESET', + 'WHENEVER', + 'LEAVE', + 'RESIGNAL', + 'WHERE', + 'LEFT', + 'RESTART', + 'WHILE', + 'LIKE', + 'RESTRICT', + 'WITH', + 'LINKTYPE', + 'RESULT', + 'WITHOUT', + 'LOCAL', + 'RESULT_SET_LOCATOR WLM', + 'LOCALDATE', + 'RETURN', + 'WRITE', + 'LOCALE', + 'RETURNS', + 'XMLELEMENT', + 'LOCALTIME', + 'REVOKE', + 'XMLEXISTS', + 'LOCALTIMESTAMP RIGHT', + 'XMLNAMESPACES', + 'LOCATOR', + 'ROLE', + 'YEAR', + 'LOCATORS', + 'ROLLBACK', + 'YEARS', + ); + } +} + diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/KeywordList.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/KeywordList.php new file mode 100644 index 0000000..dccd717 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/KeywordList.php @@ -0,0 +1,63 @@ +. + */ + + +namespace Doctrine\DBAL\Platforms\Keywords; + +/** + * Abstract interface for a SQL reserved keyword dictionary. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.0 + * @author Benjamin Eberlei + */ +abstract class KeywordList +{ + private $keywords = null; + + /** + * Check if the given word is a keyword of this dialect/vendor platform. + * + * @param string $word + * @return bool + */ + public function isKeyword($word) + { + if ($this->keywords === null) { + $this->initializeKeywords(); + } + + return isset($this->keywords[strtoupper($word)]); + } + + protected function initializeKeywords() + { + $this->keywords = array_flip(array_map('strtoupper', $this->getKeywords())); + } + + abstract protected function getKeywords(); + + /** + * Name of this keyword list. + * + * @return string + */ + abstract public function getName(); +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MsSQLKeywords.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MsSQLKeywords.php new file mode 100644 index 0000000..f59ae81 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MsSQLKeywords.php @@ -0,0 +1,243 @@ +. + */ + + +namespace Doctrine\DBAL\Platforms\Keywords; + +/** + * MsSQL Keywordlist + * + * @license BSD http://www.opensource.org/licenses/bsd-license.php + * @link www.doctrine-project.com + * @since 2.0 + * @author Benjamin Eberlei + * @author David Coallier + */ +class MsSQLKeywords extends KeywordList +{ + public function getName() + { + return 'MsSQL'; + } + + protected function getKeywords() + { + return array( + 'ADD', + 'CURRENT_TIMESTAMP', + 'GROUP', + 'OPENQUERY', + 'SERIALIZABLE', + 'ALL', + 'CURRENT_USER', + 'HAVING', + 'OPENROWSET', + 'SESSION_USER', + 'ALTER', + 'CURSOR', + 'HOLDLOCK', + 'OPTION', + 'SET', + 'AND', + 'DATABASE', + 'IDENTITY', + 'OR', + 'SETUSER', + 'ANY', + 'DBCC', + 'IDENTITYCOL', + 'ORDER', + 'SHUTDOWN', + 'AS', + 'DEALLOCATE', + 'IDENTITY_INSERT', + 'OUTER', + 'SOME', + 'ASC', + 'DECLARE', + 'IF', + 'OVER', + 'STATISTICS', + 'AUTHORIZATION', + 'DEFAULT', + 'IN', + 'PERCENT', + 'SUM', + 'AVG', + 'DELETE', + 'INDEX', + 'PERM', + 'SYSTEM_USER', + 'BACKUP', + 'DENY', + 'INNER', + 'PERMANENT', + 'TABLE', + 'BEGIN', + 'DESC', + 'INSERT', + 'PIPE', + 'TAPE', + 'BETWEEN', + 'DISK', + 'INTERSECT', + 'PLAN', + 'TEMP', + 'BREAK', + 'DISTINCT', + 'INTO', + 'PRECISION', + 'TEMPORARY', + 'BROWSE', + 'DISTRIBUTED', + 'IS', + 'PREPARE', + 'TEXTSIZE', + 'BULK', + 'DOUBLE', + 'ISOLATION', + 'PRIMARY', + 'THEN', + 'BY', + 'DROP', + 'JOIN', + 'PRINT', + 'TO', + 'CASCADE', + 'DUMMY', + 'KEY', + 'PRIVILEGES', + 'TOP', + 'CASE', + 'DUMP', + 'KILL', + 'PROC', + 'TRAN', + 'CHECK', + 'ELSE', + 'LEFT', + 'PROCEDURE', + 'TRANSACTION', + 'CHECKPOINT', + 'END', + 'LEVEL', + 'PROCESSEXIT', + 'TRIGGER', + 'CLOSE', + 'ERRLVL', + 'LIKE', + 'PUBLIC', + 'TRUNCATE', + 'CLUSTERED', + 'ERROREXIT', + 'LINENO', + 'RAISERROR', + 'TSEQUAL', + 'COALESCE', + 'ESCAPE', + 'LOAD', + 'READ', + 'UNCOMMITTED', + 'COLUMN', + 'EXCEPT', + 'MAX', + 'READTEXT', + 'UNION', + 'COMMIT', + 'EXEC', + 'MIN', + 'RECONFIGURE', + 'UNIQUE', + 'COMMITTED', + 'EXECUTE', + 'MIRROREXIT', + 'REFERENCES', + 'UPDATE', + 'COMPUTE', + 'EXISTS', + 'NATIONAL', + 'REPEATABLE', + 'UPDATETEXT', + 'CONFIRM', + 'EXIT', + 'NOCHECK', + 'REPLICATION', + 'USE', + 'CONSTRAINT', + 'FETCH', + 'NONCLUSTERED', + 'RESTORE', + 'USER', + 'CONTAINS', + 'FILE', + 'NOT', + 'RESTRICT', + 'VALUES', + 'CONTAINSTABLE', + 'FILLFACTOR', + 'NULL', + 'RETURN', + 'VARYING', + 'CONTINUE', + 'FLOPPY', + 'NULLIF', + 'REVOKE', + 'VIEW', + 'CONTROLROW', + 'FOR', + 'OF', + 'RIGHT', + 'WAITFOR', + 'CONVERT', + 'FOREIGN', + 'OFF', + 'ROLLBACK', + 'WHEN', + 'COUNT', + 'FREETEXT', + 'OFFSETS', + 'ROWCOUNT', + 'WHERE', + 'CREATE', + 'FREETEXTTABLE', + 'ON', + 'ROWGUIDCOL', + 'WHILE', + 'CROSS', + 'FROM', + 'ONCE', + 'RULE', + 'WITH', + 'CURRENT', + 'FULL', + 'ONLY', + 'SAVE', + 'WORK', + 'CURRENT_DATE', + 'GOTO', + 'OPEN', + 'SCHEMA', + 'WRITETEXT', + 'CURRENT_TIME', + 'GRANT', + 'OPENDATASOURCE', + 'SELECT', + ); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MySQLKeywords.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MySQLKeywords.php new file mode 100644 index 0000000..1d58749 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MySQLKeywords.php @@ -0,0 +1,268 @@ +. + */ + + +namespace Doctrine\DBAL\Platforms\Keywords; + +/** + * MySQL Keywordlist + * + * @license BSD http://www.opensource.org/licenses/bsd-license.php + * @link www.doctrine-project.com + * @since 2.0 + * @author Benjamin Eberlei + * @author David Coallier + */ +class MySQLKeywords extends KeywordList +{ + public function getName() + { + return 'MySQL'; + } + + protected function getKeywords() + { + return array( + 'ADD', + 'ALL', + 'ALTER', + 'ANALYZE', + 'AND', + 'AS', + 'ASC', + 'ASENSITIVE', + 'BEFORE', + 'BETWEEN', + 'BIGINT', + 'BINARY', + 'BLOB', + 'BOTH', + 'BY', + 'CALL', + 'CASCADE', + 'CASE', + 'CHANGE', + 'CHAR', + 'CHARACTER', + 'CHECK', + 'COLLATE', + 'COLUMN', + 'CONDITION', + 'CONNECTION', + 'CONSTRAINT', + 'CONTINUE', + 'CONVERT', + 'CREATE', + 'CROSS', + 'CURRENT_DATE', + 'CURRENT_TIME', + 'CURRENT_TIMESTAMP', + 'CURRENT_USER', + 'CURSOR', + 'DATABASE', + 'DATABASES', + 'DAY_HOUR', + 'DAY_MICROSECOND', + 'DAY_MINUTE', + 'DAY_SECOND', + 'DEC', + 'DECIMAL', + 'DECLARE', + 'DEFAULT', + 'DELAYED', + 'DELETE', + 'DESC', + 'DESCRIBE', + 'DETERMINISTIC', + 'DISTINCT', + 'DISTINCTROW', + 'DIV', + 'DOUBLE', + 'DROP', + 'DUAL', + 'EACH', + 'ELSE', + 'ELSEIF', + 'ENCLOSED', + 'ESCAPED', + 'EXISTS', + 'EXIT', + 'EXPLAIN', + 'FALSE', + 'FETCH', + 'FLOAT', + 'FLOAT4', + 'FLOAT8', + 'FOR', + 'FORCE', + 'FOREIGN', + 'FROM', + 'FULLTEXT', + 'GOTO', + 'GRANT', + 'GROUP', + 'HAVING', + 'HIGH_PRIORITY', + 'HOUR_MICROSECOND', + 'HOUR_MINUTE', + 'HOUR_SECOND', + 'IF', + 'IGNORE', + 'IN', + 'INDEX', + 'INFILE', + 'INNER', + 'INOUT', + 'INSENSITIVE', + 'INSERT', + 'INT', + 'INT1', + 'INT2', + 'INT3', + 'INT4', + 'INT8', + 'INTEGER', + 'INTERVAL', + 'INTO', + 'IS', + 'ITERATE', + 'JOIN', + 'KEY', + 'KEYS', + 'KILL', + 'LABEL', + 'LEADING', + 'LEAVE', + 'LEFT', + 'LIKE', + 'LIMIT', + 'LINES', + 'LOAD', + 'LOCALTIME', + 'LOCALTIMESTAMP', + 'LOCK', + 'LONG', + 'LONGBLOB', + 'LONGTEXT', + 'LOOP', + 'LOW_PRIORITY', + 'MATCH', + 'MEDIUMBLOB', + 'MEDIUMINT', + 'MEDIUMTEXT', + 'MIDDLEINT', + 'MINUTE_MICROSECOND', + 'MINUTE_SECOND', + 'MOD', + 'MODIFIES', + 'NATURAL', + 'NOT', + 'NO_WRITE_TO_BINLOG', + 'NULL', + 'NUMERIC', + 'ON', + 'OPTIMIZE', + 'OPTION', + 'OPTIONALLY', + 'OR', + 'ORDER', + 'OUT', + 'OUTER', + 'OUTFILE', + 'PRECISION', + 'PRIMARY', + 'PROCEDURE', + 'PURGE', + 'RAID0', + 'READ', + 'READS', + 'REAL', + 'REFERENCES', + 'REGEXP', + 'RELEASE', + 'RENAME', + 'REPEAT', + 'REPLACE', + 'REQUIRE', + 'RESTRICT', + 'RETURN', + 'REVOKE', + 'RIGHT', + 'RLIKE', + 'SCHEMA', + 'SCHEMAS', + 'SECOND_MICROSECOND', + 'SELECT', + 'SENSITIVE', + 'SEPARATOR', + 'SET', + 'SHOW', + 'SMALLINT', + 'SONAME', + 'SPATIAL', + 'SPECIFIC', + 'SQL', + 'SQLEXCEPTION', + 'SQLSTATE', + 'SQLWARNING', + 'SQL_BIG_RESULT', + 'SQL_CALC_FOUND_ROWS', + 'SQL_SMALL_RESULT', + 'SSL', + 'STARTING', + 'STRAIGHT_JOIN', + 'TABLE', + 'TERMINATED', + 'THEN', + 'TINYBLOB', + 'TINYINT', + 'TINYTEXT', + 'TO', + 'TRAILING', + 'TRIGGER', + 'TRUE', + 'UNDO', + 'UNION', + 'UNIQUE', + 'UNLOCK', + 'UNSIGNED', + 'UPDATE', + 'USAGE', + 'USE', + 'USING', + 'UTC_DATE', + 'UTC_TIME', + 'UTC_TIMESTAMP', + 'VALUES', + 'VARBINARY', + 'VARCHAR', + 'VARCHARACTER', + 'VARYING', + 'WHEN', + 'WHERE', + 'WHILE', + 'WITH', + 'WRITE', + 'X509', + 'XOR', + 'YEAR_MONTH', + 'ZEROFILL', + ); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/OracleKeywords.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/OracleKeywords.php new file mode 100644 index 0000000..a5840a0 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/OracleKeywords.php @@ -0,0 +1,156 @@ +. + */ + + +namespace Doctrine\DBAL\Platforms\Keywords; + +/** + * Oracle Keywordlist + * + * @license BSD http://www.opensource.org/licenses/bsd-license.php + * @link www.doctrine-project.com + * @since 2.0 + * @author Benjamin Eberlei + * @author David Coallier + */ +class OracleKeywords extends KeywordList +{ + public function getName() + { + return 'Oracle'; + } + + protected function getKeywords() + { + return array( + 'ACCESS', + 'ELSE', + 'MODIFY', + 'START', + 'ADD', + 'EXCLUSIVE', + 'NOAUDIT', + 'SELECT', + 'ALL', + 'EXISTS', + 'NOCOMPRESS', + 'SESSION', + 'ALTER', + 'FILE', + 'NOT', + 'SET', + 'AND', + 'FLOAT', + 'NOTFOUND ', + 'SHARE', + 'ANY', + 'FOR', + 'NOWAIT', + 'SIZE', + 'ARRAYLEN', + 'FROM', + 'NULL', + 'SMALLINT', + 'AS', + 'GRANT', + 'NUMBER', + 'SQLBUF', + 'ASC', + 'GROUP', + 'OF', + 'SUCCESSFUL', + 'AUDIT', + 'HAVING', + 'OFFLINE ', + 'SYNONYM', + 'BETWEEN', + 'IDENTIFIED', + 'ON', + 'SYSDATE', + 'BY', + 'IMMEDIATE', + 'ONLINE', + 'TABLE', + 'CHAR', + 'IN', + 'OPTION', + 'THEN', + 'CHECK', + 'INCREMENT', + 'OR', + 'TO', + 'CLUSTER', + 'INDEX', + 'ORDER', + 'TRIGGER', + 'COLUMN', + 'INITIAL', + 'PCTFREE', + 'UID', + 'COMMENT', + 'INSERT', + 'PRIOR', + 'UNION', + 'COMPRESS', + 'INTEGER', + 'PRIVILEGES', + 'UNIQUE', + 'CONNECT', + 'INTERSECT', + 'PUBLIC', + 'UPDATE', + 'CREATE', + 'INTO', + 'RAW', + 'USER', + 'CURRENT', + 'IS', + 'RENAME', + 'VALIDATE', + 'DATE', + 'LEVEL', + 'RESOURCE', + 'VALUES', + 'DECIMAL', + 'LIKE', + 'REVOKE', + 'VARCHAR', + 'DEFAULT', + 'LOCK', + 'ROW', + 'VARCHAR2', + 'DELETE', + 'LONG', + 'ROWID', + 'VIEW', + 'DESC', + 'MAXEXTENTS', + 'ROWLABEL', + 'WHENEVER', + 'DISTINCT', + 'MINUS', + 'ROWNUM', + 'WHERE', + 'DROP', + 'MODE', + 'ROWS', + 'WITH', + ); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/PostgreSQLKeywords.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/PostgreSQLKeywords.php new file mode 100644 index 0000000..e5acea0 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/PostgreSQLKeywords.php @@ -0,0 +1,131 @@ +. + */ + + +namespace Doctrine\DBAL\Platforms\Keywords; + +/** + * PostgreSQL Keywordlist + * + * @license BSD http://www.opensource.org/licenses/bsd-license.php + * @link www.doctrine-project.com + * @since 2.0 + * @author Benjamin Eberlei + * @author Marcelo Santos Araujo + */ +class PostgreSQLKeywords extends KeywordList +{ + public function getName() + { + return 'PostgreSQL'; + } + + protected function getKeywords() + { + return array( + 'ALL', + 'ANALYSE', + 'ANALYZE', + 'AND', + 'ANY', + 'AS', + 'ASC', + 'AUTHORIZATION', + 'BETWEEN', + 'BINARY', + 'BOTH', + 'CASE', + 'CAST', + 'CHECK', + 'COLLATE', + 'COLUMN', + 'CONSTRAINT', + 'CREATE', + 'CURRENT_DATE', + 'CURRENT_TIME', + 'CURRENT_TIMESTAMP', + 'CURRENT_USER', + 'DEFAULT', + 'DEFERRABLE', + 'DESC', + 'DISTINCT', + 'DO', + 'ELSE', + 'END', + 'EXCEPT', + 'FALSE', + 'FOR', + 'FOREIGN', + 'FREEZE', + 'FROM', + 'FULL', + 'GRANT', + 'GROUP', + 'HAVING', + 'ILIKE', + 'IN', + 'INITIALLY', + 'INNER', + 'INTERSECT', + 'INTO', + 'IS', + 'ISNULL', + 'JOIN', + 'LEADING', + 'LEFT', + 'LIKE', + 'LIMIT', + 'LOCALTIME', + 'LOCALTIMESTAMP', + 'NATURAL', + 'NEW', + 'NOT', + 'NOTNULL', + 'NULL', + 'OFF', + 'OFFSET', + 'OLD', + 'ON', + 'ONLY', + 'OR', + 'ORDER', + 'OUTER', + 'OVERLAPS', + 'PLACING', + 'PRIMARY', + 'REFERENCES', + 'SELECT', + 'SESSION_USER', + 'SIMILAR', + 'SOME', + 'TABLE', + 'THEN', + 'TO', + 'TRAILING', + 'TRUE', + 'UNION', + 'UNIQUE', + 'USER', + 'USING', + 'VERBOSE', + 'WHEN', + 'WHERE' + ); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/ReservedKeywordsValidator.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/ReservedKeywordsValidator.php new file mode 100644 index 0000000..5c99ba3 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/ReservedKeywordsValidator.php @@ -0,0 +1,116 @@ +. + */ + + +namespace Doctrine\DBAL\Platforms\Keywords; + +use Doctrine\DBAL\Schema\Visitor\Visitor; +use Doctrine\DBAL\Schema\Table; +use Doctrine\DBAL\Schema\Column; +use Doctrine\DBAL\Schema\ForeignKeyConstraint; +use Doctrine\DBAL\Schema\Schema; +use Doctrine\DBAL\Schema\Sequence; +use Doctrine\DBAL\Schema\Index; + +class ReservedKeywordsValidator implements Visitor +{ + /** + * @var KeywordList[] + */ + private $keywordLists = array(); + + /** + * @var array + */ + private $violations = array(); + + public function __construct(array $keywordLists) + { + $this->keywordLists = $keywordLists; + } + + public function getViolations() + { + return $this->violations; + } + + /** + * @param string $word + * @return array + */ + private function isReservedWord($word) + { + if ($word[0] == "`") { + $word = str_replace('`', '', $word); + } + + $keywordLists = array(); + foreach ($this->keywordLists AS $keywordList) { + if ($keywordList->isKeyword($word)) { + $keywordLists[] = $keywordList->getName(); + } + } + return $keywordLists; + } + + private function addViolation($asset, $violatedPlatforms) + { + if (!$violatedPlatforms) { + return; + } + + $this->violations[] = $asset . ' keyword violations: ' . implode(', ', $violatedPlatforms); + } + + public function acceptColumn(Table $table, Column $column) + { + $this->addViolation( + 'Table ' . $table->getName() . ' column ' . $column->getName(), + $this->isReservedWord($column->getName()) + ); + } + + public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint) + { + + } + + public function acceptIndex(Table $table, Index $index) + { + + } + + public function acceptSchema(Schema $schema) + { + + } + + public function acceptSequence(Sequence $sequence) + { + + } + + public function acceptTable(Table $table) + { + $this->addViolation( + 'Table ' . $table->getName(), + $this->isReservedWord($table->getName()) + ); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLiteKeywords.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLiteKeywords.php new file mode 100644 index 0000000..4d12aff --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLiteKeywords.php @@ -0,0 +1,164 @@ +. + */ + + +namespace Doctrine\DBAL\Platforms\Keywords; + +/** + * SQLite Keywords + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.0 + * @author Benjamin Eberlei + */ +class SQLiteKeywords extends KeywordList +{ + public function getName() + { + return 'SQLite'; + } + + protected function getKeywords() + { + return array( + 'ABORT', + 'ACTION', + 'ADD', + 'AFTER', + 'ALL', + 'ALTER', + 'ANALYZE', + 'AND', + 'AS', + 'ASC', + 'ATTACH', + 'AUTOINCREMENT', + 'BEFORE', + 'BEGIN', + 'BETWEEN', + 'BY', + 'CASCADE', + 'CASE', + 'CAST', + 'CHECK', + 'COLLATE', + 'COLUMN', + 'COMMIT', + 'CONFLICT', + 'CONSTRAINT', + 'CREATE', + 'CROSS', + 'CURRENT_DATE', + 'CURRENT_TIME', + 'CURRENT_TIMESTAMP', + 'DATABASE', + 'DEFAULT', + 'DEFERRABLE', + 'DEFERRED', + 'DELETE', + 'DESC', + 'DETACH', + 'DISTINCT', + 'DROP', + 'EACH', + 'ELSE', + 'END', + 'ESCAPE', + 'EXCEPT', + 'EXCLUSIVE', + 'EXISTS', + 'EXPLAIN', + 'FAIL', + 'FOR', + 'FOREIGN', + 'FROM', + 'FULL', + 'GLOB', + 'GROUP', + 'HAVING', + 'IF', + 'IGNORE', + 'IMMEDIATE', + 'IN', + 'INDEX', + 'INDEXED', + 'INITIALLY', + 'INNER', + 'INSERT', + 'INSTEAD', + 'INTERSECT', + 'INTO', + 'IS', + 'ISNULL', + 'JOIN', + 'KEY', + 'LEFT', + 'LIKE', + 'LIMIT', + 'MATCH', + 'NATURAL', + 'NO', + 'NOT', + 'NOTNULL', + 'NULL', + 'OF', + 'OFFSET', + 'ON', + 'OR', + 'ORDER', + 'OUTER', + 'PLAN', + 'PRAGMA', + 'PRIMARY', + 'QUERY', + 'RAISE', + 'REFERENCES', + 'REGEXP', + 'REINDEX', + 'RELEASE', + 'RENAME', + 'REPLACE', + 'RESTRICT', + 'RIGHT', + 'ROLLBACK', + 'ROW', + 'SAVEPOINT', + 'SELECT', + 'SET', + 'TABLE', + 'TEMP', + 'TEMPORARY', + 'THEN', + 'TO', + 'TRANSACTION', + 'TRIGGER', + 'UNION', + 'UNIQUE', + 'UPDATE', + 'USING', + 'VACUUM', + 'VALUES', + 'VIEW', + 'VIRTUAL', + 'WHEN', + 'WHERE' + ); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php new file mode 100644 index 0000000..8520e45 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php @@ -0,0 +1,768 @@ +. + */ + +namespace Doctrine\DBAL\Platforms; + +use Doctrine\DBAL\DBALException, + Doctrine\DBAL\Schema\TableDiff, + Doctrine\DBAL\Schema\Index, + Doctrine\DBAL\Schema\Table; + +/** + * The MySqlPlatform provides the behavior, features and SQL dialect of the + * MySQL database platform. This platform represents a MySQL 5.0 or greater platform that + * uses the InnoDB storage engine. + * + * @since 2.0 + * @author Roman Borschel + * @author Benjamin Eberlei + * @todo Rename: MySQLPlatform + */ +class MySqlPlatform extends AbstractPlatform +{ + /** + * Gets the character used for identifier quoting. + * + * @return string + * @override + */ + public function getIdentifierQuoteCharacter() + { + return '`'; + } + + /** + * Returns the regular expression operator. + * + * @return string + * @override + */ + public function getRegexpExpression() + { + return 'RLIKE'; + } + + /** + * Returns global unique identifier + * + * @return string to get global unique identifier + * @override + */ + public function getGuidExpression() + { + return 'UUID()'; + } + + /** + * returns the position of the first occurrence of substring $substr in string $str + * + * @param string $substr literal string to find + * @param string $str literal string + * @param int $pos position to start at, beginning of string by default + * @return integer + */ + public function getLocateExpression($str, $substr, $startPos = false) + { + if ($startPos == false) { + return 'LOCATE(' . $substr . ', ' . $str . ')'; + } else { + return 'LOCATE(' . $substr . ', ' . $str . ', '.$startPos.')'; + } + } + + /** + * Returns a series of strings concatinated + * + * concat() accepts an arbitrary number of parameters. Each parameter + * must contain an expression or an array with expressions. + * + * @param string|array(string) strings that will be concatinated. + * @override + */ + public function getConcatExpression() + { + $args = func_get_args(); + return 'CONCAT(' . join(', ', (array) $args) . ')'; + } + + public function getDateDiffExpression($date1, $date2) + { + return 'DATEDIFF(' . $date1 . ', ' . $date2 . ')'; + } + + public function getDateAddDaysExpression($date, $days) + { + return 'DATE_ADD(' . $date . ', INTERVAL ' . $days . ' DAY)'; + } + + public function getDateSubDaysExpression($date, $days) + { + return 'DATE_SUB(' . $date . ', INTERVAL ' . $days . ' DAY)'; + } + + public function getDateAddMonthExpression($date, $months) + { + return 'DATE_ADD(' . $date . ', INTERVAL ' . $months . ' MONTH)'; + } + + public function getDateSubMonthExpression($date, $months) + { + return 'DATE_SUB(' . $date . ', INTERVAL ' . $months . ' MONTH)'; + } + + public function getListDatabasesSQL() + { + return 'SHOW DATABASES'; + } + + public function getListTableConstraintsSQL($table) + { + return 'SHOW INDEX FROM ' . $table; + } + + /** + * Two approaches to listing the table indexes. The information_schema is + * prefered, because it doesn't cause problems with SQL keywords such as "order" or "table". + * + * @param string $table + * @param string $currentDatabase + * @return string + */ + public function getListTableIndexesSQL($table, $currentDatabase = null) + { + if ($currentDatabase) { + return "SELECT TABLE_NAME AS `Table`, NON_UNIQUE AS Non_Unique, INDEX_NAME AS Key_name, ". + "SEQ_IN_INDEX AS Seq_in_index, COLUMN_NAME AS Column_Name, COLLATION AS Collation, ". + "CARDINALITY AS Cardinality, SUB_PART AS Sub_Part, PACKED AS Packed, " . + "NULLABLE AS `Null`, INDEX_TYPE AS Index_Type, COMMENT AS Comment " . + "FROM information_schema.STATISTICS WHERE TABLE_NAME = '" . $table . "' AND TABLE_SCHEMA = '" . $currentDatabase . "'"; + } else { + return 'SHOW INDEX FROM ' . $table; + } + } + + public function getListViewsSQL($database) + { + return "SELECT * FROM information_schema.VIEWS WHERE TABLE_SCHEMA = '".$database."'"; + } + + public function getListTableForeignKeysSQL($table, $database = null) + { + $sql = "SELECT DISTINCT k.`CONSTRAINT_NAME`, k.`COLUMN_NAME`, k.`REFERENCED_TABLE_NAME`, ". + "k.`REFERENCED_COLUMN_NAME` /*!50116 , c.update_rule, c.delete_rule */ ". + "FROM information_schema.key_column_usage k /*!50116 ". + "INNER JOIN information_schema.referential_constraints c ON ". + " c.constraint_name = k.constraint_name AND ". + " c.table_name = '$table' */ WHERE k.table_name = '$table'"; + + if ($database) { + $sql .= " AND k.table_schema = '$database' /*!50116 AND c.constraint_schema = '$database' */"; + } + + $sql .= " AND k.`REFERENCED_COLUMN_NAME` is not NULL"; + + return $sql; + } + + public function getCreateViewSQL($name, $sql) + { + return 'CREATE VIEW ' . $name . ' AS ' . $sql; + } + + public function getDropViewSQL($name) + { + return 'DROP VIEW '. $name; + } + + /** + * Gets the SQL snippet used to declare a VARCHAR column on the MySql platform. + * + * @params array $field + */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) + { + return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)') + : ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)'); + } + + /** @override */ + public function getClobTypeDeclarationSQL(array $field) + { + if ( ! empty($field['length']) && is_numeric($field['length'])) { + $length = $field['length']; + if ($length <= 255) { + return 'TINYTEXT'; + } else if ($length <= 65532) { + return 'TEXT'; + } else if ($length <= 16777215) { + return 'MEDIUMTEXT'; + } + } + return 'LONGTEXT'; + } + + /** + * @override + */ + public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) + { + if (isset($fieldDeclaration['version']) && $fieldDeclaration['version'] == true) { + return 'TIMESTAMP'; + } else { + return 'DATETIME'; + } + } + + /** + * @override + */ + public function getDateTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATE'; + } + + /** + * @override + */ + public function getTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'TIME'; + } + + /** + * @override + */ + public function getBooleanTypeDeclarationSQL(array $field) + { + return 'TINYINT(1)'; + } + + /** + * Obtain DBMS specific SQL code portion needed to set the COLLATION + * of a field declaration to be used in statements like CREATE TABLE. + * + * @param string $collation name of the collation + * @return string DBMS specific SQL code portion needed to set the COLLATION + * of a field declaration. + */ + public function getCollationFieldDeclaration($collation) + { + return 'COLLATE ' . $collation; + } + + /** + * Whether the platform prefers identity columns for ID generation. + * MySql prefers "autoincrement" identity columns since sequences can only + * be emulated with a table. + * + * @return boolean + * @override + */ + public function prefersIdentityColumns() + { + return true; + } + + /** + * Whether the platform supports identity columns. + * MySql supports this through AUTO_INCREMENT columns. + * + * @return boolean + * @override + */ + public function supportsIdentityColumns() + { + return true; + } + + public function supportsInlineColumnComments() + { + return true; + } + + public function getShowDatabasesSQL() + { + return 'SHOW DATABASES'; + } + + public function getListTablesSQL() + { + return "SHOW FULL TABLES WHERE Table_type = 'BASE TABLE'"; + } + + public function getListTableColumnsSQL($table, $database = null) + { + if ($database) { + return "SELECT COLUMN_NAME AS Field, COLUMN_TYPE AS Type, IS_NULLABLE AS `Null`, ". + "COLUMN_KEY AS `Key`, COLUMN_DEFAULT AS `Default`, EXTRA AS Extra, COLUMN_COMMENT AS Comment, " . + "CHARACTER_SET_NAME AS CharacterSet, COLLATION_NAME AS CollactionName ". + "FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = '" . $database . "' AND TABLE_NAME = '" . $table . "'"; + } else { + return 'DESCRIBE ' . $table; + } + } + + /** + * create a new database + * + * @param string $name name of the database that should be created + * @return string + * @override + */ + public function getCreateDatabaseSQL($name) + { + return 'CREATE DATABASE ' . $name; + } + + /** + * drop an existing database + * + * @param string $name name of the database that should be dropped + * @return string + * @override + */ + public function getDropDatabaseSQL($name) + { + return 'DROP DATABASE ' . $name; + } + + /** + * create a new table + * + * @param string $tableName Name of the database that should be created + * @param array $columns Associative array that contains the definition of each field of the new table + * The indexes of the array entries are the names of the fields of the table an + * the array entry values are associative arrays like those that are meant to be + * passed with the field definitions to get[Type]Declaration() functions. + * array( + * 'id' => array( + * 'type' => 'integer', + * 'unsigned' => 1 + * 'notnull' => 1 + * 'default' => 0 + * ), + * 'name' => array( + * 'type' => 'text', + * 'length' => 12 + * ), + * 'password' => array( + * 'type' => 'text', + * 'length' => 12 + * ) + * ); + * @param array $options An associative array of table options: + * array( + * 'comment' => 'Foo', + * 'charset' => 'utf8', + * 'collate' => 'utf8_unicode_ci', + * 'engine' => 'innodb', + * 'foreignKeys' => array( + * new ForeignKeyConstraint(), + * new ForeignKeyConstraint(), + * new ForeignKeyConstraint(), + * // etc + * ) + * ); + * + * @return void + * @override + */ + protected function _getCreateTableSQL($tableName, array $columns, array $options = array()) + { + $queryFields = $this->getColumnDeclarationListSQL($columns); + + if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) { + foreach ($options['uniqueConstraints'] as $index => $definition) { + $queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($index, $definition); + } + } + + // add all indexes + if (isset($options['indexes']) && ! empty($options['indexes'])) { + foreach($options['indexes'] as $index => $definition) { + $queryFields .= ', ' . $this->getIndexDeclarationSQL($index, $definition); + } + } + + // attach all primary keys + if (isset($options['primary']) && ! empty($options['primary'])) { + $keyColumns = array_unique(array_values($options['primary'])); + $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')'; + } + + $query = 'CREATE '; + if (!empty($options['temporary'])) { + $query .= 'TEMPORARY '; + } + $query.= 'TABLE ' . $tableName . ' (' . $queryFields . ')'; + + $optionStrings = array(); + + if (isset($options['comment'])) { + $optionStrings['comment'] = 'COMMENT = ' . $options['comment']; + } + if (isset($options['charset'])) { + $optionStrings['charset'] = 'DEFAULT CHARACTER SET ' . $options['charset']; + if (isset($options['collate'])) { + $optionStrings['charset'] .= ' COLLATE ' . $options['collate']; + } + } + + // get the type of the table + if (isset($options['engine'])) { + $optionStrings[] = 'ENGINE = ' . $options['engine']; + } else { + // default to innodb + $optionStrings[] = 'ENGINE = InnoDB'; + } + + if ( ! empty($optionStrings)) { + $query.= ' '.implode(' ', $optionStrings); + } + $sql[] = $query; + + if (isset($options['foreignKeys'])) { + foreach ((array) $options['foreignKeys'] as $definition) { + $sql[] = $this->getCreateForeignKeySQL($definition, $tableName); + } + } + + return $sql; + } + + /** + * Gets the SQL to alter an existing table. + * + * @param TableDiff $diff + * @return array + */ + public function getAlterTableSQL(TableDiff $diff) + { + $columnSql = array(); + $queryParts = array(); + if ($diff->newName !== false) { + $queryParts[] = 'RENAME TO ' . $diff->newName; + } + + foreach ($diff->addedColumns AS $fieldName => $column) { + if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { + continue; + } + + $columnArray = $column->toArray(); + $columnArray['comment'] = $this->getColumnComment($column); + $queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray); + } + + foreach ($diff->removedColumns AS $column) { + if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) { + continue; + } + + $queryParts[] = 'DROP ' . $column->getQuotedName($this); + } + + foreach ($diff->changedColumns AS $columnDiff) { + if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { + continue; + } + + /* @var $columnDiff Doctrine\DBAL\Schema\ColumnDiff */ + $column = $columnDiff->column; + $columnArray = $column->toArray(); + $columnArray['comment'] = $this->getColumnComment($column); + $queryParts[] = 'CHANGE ' . ($columnDiff->oldColumnName) . ' ' + . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray); + } + + foreach ($diff->renamedColumns AS $oldColumnName => $column) { + if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { + continue; + } + + $columnArray = $column->toArray(); + $columnArray['comment'] = $this->getColumnComment($column); + $queryParts[] = 'CHANGE ' . $oldColumnName . ' ' + . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray); + } + + $sql = array(); + $tableSql = array(); + + if (!$this->onSchemaAlterTable($diff, $tableSql)) { + if (count($queryParts) > 0) { + $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . implode(", ", $queryParts); + } + $sql = array_merge( + $this->getPreAlterTableIndexForeignKeySQL($diff), + $sql, + $this->getPostAlterTableIndexForeignKeySQL($diff) + ); + } + + return array_merge($sql, $tableSql, $columnSql); + } + + /** + * Fix for DROP/CREATE index after foreign key change from OneToOne to ManyToOne + * + * @param TableDiff $diff + * @return array + */ + protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff) + { + $sql = array(); + $table = $diff->name; + + foreach ($diff->removedIndexes AS $remKey => $remIndex) { + + foreach ($diff->addedIndexes as $addKey => $addIndex) { + if ($remIndex->getColumns() == $addIndex->getColumns()) { + + $columns = $addIndex->getColumns(); + $type = ''; + if ($addIndex->isUnique()) { + $type = 'UNIQUE '; + } + + $query = 'ALTER TABLE ' . $table . ' DROP INDEX ' . $remIndex->getName() . ', '; + $query .= 'ADD ' . $type . 'INDEX ' . $addIndex->getName(); + $query .= ' (' . $this->getIndexFieldDeclarationListSQL($columns) . ')'; + + $sql[] = $query; + + unset($diff->removedIndexes[$remKey]); + unset($diff->addedIndexes[$addKey]); + + break; + } + } + } + + $sql = array_merge($sql, parent::getPreAlterTableIndexForeignKeySQL($diff)); + + return $sql; + } + + /** + * Obtain DBMS specific SQL code portion needed to declare an integer type + * field to be used in statements like CREATE TABLE. + * + * @param string $name name the field to be declared. + * @param string $field associative array with the name of the properties + * of the field being declared as array indexes. + * Currently, the types of supported field + * properties are as follows: + * + * unsigned + * Boolean flag that indicates whether the field + * should be declared as unsigned integer if + * possible. + * + * default + * Integer value to be used as default for this + * field. + * + * notnull + * Boolean flag that indicates whether this field is + * constrained to not be set to null. + * @return string DBMS specific SQL code portion that should be used to + * declare the specified field. + * @override + */ + public function getIntegerTypeDeclarationSQL(array $field) + { + return 'INT' . $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** @override */ + public function getBigIntTypeDeclarationSQL(array $field) + { + return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** @override */ + public function getSmallIntTypeDeclarationSQL(array $field) + { + return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** @override */ + protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef) + { + $autoinc = ''; + if ( ! empty($columnDef['autoincrement'])) { + $autoinc = ' AUTO_INCREMENT'; + } + $unsigned = (isset($columnDef['unsigned']) && $columnDef['unsigned']) ? ' UNSIGNED' : ''; + + return $unsigned . $autoinc; + } + + /** + * Return the FOREIGN KEY query section dealing with non-standard options + * as MATCH, INITIALLY DEFERRED, ON UPDATE, ... + * + * @param ForeignKeyConstraint $foreignKey + * @return string + * @override + */ + public function getAdvancedForeignKeyOptionsSQL(\Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey) + { + $query = ''; + if ($foreignKey->hasOption('match')) { + $query .= ' MATCH ' . $foreignKey->getOption('match'); + } + $query .= parent::getAdvancedForeignKeyOptionsSQL($foreignKey); + return $query; + } + + /** + * Gets the SQL to drop an index of a table. + * + * @param Index $index name of the index to be dropped + * @param string|Table $table name of table that should be used in method + * @override + */ + public function getDropIndexSQL($index, $table=null) + { + if($index instanceof Index) { + $indexName = $index->getQuotedName($this); + } else if(is_string($index)) { + $indexName = $index; + } else { + throw new \InvalidArgumentException('MysqlPlatform::getDropIndexSQL() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.'); + } + + if($table instanceof Table) { + $table = $table->getQuotedName($this); + } else if(!is_string($table)) { + throw new \InvalidArgumentException('MysqlPlatform::getDropIndexSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.'); + } + + if ($index instanceof Index && $index->isPrimary()) { + // mysql primary keys are always named "PRIMARY", + // so we cannot use them in statements because of them being keyword. + return $this->getDropPrimaryKeySQL($table); + } + + return 'DROP INDEX ' . $indexName . ' ON ' . $table; + } + + /** + * @param Index $index + * @param Table $table + */ + protected function getDropPrimaryKeySQL($table) + { + return 'ALTER TABLE ' . $table . ' DROP PRIMARY KEY'; + } + + public function getSetTransactionIsolationSQL($level) + { + return 'SET SESSION TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level); + } + + /** + * Get the platform name for this instance. + * + * @return string + */ + public function getName() + { + return 'mysql'; + } + + public function getReadLockSQL() + { + return 'LOCK IN SHARE MODE'; + } + + protected function initializeDoctrineTypeMappings() + { + $this->doctrineTypeMapping = array( + 'tinyint' => 'boolean', + 'smallint' => 'smallint', + 'mediumint' => 'integer', + 'int' => 'integer', + 'integer' => 'integer', + 'bigint' => 'bigint', + 'tinytext' => 'text', + 'mediumtext' => 'text', + 'longtext' => 'text', + 'text' => 'text', + 'varchar' => 'string', + 'string' => 'string', + 'char' => 'string', + 'date' => 'date', + 'datetime' => 'datetime', + 'timestamp' => 'datetime', + 'time' => 'time', + 'float' => 'float', + 'double' => 'float', + 'real' => 'float', + 'decimal' => 'decimal', + 'numeric' => 'decimal', + 'year' => 'date', + 'longblob' => 'blob', + 'blob' => 'blob', + 'mediumblob' => 'blob', + 'tinyblob' => 'blob', + ); + } + + public function getVarcharMaxLength() + { + return 65535; + } + + protected function getReservedKeywordsClass() + { + return 'Doctrine\DBAL\Platforms\Keywords\MySQLKeywords'; + } + + /** + * Get SQL to safely drop a temporary table WITHOUT implicitly committing an open transaction. + * + * MySQL commits a transaction implicitly when DROP TABLE is executed, however not + * if DROP TEMPORARY TABLE is executed. + * + * @throws \InvalidArgumentException + * @param $table + * @return string + */ + public function getDropTemporaryTableSQL($table) + { + if ($table instanceof \Doctrine\DBAL\Schema\Table) { + $table = $table->getQuotedName($this); + } else if(!is_string($table)) { + throw new \InvalidArgumentException('getDropTableSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.'); + } + + return 'DROP TEMPORARY TABLE ' . $table; + } + + /** + * Gets the SQL Snippet used to declare a BLOB column type. + */ + public function getBlobTypeDeclarationSQL(array $field) + { + return 'LONGBLOB'; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/OraclePlatform.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/OraclePlatform.php new file mode 100644 index 0000000..215ea1c --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/OraclePlatform.php @@ -0,0 +1,840 @@ +. + */ + +namespace Doctrine\DBAL\Platforms; + +use Doctrine\DBAL\Schema\TableDiff; + +/** + * OraclePlatform. + * + * @since 2.0 + * @author Roman Borschel + * @author Lukas Smith (PEAR MDB2 library) + * @author Benjamin Eberlei + */ +class OraclePlatform extends AbstractPlatform +{ + /** + * return string to call a function to get a substring inside an SQL statement + * + * Note: Not SQL92, but common functionality. + * + * @param string $value an sql string literal or column name/alias + * @param integer $position where to start the substring portion + * @param integer $length the substring portion length + * @return string SQL substring function with given parameters + * @override + */ + public function getSubstringExpression($value, $position, $length = null) + { + if ($length !== null) { + return "SUBSTR($value, $position, $length)"; + } + + return "SUBSTR($value, $position)"; + } + + /** + * Return string to call a variable with the current timestamp inside an SQL statement + * There are three special variables for current date and time: + * - CURRENT_TIMESTAMP (date and time, TIMESTAMP type) + * - CURRENT_DATE (date, DATE type) + * - CURRENT_TIME (time, TIME type) + * + * @return string to call a variable with the current timestamp + * @override + */ + public function getNowExpression($type = 'timestamp') + { + switch ($type) { + case 'date': + case 'time': + case 'timestamp': + default: + return 'TO_CHAR(CURRENT_TIMESTAMP, \'YYYY-MM-DD HH24:MI:SS\')'; + } + } + + /** + * returns the position of the first occurrence of substring $substr in string $str + * + * @param string $substr literal string to find + * @param string $str literal string + * @param int $pos position to start at, beginning of string by default + * @return integer + */ + public function getLocateExpression($str, $substr, $startPos = false) + { + if ($startPos == false) { + return 'INSTR('.$str.', '.$substr.')'; + } else { + return 'INSTR('.$str.', '.$substr.', '.$startPos.')'; + } + } + + /** + * Returns global unique identifier + * + * @return string to get global unique identifier + * @override + */ + public function getGuidExpression() + { + return 'SYS_GUID()'; + } + + /** + * Get the number of days difference between two dates. + * + * Note: Since Oracle timestamp differences are calculated down to the microsecond we have to truncate + * them to the difference in days. This is obviously a restriction of the original functionality, but we + * need to make this a portable function. + * + * @param type $date1 + * @param type $date2 + * @return type + */ + public function getDateDiffExpression($date1, $date2) + { + return "TRUNC(TO_NUMBER(SUBSTR((" . $date1 . "-" . $date2 . "), 1, INSTR(" . $date1 . "-" . $date2 .", ' '))))"; + } + + /** + * {@inheritdoc} + */ + public function getDateAddDaysExpression($date, $days) + { + return '(' . $date . '+' . $days . ')'; + } + + /** + * {@inheritdoc} + */ + public function getDateSubDaysExpression($date, $days) + { + return '(' . $date . '-' . $days . ')'; + } + + /** + * {@inheritdoc} + */ + public function getDateAddMonthExpression($date, $months) + { + return "ADD_MONTHS(" . $date . ", " . $months . ")"; + } + + /** + * {@inheritdoc} + */ + public function getDateSubMonthExpression($date, $months) + { + return "ADD_MONTHS(" . $date . ", -" . $months . ")"; + } + + /** + * {@inheritdoc} + */ + public function getBitAndComparisonExpression($value1, $value2) + { + return 'BITAND('.$value1 . ', ' . $value2 . ')'; + } + + /** + * {@inheritdoc} + */ + public function getBitOrComparisonExpression($value1, $value2) + { + return '(' . $value1 . '-' . + $this->getBitAndComparisonExpression($value1, $value2) + . '+' . $value2 . ')'; + } + + /** + * Gets the SQL used to create a sequence that starts with a given value + * and increments by the given allocation size. + * + * Need to specifiy minvalue, since start with is hidden in the system and MINVALUE <= START WITH. + * Therefore we can use MINVALUE to be able to get a hint what START WITH was for later introspection + * in {@see listSequences()} + * + * @param \Doctrine\DBAL\Schema\Sequence $sequence + * @return string + */ + public function getCreateSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence) + { + return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) . + ' START WITH ' . $sequence->getInitialValue() . + ' MINVALUE ' . $sequence->getInitialValue() . + ' INCREMENT BY ' . $sequence->getAllocationSize(); + } + + public function getAlterSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence) + { + return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) . + ' INCREMENT BY ' . $sequence->getAllocationSize(); + } + + /** + * {@inheritdoc} + * + * @param string $sequenceName + * @override + */ + public function getSequenceNextValSQL($sequenceName) + { + return 'SELECT ' . $sequenceName . '.nextval FROM DUAL'; + } + + /** + * {@inheritdoc} + * + * @param integer $level + * @override + */ + public function getSetTransactionIsolationSQL($level) + { + return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level); + } + + protected function _getTransactionIsolationLevelSQL($level) + { + switch ($level) { + case \Doctrine\DBAL\Connection::TRANSACTION_READ_UNCOMMITTED: + return 'READ UNCOMMITTED'; + case \Doctrine\DBAL\Connection::TRANSACTION_READ_COMMITTED: + return 'READ COMMITTED'; + case \Doctrine\DBAL\Connection::TRANSACTION_REPEATABLE_READ: + case \Doctrine\DBAL\Connection::TRANSACTION_SERIALIZABLE: + return 'SERIALIZABLE'; + default: + return parent::_getTransactionIsolationLevelSQL($level); + } + } + + /** + * @override + */ + public function getBooleanTypeDeclarationSQL(array $field) + { + return 'NUMBER(1)'; + } + + /** + * @override + */ + public function getIntegerTypeDeclarationSQL(array $field) + { + return 'NUMBER(10)'; + } + + /** + * @override + */ + public function getBigIntTypeDeclarationSQL(array $field) + { + return 'NUMBER(20)'; + } + + /** + * @override + */ + public function getSmallIntTypeDeclarationSQL(array $field) + { + return 'NUMBER(5)'; + } + + /** + * @override + */ + public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'TIMESTAMP(0)'; + } + + /** + * @override + */ + public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration) + { + return 'TIMESTAMP(0) WITH TIME ZONE'; + } + + /** + * @override + */ + public function getDateTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATE'; + } + + /** + * @override + */ + public function getTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATE'; + } + + /** + * @override + */ + protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef) + { + return ''; + } + + /** + * Gets the SQL snippet used to declare a VARCHAR column on the Oracle platform. + * + * @params array $field + * @override + */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) + { + return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(2000)') + : ($length ? 'VARCHAR2(' . $length . ')' : 'VARCHAR2(4000)'); + } + + /** @override */ + public function getClobTypeDeclarationSQL(array $field) + { + return 'CLOB'; + } + + public function getListDatabasesSQL() + { + return 'SELECT username FROM all_users'; + } + + public function getListSequencesSQL($database) + { + return "SELECT sequence_name, min_value, increment_by FROM sys.all_sequences ". + "WHERE SEQUENCE_OWNER = '".strtoupper($database)."'"; + } + + /** + * + * @param string $table + * @param array $columns + * @param array $options + * @return array + */ + protected function _getCreateTableSQL($table, array $columns, array $options = array()) + { + $indexes = isset($options['indexes']) ? $options['indexes'] : array(); + $options['indexes'] = array(); + $sql = parent::_getCreateTableSQL($table, $columns, $options); + + foreach ($columns as $name => $column) { + if (isset($column['sequence'])) { + $sql[] = $this->getCreateSequenceSQL($column['sequence'], 1); + } + + if (isset($column['autoincrement']) && $column['autoincrement'] || + (isset($column['autoinc']) && $column['autoinc'])) { + $sql = array_merge($sql, $this->getCreateAutoincrementSql($name, $table)); + } + } + + if (isset($indexes) && ! empty($indexes)) { + foreach ($indexes as $indexName => $index) { + $sql[] = $this->getCreateIndexSQL($index, $table); + } + } + + return $sql; + } + + /** + * @license New BSD License + * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaOracleReader.html + * @param string $table + * @return string + */ + public function getListTableIndexesSQL($table, $currentDatabase = null) + { + $table = strtoupper($table); + + return "SELECT uind.index_name AS name, " . + " uind.index_type AS type, " . + " decode( uind.uniqueness, 'NONUNIQUE', 0, 'UNIQUE', 1 ) AS is_unique, " . + " uind_col.column_name AS column_name, " . + " uind_col.column_position AS column_pos, " . + " (SELECT ucon.constraint_type FROM user_constraints ucon WHERE ucon.constraint_name = uind.index_name) AS is_primary ". + "FROM user_indexes uind, user_ind_columns uind_col " . + "WHERE uind.index_name = uind_col.index_name AND uind_col.table_name = '$table' ORDER BY uind_col.column_position ASC"; + } + + public function getListTablesSQL() + { + return 'SELECT * FROM sys.user_tables'; + } + + public function getListViewsSQL($database) + { + return 'SELECT view_name, text FROM sys.user_views'; + } + + public function getCreateViewSQL($name, $sql) + { + return 'CREATE VIEW ' . $name . ' AS ' . $sql; + } + + public function getDropViewSQL($name) + { + return 'DROP VIEW '. $name; + } + + public function getCreateAutoincrementSql($name, $table, $start = 1) + { + $table = strtoupper($table); + $sql = array(); + + $indexName = $table . '_AI_PK'; + $definition = array( + 'primary' => true, + 'columns' => array($name => true), + ); + + $idx = new \Doctrine\DBAL\Schema\Index($indexName, array($name), true, true); + + $sql[] = 'DECLARE + constraints_Count NUMBER; +BEGIN + SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = \''.$table.'\' AND CONSTRAINT_TYPE = \'P\'; + IF constraints_Count = 0 OR constraints_Count = \'\' THEN + EXECUTE IMMEDIATE \''.$this->getCreateConstraintSQL($idx, $table).'\'; + END IF; +END;'; + + $sequenceName = $table . '_SEQ'; + $sequence = new \Doctrine\DBAL\Schema\Sequence($sequenceName, $start); + $sql[] = $this->getCreateSequenceSQL($sequence); + + $triggerName = $table . '_AI_PK'; + $sql[] = 'CREATE TRIGGER ' . $triggerName . ' + BEFORE INSERT + ON ' . $table . ' + FOR EACH ROW +DECLARE + last_Sequence NUMBER; + last_InsertID NUMBER; +BEGIN + SELECT ' . $sequenceName . '.NEXTVAL INTO :NEW.' . $name . ' FROM DUAL; + IF (:NEW.' . $name . ' IS NULL OR :NEW.'.$name.' = 0) THEN + SELECT ' . $sequenceName . '.NEXTVAL INTO :NEW.' . $name . ' FROM DUAL; + ELSE + SELECT NVL(Last_Number, 0) INTO last_Sequence + FROM User_Sequences + WHERE Sequence_Name = \'' . $sequenceName . '\'; + SELECT :NEW.' . $name . ' INTO last_InsertID FROM DUAL; + WHILE (last_InsertID > last_Sequence) LOOP + SELECT ' . $sequenceName . '.NEXTVAL INTO last_Sequence FROM DUAL; + END LOOP; + END IF; +END;'; + return $sql; + } + + public function getDropAutoincrementSql($table) + { + $table = strtoupper($table); + $trigger = $table . '_AI_PK'; + + if ($trigger) { + $sql[] = 'DROP TRIGGER ' . $trigger; + $sql[] = $this->getDropSequenceSQL($table.'_SEQ'); + + $indexName = $table . '_AI_PK'; + $sql[] = $this->getDropConstraintSQL($indexName, $table); + } + + return $sql; + } + + public function getListTableForeignKeysSQL($table) + { + $table = strtoupper($table); + + return "SELECT alc.constraint_name, + alc.DELETE_RULE, + alc.search_condition, + cols.column_name \"local_column\", + cols.position, + r_alc.table_name \"references_table\", + r_cols.column_name \"foreign_column\" + FROM user_cons_columns cols +LEFT JOIN user_constraints alc + ON alc.constraint_name = cols.constraint_name +LEFT JOIN user_constraints r_alc + ON alc.r_constraint_name = r_alc.constraint_name +LEFT JOIN user_cons_columns r_cols + ON r_alc.constraint_name = r_cols.constraint_name + AND cols.position = r_cols.position + WHERE alc.constraint_name = cols.constraint_name + AND alc.constraint_type = 'R' + AND alc.table_name = '".$table."'"; + } + + public function getListTableConstraintsSQL($table) + { + $table = strtoupper($table); + return 'SELECT * FROM user_constraints WHERE table_name = \'' . $table . '\''; + } + + public function getListTableColumnsSQL($table, $database = null) + { + $table = strtoupper($table); + + $tabColumnsTableName = "user_tab_columns"; + $ownerCondition = ''; + if(null !== $database){ + $database = strtoupper($database); + $tabColumnsTableName = "all_tab_columns"; + $ownerCondition = "AND c.owner = '".$database."'"; + } + + return "SELECT c.*, d.comments FROM $tabColumnsTableName c ". + "INNER JOIN user_col_comments d ON d.TABLE_NAME = c.TABLE_NAME AND d.COLUMN_NAME = c.COLUMN_NAME ". + "WHERE c.table_name = '" . $table . "' ".$ownerCondition." ORDER BY c.column_name"; + } + + /** + * + * @param \Doctrine\DBAL\Schema\Sequence $sequence + * @return string + */ + public function getDropSequenceSQL($sequence) + { + if ($sequence instanceof \Doctrine\DBAL\Schema\Sequence) { + $sequence = $sequence->getQuotedName($this); + } + + return 'DROP SEQUENCE ' . $sequence; + } + + /** + * @param ForeignKeyConstraint|string $foreignKey + * @param Table|string $table + * @return string + */ + public function getDropForeignKeySQL($foreignKey, $table) + { + if ($foreignKey instanceof \Doctrine\DBAL\Schema\ForeignKeyConstraint) { + $foreignKey = $foreignKey->getQuotedName($this); + } + + if ($table instanceof \Doctrine\DBAL\Schema\Table) { + $table = $table->getQuotedName($this); + } + + return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $foreignKey; + } + + public function getDropDatabaseSQL($database) + { + return 'DROP USER ' . $database . ' CASCADE'; + } + + /** + * Gets the sql statements for altering an existing table. + * + * The method returns an array of sql statements, since some platforms need several statements. + * + * @param string $diff->name name of the table that is intended to be changed. + * @param array $changes associative array that contains the details of each type * + * @param boolean $check indicates whether the function should just check if the DBMS driver + * can perform the requested table alterations if the value is true or + * actually perform them otherwise. + * @return array + */ + public function getAlterTableSQL(TableDiff $diff) + { + $sql = array(); + $commentsSQL = array(); + $columnSql = array(); + + $fields = array(); + foreach ($diff->addedColumns AS $column) { + if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { + continue; + } + + $fields[] = $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); + if ($comment = $this->getColumnComment($column)) { + $commentsSQL[] = $this->getCommentOnColumnSQL($diff->name, $column->getName(), $comment); + } + } + if (count($fields)) { + $sql[] = 'ALTER TABLE ' . $diff->name . ' ADD (' . implode(', ', $fields) . ')'; + } + + $fields = array(); + foreach ($diff->changedColumns AS $columnDiff) { + if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { + continue; + } + + $column = $columnDiff->column; + $fields[] = $column->getQuotedName($this). ' ' . $this->getColumnDeclarationSQL('', $column->toArray()); + if ($columnDiff->hasChanged('comment') && $comment = $this->getColumnComment($column)) { + $commentsSQL[] = $this->getCommentOnColumnSQL($diff->name, $column->getName(), $comment); + } + } + if (count($fields)) { + $sql[] = 'ALTER TABLE ' . $diff->name . ' MODIFY (' . implode(', ', $fields) . ')'; + } + + foreach ($diff->renamedColumns AS $oldColumnName => $column) { + if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { + continue; + } + + $sql[] = 'ALTER TABLE ' . $diff->name . ' RENAME COLUMN ' . $oldColumnName .' TO ' . $column->getQuotedName($this); + } + + $fields = array(); + foreach ($diff->removedColumns AS $column) { + if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) { + continue; + } + + $fields[] = $column->getQuotedName($this); + } + if (count($fields)) { + $sql[] = 'ALTER TABLE ' . $diff->name . ' DROP (' . implode(', ', $fields).')'; + } + + $tableSql = array(); + + if (!$this->onSchemaAlterTable($diff, $tableSql)) { + if ($diff->newName !== false) { + $sql[] = 'ALTER TABLE ' . $diff->name . ' RENAME TO ' . $diff->newName; + } + + $sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff), $commentsSQL); + } + + return array_merge($sql, $tableSql, $columnSql); + } + + /** + * Whether the platform prefers sequences for ID generation. + * + * @return boolean + */ + public function prefersSequences() + { + return true; + } + + public function supportsCommentOnStatement() + { + return true; + } + + /** + * Get the platform name for this instance + * + * @return string + */ + public function getName() + { + return 'oracle'; + } + + /** + * Adds an driver-specific LIMIT clause to the query + * + * @param string $query query to modify + * @param integer $limit limit the number of rows + * @param integer $offset start reading from given offset + * @return string the modified query + */ + protected function doModifyLimitQuery($query, $limit, $offset = null) + { + $limit = (int) $limit; + $offset = (int) $offset; + if (preg_match('/^\s*SELECT/i', $query)) { + if (!preg_match('/\sFROM\s/i', $query)) { + $query .= " FROM dual"; + } + if ($limit > 0) { + $max = $offset + $limit; + $column = '*'; + if ($offset > 0) { + $min = $offset + 1; + $query = 'SELECT * FROM (SELECT a.' . $column . ', rownum AS doctrine_rownum FROM (' . + $query . + ') a WHERE rownum <= ' . $max . ') WHERE doctrine_rownum >= ' . $min; + } else { + $query = 'SELECT a.' . $column . ' FROM (' . $query . ') a WHERE ROWNUM <= ' . $max; + } + } + } + return $query; + } + + /** + * Gets the character casing of a column in an SQL result set of this platform. + * + * Oracle returns all column names in SQL result sets in uppercase. + * + * @param string $column The column name for which to get the correct character casing. + * @return string The column name in the character casing used in SQL result sets. + */ + public function getSQLResultCasing($column) + { + return strtoupper($column); + } + + public function getCreateTemporaryTableSnippetSQL() + { + return "CREATE GLOBAL TEMPORARY TABLE"; + } + + public function getDateTimeTzFormatString() + { + return 'Y-m-d H:i:sP'; + } + + public function getDateFormatString() + { + return 'Y-m-d 00:00:00'; + } + + public function getTimeFormatString() + { + return '1900-01-01 H:i:s'; + } + + public function fixSchemaElementName($schemaElementName) + { + if (strlen($schemaElementName) > 30) { + // Trim it + return substr($schemaElementName, 0, 30); + } + return $schemaElementName; + } + + /** + * Maximum length of any given databse identifier, like tables or column names. + * + * @return int + */ + public function getMaxIdentifierLength() + { + return 30; + } + + /** + * Whether the platform supports sequences. + * + * @return boolean + */ + public function supportsSequences() + { + return true; + } + + public function supportsForeignKeyOnUpdate() + { + return false; + } + + /** + * Whether the platform supports releasing savepoints. + * + * @return boolean + */ + public function supportsReleaseSavepoints() + { + return false; + } + + /** + * @inheritdoc + */ + public function getTruncateTableSQL($tableName, $cascade = false) + { + return 'TRUNCATE TABLE '.$tableName; + } + + /** + * This is for test reasons, many vendors have special requirements for dummy statements. + * + * @return string + */ + public function getDummySelectSQL() + { + return 'SELECT 1 FROM DUAL'; + } + + protected function initializeDoctrineTypeMappings() + { + $this->doctrineTypeMapping = array( + 'integer' => 'integer', + 'number' => 'integer', + 'pls_integer' => 'boolean', + 'binary_integer' => 'boolean', + 'varchar' => 'string', + 'varchar2' => 'string', + 'nvarchar2' => 'string', + 'char' => 'string', + 'nchar' => 'string', + 'date' => 'datetime', + 'timestamp' => 'datetime', + 'timestamptz' => 'datetimetz', + 'float' => 'float', + 'long' => 'string', + 'clob' => 'text', + 'nclob' => 'text', + 'raw' => 'text', + 'long raw' => 'text', + 'rowid' => 'string', + 'urowid' => 'string', + 'blob' => 'blob', + ); + } + + /** + * Generate SQL to release a savepoint + * + * @param string $savepoint + * @return string + */ + public function releaseSavePoint($savepoint) + { + return ''; + } + + protected function getReservedKeywordsClass() + { + return 'Doctrine\DBAL\Platforms\Keywords\OracleKeywords'; + } + + /** + * Gets the SQL Snippet used to declare a BLOB column type. + */ + public function getBlobTypeDeclarationSQL(array $field) + { + return 'BLOB'; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php new file mode 100644 index 0000000..d398651 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php @@ -0,0 +1,792 @@ +. + */ + +namespace Doctrine\DBAL\Platforms; + +use Doctrine\DBAL\Schema\TableDiff, + Doctrine\DBAL\Schema\Table; + +/** + * PostgreSqlPlatform. + * + * @since 2.0 + * @author Roman Borschel + * @author Lukas Smith (PEAR MDB2 library) + * @author Benjamin Eberlei + * @todo Rename: PostgreSQLPlatform + */ +class PostgreSqlPlatform extends AbstractPlatform +{ + /** + * Returns part of a string. + * + * Note: Not SQL92, but common functionality. + * + * @param string $value the target $value the string or the string column. + * @param int $from extract from this characeter. + * @param int $len extract this amount of characters. + * @return string sql that extracts part of a string. + * @override + */ + public function getSubstringExpression($value, $from, $len = null) + { + if ($len === null) { + return 'SUBSTR(' . $value . ', ' . $from . ')'; + } else { + return 'SUBSTR(' . $value . ', ' . $from . ', ' . $len . ')'; + } + } + + /** + * Returns the SQL string to return the current system date and time. + * + * @return string + */ + public function getNowExpression() + { + return 'LOCALTIMESTAMP(0)'; + } + + /** + * regexp + * + * @return string the regular expression operator + * @override + */ + public function getRegexpExpression() + { + return 'SIMILAR TO'; + } + + /** + * returns the position of the first occurrence of substring $substr in string $str + * + * @param string $substr literal string to find + * @param string $str literal string + * @param int $pos position to start at, beginning of string by default + * @return integer + */ + public function getLocateExpression($str, $substr, $startPos = false) + { + if ($startPos !== false) { + $str = $this->getSubstringExpression($str, $startPos); + return 'CASE WHEN (POSITION('.$substr.' IN '.$str.') = 0) THEN 0 ELSE (POSITION('.$substr.' IN '.$str.') + '.($startPos-1).') END'; + } else { + return 'POSITION('.$substr.' IN '.$str.')'; + } + } + + public function getDateDiffExpression($date1, $date2) + { + return '(DATE(' . $date1 . ')-DATE(' . $date2 . '))'; + } + + public function getDateAddDaysExpression($date, $days) + { + return "(" . $date ." + (" . $days . " || ' day')::interval)"; + } + + public function getDateSubDaysExpression($date, $days) + { + return "(" . $date ." - (" . $days . " || ' day')::interval)"; + } + + public function getDateAddMonthExpression($date, $months) + { + return "(" . $date ." + (" . $months . " || ' month')::interval)"; + } + + public function getDateSubMonthExpression($date, $months) + { + return "(" . $date ." - (" . $months . " || ' month')::interval)"; + } + + /** + * parses a literal boolean value and returns + * proper sql equivalent + * + * @param string $value boolean value to be parsed + * @return string parsed boolean value + */ + /*public function parseBoolean($value) + { + return $value; + }*/ + + /** + * Whether the platform supports sequences. + * Postgres has native support for sequences. + * + * @return boolean + */ + public function supportsSequences() + { + return true; + } + + /** + * Whether the platform supports database schemas. + * + * @return boolean + */ + public function supportsSchemas() + { + return true; + } + + /** + * Whether the platform supports identity columns. + * Postgres supports these through the SERIAL keyword. + * + * @return boolean + */ + public function supportsIdentityColumns() + { + return true; + } + + public function supportsCommentOnStatement() + { + return true; + } + + /** + * Whether the platform prefers sequences for ID generation. + * + * @return boolean + */ + public function prefersSequences() + { + return true; + } + + public function getListDatabasesSQL() + { + return 'SELECT datname FROM pg_database'; + } + + public function getListSequencesSQL($database) + { + return "SELECT + c.relname, n.nspname AS schemaname + FROM + pg_class c, pg_namespace n + WHERE relkind = 'S' AND n.oid = c.relnamespace AND + (n.nspname NOT LIKE 'pg_%' AND n.nspname != 'information_schema')"; + } + + public function getListTablesSQL() + { + return "SELECT tablename AS table_name, schemaname AS schema_name + FROM pg_tables WHERE schemaname NOT LIKE 'pg_%' AND schemaname != 'information_schema' AND tablename != 'geometry_columns' AND tablename != 'spatial_ref_sys'"; + } + + public function getListViewsSQL($database) + { + return 'SELECT viewname, definition FROM pg_views'; + } + + public function getListTableForeignKeysSQL($table, $database = null) + { + return "SELECT r.conname, pg_catalog.pg_get_constraintdef(r.oid, true) as condef + FROM pg_catalog.pg_constraint r + WHERE r.conrelid = + ( + SELECT c.oid + FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n + WHERE " .$this->getTableWhereClause($table) ." AND n.oid = c.relnamespace + ) + AND r.contype = 'f'"; + } + + public function getCreateViewSQL($name, $sql) + { + return 'CREATE VIEW ' . $name . ' AS ' . $sql; + } + + public function getDropViewSQL($name) + { + return 'DROP VIEW '. $name; + } + + public function getListTableConstraintsSQL($table) + { + return "SELECT + relname + FROM + pg_class + WHERE oid IN ( + SELECT indexrelid + FROM pg_index, pg_class + WHERE pg_class.relname = '$table' + AND pg_class.oid = pg_index.indrelid + AND (indisunique = 't' OR indisprimary = 't') + )"; + } + + /** + * @license New BSD License + * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html + * @param string $table + * @return string + */ + public function getListTableIndexesSQL($table, $currentDatabase = null) + { + return "SELECT relname, pg_index.indisunique, pg_index.indisprimary, + pg_index.indkey, pg_index.indrelid + FROM pg_class, pg_index + WHERE oid IN ( + SELECT indexrelid + FROM pg_index si, pg_class sc, pg_namespace sn + WHERE " . $this->getTableWhereClause($table, 'sc', 'sn')." AND sc.oid=si.indrelid AND sc.relnamespace = sn.oid + ) AND pg_index.indexrelid = oid"; + } + + /** + * @param string $table + * @param string $classAlias + * @param string $namespaceAlias + * @return string + */ + private function getTableWhereClause($table, $classAlias = 'c', $namespaceAlias = 'n') + { + $whereClause = $namespaceAlias.".nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast') AND "; + if (strpos($table, ".") !== false) { + list($schema, $table) = explode(".", $table); + $schema = "'" . $schema . "'"; + } else { + $schema = "ANY(string_to_array((select setting from pg_catalog.pg_settings where name = 'search_path'),','))"; + } + $whereClause .= "$classAlias.relname = '" . $table . "' AND $namespaceAlias.nspname = $schema"; + + return $whereClause; + } + + public function getListTableColumnsSQL($table, $database = null) + { + return "SELECT + a.attnum, + a.attname AS field, + t.typname AS type, + format_type(a.atttypid, a.atttypmod) AS complete_type, + (SELECT t1.typname FROM pg_catalog.pg_type t1 WHERE t1.oid = t.typbasetype) AS domain_type, + (SELECT format_type(t2.typbasetype, t2.typtypmod) FROM pg_catalog.pg_type t2 + WHERE t2.typtype = 'd' AND t2.typname = format_type(a.atttypid, a.atttypmod)) AS domain_complete_type, + a.attnotnull AS isnotnull, + (SELECT 't' + FROM pg_index + WHERE c.oid = pg_index.indrelid + AND pg_index.indkey[0] = a.attnum + AND pg_index.indisprimary = 't' + ) AS pri, + (SELECT pg_attrdef.adsrc + FROM pg_attrdef + WHERE c.oid = pg_attrdef.adrelid + AND pg_attrdef.adnum=a.attnum + ) AS default, + (SELECT pg_description.description + FROM pg_description WHERE pg_description.objoid = c.oid AND a.attnum = pg_description.objsubid + ) AS comment + FROM pg_attribute a, pg_class c, pg_type t, pg_namespace n + WHERE ".$this->getTableWhereClause($table, 'c', 'n') ." + AND a.attnum > 0 + AND a.attrelid = c.oid + AND a.atttypid = t.oid + AND n.oid = c.relnamespace + ORDER BY a.attnum"; + } + + /** + * create a new database + * + * @param string $name name of the database that should be created + * @throws PDOException + * @return void + * @override + */ + public function getCreateDatabaseSQL($name) + { + return 'CREATE DATABASE ' . $name; + } + + /** + * drop an existing database + * + * @param string $name name of the database that should be dropped + * @throws PDOException + * @access public + */ + public function getDropDatabaseSQL($name) + { + return 'DROP DATABASE ' . $name; + } + + /** + * Return the FOREIGN KEY query section dealing with non-standard options + * as MATCH, INITIALLY DEFERRED, ON UPDATE, ... + * + * @param \Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey foreign key definition + * @return string + * @override + */ + public function getAdvancedForeignKeyOptionsSQL(\Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey) + { + $query = ''; + if ($foreignKey->hasOption('match')) { + $query .= ' MATCH ' . $foreignKey->getOption('match'); + } + $query .= parent::getAdvancedForeignKeyOptionsSQL($foreignKey); + if ($foreignKey->hasOption('deferrable') && $foreignKey->getOption('deferrable') !== false) { + $query .= ' DEFERRABLE'; + } else { + $query .= ' NOT DEFERRABLE'; + } + if ($foreignKey->hasOption('feferred') && $foreignKey->getOption('feferred') !== false) { + $query .= ' INITIALLY DEFERRED'; + } else { + $query .= ' INITIALLY IMMEDIATE'; + } + return $query; + } + + /** + * generates the sql for altering an existing table on postgresql + * + * @param string $name name of the table that is intended to be changed. + * @param array $changes associative array that contains the details of each type * + * @param boolean $check indicates whether the function should just check if the DBMS driver + * can perform the requested table alterations if the value is true or + * actually perform them otherwise. + * @see Doctrine_Export::alterTable() + * @return array + * @override + */ + public function getAlterTableSQL(TableDiff $diff) + { + $sql = array(); + $commentsSQL = array(); + $columnSql = array(); + + foreach ($diff->addedColumns as $column) { + if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { + continue; + } + + $query = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); + $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query; + if ($comment = $this->getColumnComment($column)) { + $commentsSQL[] = $this->getCommentOnColumnSQL($diff->name, $column->getName(), $comment); + } + } + + foreach ($diff->removedColumns as $column) { + if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) { + continue; + } + + $query = 'DROP ' . $column->getQuotedName($this); + $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query; + } + + foreach ($diff->changedColumns AS $columnDiff) { + if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { + continue; + } + + $oldColumnName = $columnDiff->oldColumnName; + $column = $columnDiff->column; + + if ($columnDiff->hasChanged('type')) { + $type = $column->getType(); + + // here was a server version check before, but DBAL API does not support this anymore. + $query = 'ALTER ' . $oldColumnName . ' TYPE ' . $type->getSqlDeclaration($column->toArray(), $this); + $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query; + } + if ($columnDiff->hasChanged('default')) { + $query = 'ALTER ' . $oldColumnName . ' SET ' . $this->getDefaultValueDeclarationSQL($column->toArray()); + $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query; + } + if ($columnDiff->hasChanged('notnull')) { + $query = 'ALTER ' . $oldColumnName . ' ' . ($column->getNotNull() ? 'SET' : 'DROP') . ' NOT NULL'; + $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query; + } + if ($columnDiff->hasChanged('autoincrement')) { + if ($column->getAutoincrement()) { + // add autoincrement + $seqName = $diff->name . '_' . $oldColumnName . '_seq'; + + $sql[] = "CREATE SEQUENCE " . $seqName; + $sql[] = "SELECT setval('" . $seqName . "', (SELECT MAX(" . $oldColumnName . ") FROM " . $diff->name . "))"; + $query = "ALTER " . $oldColumnName . " SET DEFAULT nextval('" . $seqName . "')"; + $sql[] = "ALTER TABLE " . $diff->name . " " . $query; + } else { + // Drop autoincrement, but do NOT drop the sequence. It might be re-used by other tables or have + $query = "ALTER " . $oldColumnName . " " . "DROP DEFAULT"; + $sql[] = "ALTER TABLE " . $diff->name . " " . $query; + } + } + if ($columnDiff->hasChanged('comment') && $comment = $this->getColumnComment($column)) { + $commentsSQL[] = $this->getCommentOnColumnSQL($diff->name, $column->getName(), $comment); + } + } + + foreach ($diff->renamedColumns as $oldColumnName => $column) { + if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { + continue; + } + + $sql[] = 'ALTER TABLE ' . $diff->name . ' RENAME COLUMN ' . $oldColumnName . ' TO ' . $column->getQuotedName($this); + } + + $tableSql = array(); + + if (!$this->onSchemaAlterTable($diff, $tableSql)) { + if ($diff->newName !== false) { + $sql[] = 'ALTER TABLE ' . $diff->name . ' RENAME TO ' . $diff->newName; + } + + $sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff), $commentsSQL); + } + + return array_merge($sql, $tableSql, $columnSql); + } + + /** + * Gets the SQL to create a sequence on this platform. + * + * @param \Doctrine\DBAL\Schema\Sequence $sequence + * @return string + */ + public function getCreateSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence) + { + return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) . + ' INCREMENT BY ' . $sequence->getAllocationSize() . + ' MINVALUE ' . $sequence->getInitialValue() . + ' START ' . $sequence->getInitialValue(); + } + + public function getAlterSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence) + { + return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) . + ' INCREMENT BY ' . $sequence->getAllocationSize(); + } + + /** + * Drop existing sequence + * @param \Doctrine\DBAL\Schema\Sequence $sequence + * @return string + */ + public function getDropSequenceSQL($sequence) + { + if ($sequence instanceof \Doctrine\DBAL\Schema\Sequence) { + $sequence = $sequence->getQuotedName($this); + } + return 'DROP SEQUENCE ' . $sequence; + } + + /** + * @param ForeignKeyConstraint|string $foreignKey + * @param Table|string $table + * @return string + */ + public function getDropForeignKeySQL($foreignKey, $table) + { + return $this->getDropConstraintSQL($foreignKey, $table); + } + + /** + * Gets the SQL used to create a table. + * + * @param unknown_type $tableName + * @param array $columns + * @param array $options + * @return unknown + */ + protected function _getCreateTableSQL($tableName, array $columns, array $options = array()) + { + $queryFields = $this->getColumnDeclarationListSQL($columns); + + if (isset($options['primary']) && ! empty($options['primary'])) { + $keyColumns = array_unique(array_values($options['primary'])); + $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')'; + } + + $query = 'CREATE TABLE ' . $tableName . ' (' . $queryFields . ')'; + + $sql[] = $query; + + if (isset($options['indexes']) && ! empty($options['indexes'])) { + foreach ($options['indexes'] AS $index) { + $sql[] = $this->getCreateIndexSQL($index, $tableName); + } + } + + if (isset($options['foreignKeys'])) { + foreach ((array) $options['foreignKeys'] as $definition) { + $sql[] = $this->getCreateForeignKeySQL($definition, $tableName); + } + } + + return $sql; + } + + /** + * Postgres wants boolean values converted to the strings 'true'/'false'. + * + * @param array $item + * @override + */ + public function convertBooleans($item) + { + if (is_array($item)) { + foreach ($item as $key => $value) { + if (is_bool($value) || is_numeric($item)) { + $item[$key] = ($value) ? 'true' : 'false'; + } + } + } else { + if (is_bool($item) || is_numeric($item)) { + $item = ($item) ? 'true' : 'false'; + } + } + return $item; + } + + public function getSequenceNextValSQL($sequenceName) + { + return "SELECT NEXTVAL('" . $sequenceName . "')"; + } + + public function getSetTransactionIsolationSQL($level) + { + return 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL ' + . $this->_getTransactionIsolationLevelSQL($level); + } + + /** + * @override + */ + public function getBooleanTypeDeclarationSQL(array $field) + { + return 'BOOLEAN'; + } + + /** + * @override + */ + public function getIntegerTypeDeclarationSQL(array $field) + { + if ( ! empty($field['autoincrement'])) { + return 'SERIAL'; + } + + return 'INT'; + } + + /** + * @override + */ + public function getBigIntTypeDeclarationSQL(array $field) + { + if ( ! empty($field['autoincrement'])) { + return 'BIGSERIAL'; + } + return 'BIGINT'; + } + + /** + * @override + */ + public function getSmallIntTypeDeclarationSQL(array $field) + { + return 'SMALLINT'; + } + + /** + * @override + */ + public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'TIMESTAMP(0) WITHOUT TIME ZONE'; + } + + /** + * @override + */ + public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration) + { + return 'TIMESTAMP(0) WITH TIME ZONE'; + } + + /** + * @override + */ + public function getDateTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATE'; + } + + /** + * @override + */ + public function getTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'TIME(0) WITHOUT TIME ZONE'; + } + + /** + * @override + */ + protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef) + { + return ''; + } + + /** + * Gets the SQL snippet used to declare a VARCHAR column on the MySql platform. + * + * @params array $field + * @override + */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) + { + return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)') + : ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)'); + } + + /** @override */ + public function getClobTypeDeclarationSQL(array $field) + { + return 'TEXT'; + } + + /** + * Get the platform name for this instance + * + * @return string + */ + public function getName() + { + return 'postgresql'; + } + + /** + * Gets the character casing of a column in an SQL result set. + * + * PostgreSQL returns all column names in SQL result sets in lowercase. + * + * @param string $column The column name for which to get the correct character casing. + * @return string The column name in the character casing used in SQL result sets. + */ + public function getSQLResultCasing($column) + { + return strtolower($column); + } + + public function getDateTimeTzFormatString() + { + return 'Y-m-d H:i:sO'; + } + + /** + * Get the insert sql for an empty insert statement + * + * @param string $tableName + * @param string $identifierColumnName + * @return string $sql + */ + public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName) + { + return 'INSERT INTO ' . $quotedTableName . ' (' . $quotedIdentifierColumnName . ') VALUES (DEFAULT)'; + } + + /** + * @inheritdoc + */ + public function getTruncateTableSQL($tableName, $cascade = false) + { + return 'TRUNCATE '.$tableName.' '.(($cascade)?'CASCADE':''); + } + + public function getReadLockSQL() + { + return 'FOR SHARE'; + } + + protected function initializeDoctrineTypeMappings() + { + $this->doctrineTypeMapping = array( + 'smallint' => 'smallint', + 'int2' => 'smallint', + 'serial' => 'integer', + 'serial4' => 'integer', + 'int' => 'integer', + 'int4' => 'integer', + 'integer' => 'integer', + 'bigserial' => 'bigint', + 'serial8' => 'bigint', + 'bigint' => 'bigint', + 'int8' => 'bigint', + 'bool' => 'boolean', + 'boolean' => 'boolean', + 'text' => 'text', + 'varchar' => 'string', + 'interval' => 'string', + '_varchar' => 'string', + 'char' => 'string', + 'bpchar' => 'string', + 'date' => 'date', + 'datetime' => 'datetime', + 'timestamp' => 'datetime', + 'timestamptz' => 'datetimetz', + 'time' => 'time', + 'timetz' => 'time', + 'float' => 'float', + 'float4' => 'float', + 'float8' => 'float', + 'double' => 'float', + 'double precision' => 'float', + 'real' => 'float', + 'decimal' => 'decimal', + 'money' => 'decimal', + 'numeric' => 'decimal', + 'year' => 'date', + 'bytea' => 'blob', + ); + } + + public function getVarcharMaxLength() + { + return 65535; + } + + protected function getReservedKeywordsClass() + { + return 'Doctrine\DBAL\Platforms\Keywords\PostgreSQLKeywords'; + } + + /** + * Gets the SQL Snippet used to declare a BLOB column type. + */ + public function getBlobTypeDeclarationSQL(array $field) + { + return 'BYTEA'; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServer2005Platform.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServer2005Platform.php new file mode 100644 index 0000000..2bbcee2 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServer2005Platform.php @@ -0,0 +1,52 @@ +. + */ + +namespace Doctrine\DBAL\Platforms; + +/** + * Platform to ensure compatibility of Doctrine with SQLServer2005 version and + * higher. + * + * Differences to SQL Server 2008 are: + * + * - DATETIME2 datatype does not exist, only DATETIME which has a precision of + * 3. This is not supported by PHP DateTime, so we are emulating it by + * setting .000 manually. + * - Starting with SQLServer2005 VARCHAR(MAX), VARBINARY(MAX) and + * NVARCHAR(max) replace the old TEXT, NTEXT and IMAGE types. See + * {@link http://www.sql-server-helper.com/faq/sql-server-2005-varchar-max-p01.aspx} + * for more information. + */ +class SQLServer2005Platform extends SQLServerPlatform +{ + /** + * @override + */ + public function supportsLimitOffset() + { + return true; + } + + /** @override */ + public function getClobTypeDeclarationSQL(array $field) + { + return 'VARCHAR(MAX)'; + } +} + diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServer2008Platform.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServer2008Platform.php new file mode 100644 index 0000000..2938d4a --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServer2008Platform.php @@ -0,0 +1,90 @@ +. + */ + +namespace Doctrine\DBAL\Platforms; + +/** + * Platform to ensure compatibility of Doctrine with SQLServer2008 version. + * + * Differences to SQL Server 2005 and before are that a new DATETIME2 type was + * introduced that has a higher precision. + */ +class SQLServer2008Platform extends SQLServer2005Platform +{ + /** + * @override + */ + public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) + { + // 3 - microseconds precision length + // http://msdn.microsoft.com/en-us/library/ms187819.aspx + return 'DATETIME2(6)'; + } + + /** + * @override + */ + public function getDateTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATE'; + } + + /** + * @override + */ + public function getTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'TIME(0)'; + } + + /** + * @override + */ + public function getDateTimeFormatString() + { + return 'Y-m-d H:i:s.u'; + } + + /** + * @override + */ + public function getDateFormatString() + { + return 'Y-m-d'; + } + + /** + * @override + */ + public function getTimeFormatString() + { + return 'H:i:s'; + } + + /** + * Adding Datetime2 Type + */ + protected function initializeDoctrineTypeMappings() + { + parent::initializeDoctrineTypeMappings(); + $this->doctrineTypeMapping['datetime2'] = 'datetime'; + $this->doctrineTypeMapping['date'] = 'date'; + $this->doctrineTypeMapping['time'] = 'time'; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php new file mode 100644 index 0000000..ddb075a --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php @@ -0,0 +1,865 @@ +. + */ + +namespace Doctrine\DBAL\Platforms; + +use Doctrine\DBAL\Schema\TableDiff; +use Doctrine\DBAL\DBALException; +use Doctrine\DBAL\Schema\Index, + Doctrine\DBAL\Schema\Table; + +/** + * The SQLServerPlatform provides the behavior, features and SQL dialect of the + * Microsoft SQL Server database platform. + * + * @since 2.0 + * @author Roman Borschel + * @author Jonathan H. Wage + * @author Benjamin Eberlei + */ +class SQLServerPlatform extends AbstractPlatform +{ + /** + * {@inheritDoc} + */ + public function getDateDiffExpression($date1, $date2) + { + return 'DATEDIFF(day, ' . $date2 . ',' . $date1 . ')'; + } + + public function getDateAddDaysExpression($date, $days) + { + return 'DATEADD(day, ' . $days . ', ' . $date . ')'; + } + + public function getDateSubDaysExpression($date, $days) + { + return 'DATEADD(day, -1 * ' . $days . ', ' . $date . ')'; + } + + public function getDateAddMonthExpression($date, $months) + { + return 'DATEADD(month, ' . $months . ', ' . $date . ')'; + } + + public function getDateSubMonthExpression($date, $months) + { + return 'DATEADD(month, -1 * ' . $months . ', ' . $date . ')'; + } + + /** + * Whether the platform prefers identity columns for ID generation. + * MsSql prefers "autoincrement" identity columns since sequences can only + * be emulated with a table. + * + * @return boolean + * @override + */ + public function prefersIdentityColumns() + { + return true; + } + + /** + * Whether the platform supports identity columns. + * MsSql supports this through AUTO_INCREMENT columns. + * + * @return boolean + * @override + */ + public function supportsIdentityColumns() + { + return true; + } + + /** + * Whether the platform supports releasing savepoints. + * + * @return boolean + */ + public function supportsReleaseSavepoints() + { + return false; + } + + /** + * create a new database + * + * @param string $name name of the database that should be created + * @return string + * @override + */ + public function getCreateDatabaseSQL($name) + { + return 'CREATE DATABASE ' . $name; + } + + /** + * drop an existing database + * + * @param string $name name of the database that should be dropped + * @return string + * @override + */ + public function getDropDatabaseSQL($name) + { + return 'DROP DATABASE ' . $name; + } + + /** + * @override + */ + public function supportsCreateDropDatabase() + { + return false; + } + + /** + * @override + */ + public function getDropForeignKeySQL($foreignKey, $table) + { + if ($foreignKey instanceof \Doctrine\DBAL\Schema\ForeignKeyConstraint) { + $foreignKey = $foreignKey->getQuotedName($this); + } + + if ($table instanceof \Doctrine\DBAL\Schema\Table) { + $table = $table->getQuotedName($this); + } + + return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $foreignKey; + } + + /** + * @override + */ + public function getDropIndexSQL($index, $table=null) + { + if ($index instanceof \Doctrine\DBAL\Schema\Index) { + $index_ = $index; + $index = $index->getQuotedName($this); + } else if (!is_string($index)) { + throw new \InvalidArgumentException('AbstractPlatform::getDropIndexSQL() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.'); + } + + if (!isset($table)) { + return 'DROP INDEX ' . $index; + } else { + if ($table instanceof \Doctrine\DBAL\Schema\Table) { + $table = $table->getQuotedName($this); + } + + return "IF EXISTS (SELECT * FROM sysobjects WHERE name = '$index') + ALTER TABLE " . $table . " DROP CONSTRAINT " . $index . " + ELSE + DROP INDEX " . $index . " ON " . $table; + } + } + + /** + * @override + */ + protected function _getCreateTableSQL($tableName, array $columns, array $options = array()) + { + // @todo does other code breaks because of this? + // foce primary keys to be not null + foreach ($columns as &$column) { + if (isset($column['primary']) && $column['primary']) { + $column['notnull'] = true; + } + } + + $columnListSql = $this->getColumnDeclarationListSQL($columns); + + if (isset($options['uniqueConstraints']) && !empty($options['uniqueConstraints'])) { + foreach ($options['uniqueConstraints'] as $name => $definition) { + $columnListSql .= ', ' . $this->getUniqueConstraintDeclarationSQL($name, $definition); + } + } + + if (isset($options['primary']) && !empty($options['primary'])) { + $columnListSql .= ', PRIMARY KEY(' . implode(', ', array_unique(array_values($options['primary']))) . ')'; + } + + $query = 'CREATE TABLE ' . $tableName . ' (' . $columnListSql; + + $check = $this->getCheckDeclarationSQL($columns); + if (!empty($check)) { + $query .= ', ' . $check; + } + $query .= ')'; + + $sql[] = $query; + + if (isset($options['indexes']) && !empty($options['indexes'])) { + foreach ($options['indexes'] AS $index) { + $sql[] = $this->getCreateIndexSQL($index, $tableName); + } + } + + if (isset($options['foreignKeys'])) { + foreach ((array) $options['foreignKeys'] AS $definition) { + $sql[] = $this->getCreateForeignKeySQL($definition, $tableName); + } + } + + return $sql; + } + + /** + * @override + */ + public function getUniqueConstraintDeclarationSQL($name, Index $index) + { + $constraint = parent::getUniqueConstraintDeclarationSQL($name, $index); + + $constraint = $this->_appendUniqueConstraintDefinition($constraint, $index); + + return $constraint; + } + + /** + * @override + */ + public function getCreateIndexSQL(Index $index, $table) + { + $constraint = parent::getCreateIndexSQL($index, $table); + + if ($index->isUnique()) { + $constraint = $this->_appendUniqueConstraintDefinition($constraint, $index); + } + + return $constraint; + } + + /** + * Extend unique key constraint with required filters + * + * @param string $sql + * @param Index $index + * @return string + */ + private function _appendUniqueConstraintDefinition($sql, Index $index) + { + $fields = array(); + foreach ($index->getColumns() as $field => $definition) { + if (!is_array($definition)) { + $field = $definition; + } + + $fields[] = $field . ' IS NOT NULL'; + } + + return $sql . ' WHERE ' . implode(' AND ', $fields); + } + + /** + * @override + */ + public function getAlterTableSQL(TableDiff $diff) + { + $queryParts = array(); + $sql = array(); + $columnSql = array(); + + if ($diff->newName !== false) { + $queryParts[] = 'RENAME TO ' . $diff->newName; + } + + foreach ($diff->addedColumns AS $fieldName => $column) { + if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { + continue; + } + + $queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); + } + + foreach ($diff->removedColumns AS $column) { + if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) { + continue; + } + + $queryParts[] = 'DROP COLUMN ' . $column->getQuotedName($this); + } + + foreach ($diff->changedColumns AS $columnDiff) { + if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { + continue; + } + + /* @var $columnDiff Doctrine\DBAL\Schema\ColumnDiff */ + $column = $columnDiff->column; + $queryParts[] = 'ALTER COLUMN ' . + $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); + } + + foreach ($diff->renamedColumns AS $oldColumnName => $column) { + if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { + continue; + } + + $sql[] = "sp_RENAME '". $diff->name. ".". $oldColumnName . "' , '".$column->getQuotedName($this)."', 'COLUMN'"; + $queryParts[] = 'ALTER COLUMN ' . + $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); + } + + $tableSql = array(); + + if ($this->onSchemaAlterTable($diff, $tableSql)) { + return array_merge($tableSql, $columnSql); + } + + foreach ($queryParts as $query) { + $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query; + } + + $sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff)); + + return array_merge($sql, $tableSql, $columnSql); + } + + /** + * @override + */ + public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName) + { + return 'INSERT INTO ' . $quotedTableName . ' DEFAULT VALUES'; + } + + /** + * @override + */ + public function getShowDatabasesSQL() + { + return 'SHOW DATABASES'; + } + + /** + * @override + */ + public function getListTablesSQL() + { + // "sysdiagrams" table must be ignored as it's internal SQL Server table for Database Diagrams + return "SELECT name FROM sysobjects WHERE type = 'U' AND name != 'sysdiagrams' ORDER BY name"; + } + + /** + * @override + */ + public function getListTableColumnsSQL($table, $database = null) + { + return "exec sp_columns @table_name = '" . $table . "'"; + } + + /** + * @override + */ + public function getListTableForeignKeysSQL($table, $database = null) + { + return "SELECT f.name AS ForeignKey, + SCHEMA_NAME (f.SCHEMA_ID) AS SchemaName, + OBJECT_NAME (f.parent_object_id) AS TableName, + COL_NAME (fc.parent_object_id,fc.parent_column_id) AS ColumnName, + SCHEMA_NAME (o.SCHEMA_ID) ReferenceSchemaName, + OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName, + COL_NAME(fc.referenced_object_id,fc.referenced_column_id) AS ReferenceColumnName, + f.delete_referential_action_desc, + f.update_referential_action_desc + FROM sys.foreign_keys AS f + INNER JOIN sys.foreign_key_columns AS fc + INNER JOIN sys.objects AS o ON o.OBJECT_ID = fc.referenced_object_id + ON f.OBJECT_ID = fc.constraint_object_id + WHERE OBJECT_NAME (f.parent_object_id) = '" . $table . "'"; + } + + /** + * @override + */ + public function getListTableIndexesSQL($table, $currentDatabase = null) + { + return "exec sp_helpindex '" . $table . "'"; + } + + /** + * @override + */ + public function getCreateViewSQL($name, $sql) + { + return 'CREATE VIEW ' . $name . ' AS ' . $sql; + } + + /** + * @override + */ + public function getListViewsSQL($database) + { + return "SELECT name FROM sysobjects WHERE type = 'V' ORDER BY name"; + } + + /** + * @override + */ + public function getDropViewSQL($name) + { + return 'DROP VIEW ' . $name; + } + + /** + * Returns the regular expression operator. + * + * @return string + * @override + */ + public function getRegexpExpression() + { + return 'RLIKE'; + } + + /** + * Returns global unique identifier + * + * @return string to get global unique identifier + * @override + */ + public function getGuidExpression() + { + return 'UUID()'; + } + + /** + * @override + */ + public function getLocateExpression($str, $substr, $startPos = false) + { + if ($startPos == false) { + return 'CHARINDEX(' . $substr . ', ' . $str . ')'; + } else { + return 'CHARINDEX(' . $substr . ', ' . $str . ', ' . $startPos . ')'; + } + } + + /** + * @override + */ + public function getModExpression($expression1, $expression2) + { + return $expression1 . ' % ' . $expression2; + } + + /** + * @override + */ + public function getTrimExpression($str, $pos = self::TRIM_UNSPECIFIED, $char = false) + { + $trimFn = ''; + + if (!$char) { + if ($pos == self::TRIM_LEADING) { + $trimFn = 'LTRIM'; + } else if ($pos == self::TRIM_TRAILING) { + $trimFn = 'RTRIM'; + } else { + return 'LTRIM(RTRIM(' . $str . '))'; + } + + return $trimFn . '(' . $str . ')'; + } else { + /** Original query used to get those expressions + declare @c varchar(100) = 'xxxBarxxx', @trim_char char(1) = 'x'; + declare @pat varchar(10) = '%[^' + @trim_char + ']%'; + select @c as string + , @trim_char as trim_char + , stuff(@c, 1, patindex(@pat, @c) - 1, null) as trim_leading + , reverse(stuff(reverse(@c), 1, patindex(@pat, reverse(@c)) - 1, null)) as trim_trailing + , reverse(stuff(reverse(stuff(@c, 1, patindex(@pat, @c) - 1, null)), 1, patindex(@pat, reverse(stuff(@c, 1, patindex(@pat, @c) - 1, null))) - 1, null)) as trim_both; + */ + $pattern = "'%[^' + $char + ']%'"; + + if ($pos == self::TRIM_LEADING) { + return 'stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str . ') - 1, null)'; + } else if ($pos == self::TRIM_TRAILING) { + return 'reverse(stuff(reverse(' . $str . '), 1, patindex(' . $pattern . ', reverse(' . $str . ')) - 1, null))'; + } else { + return 'reverse(stuff(reverse(stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str . ') - 1, null)), 1, patindex(' . $pattern . ', reverse(stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str . ') - 1, null))) - 1, null))'; + } + } + } + + /** + * @override + */ + public function getConcatExpression() + { + $args = func_get_args(); + return '(' . implode(' + ', $args) . ')'; + } + + public function getListDatabasesSQL() + { + return 'SELECT * FROM SYS.DATABASES'; + } + + /** + * @override + */ + public function getSubstringExpression($value, $from, $len = null) + { + if (!is_null($len)) { + return 'SUBSTRING(' . $value . ', ' . $from . ', ' . $len . ')'; + } + return 'SUBSTRING(' . $value . ', ' . $from . ', LEN(' . $value . ') - ' . $from . ' + 1)'; + } + + /** + * @override + */ + public function getLengthExpression($column) + { + return 'LEN(' . $column . ')'; + } + + /** + * @override + */ + public function getSetTransactionIsolationSQL($level) + { + return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level); + } + + /** + * @override + */ + public function getIntegerTypeDeclarationSQL(array $field) + { + return 'INT' . $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** + * @override + */ + public function getBigIntTypeDeclarationSQL(array $field) + { + return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** + * @override + */ + public function getSmallIntTypeDeclarationSQL(array $field) + { + return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** @override */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) + { + return $fixed ? ($length ? 'NCHAR(' . $length . ')' : 'CHAR(255)') : ($length ? 'NVARCHAR(' . $length . ')' : 'NVARCHAR(255)'); + } + + /** @override */ + public function getClobTypeDeclarationSQL(array $field) + { + return 'TEXT'; + } + + /** + * @override + */ + protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef) + { + $autoinc = ''; + if (!empty($columnDef['autoincrement'])) { + $autoinc = ' IDENTITY'; + } + $unsigned = (isset($columnDef['unsigned']) && $columnDef['unsigned']) ? ' UNSIGNED' : ''; + + return $unsigned . $autoinc; + } + + /** + * @override + */ + public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATETIME'; + } + + /** + * @override + */ + public function getDateTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATETIME'; + } + + /** + * @override + */ + public function getTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATETIME'; + } + + /** + * @override + */ + public function getBooleanTypeDeclarationSQL(array $field) + { + return 'BIT'; + } + + /** + * Adds an adapter-specific LIMIT clause to the SELECT statement. + * + * @param string $query + * @param integer $limit + * @param integer $offset + * @link http://lists.bestpractical.com/pipermail/rt-devel/2005-June/007339.html + * @return string + */ + protected function doModifyLimitQuery($query, $limit, $offset = null) + { + if ($limit > 0) { + if ($offset == 0) { + $query = preg_replace('/^(SELECT\s(DISTINCT\s)?)/i', '\1TOP ' . $limit . ' ', $query); + } else { + $orderby = stristr($query, 'ORDER BY'); + + if (!$orderby) { + $over = 'ORDER BY (SELECT 0)'; + } else { + $over = preg_replace('/\"[^,]*\".\"([^,]*)\"/i', '"inner_tbl"."$1"', $orderby); + } + + // Remove ORDER BY clause from $query + $query = preg_replace('/\s+ORDER BY(.*)/', '', $query); + $query = preg_replace('/^SELECT\s/', '', $query); + + $start = $offset + 1; + $end = $offset + $limit; + + $query = "SELECT * FROM (SELECT ROW_NUMBER() OVER ($over) AS \"doctrine_rownum\", $query) AS doctrine_tbl WHERE \"doctrine_rownum\" BETWEEN $start AND $end"; + } + } + + return $query; + } + + /** + * @override + */ + public function supportsLimitOffset() + { + return false; + } + + /** + * @override + */ + public function convertBooleans($item) + { + if (is_array($item)) { + foreach ($item as $key => $value) { + if (is_bool($value) || is_numeric($item)) { + $item[$key] = ($value) ? 1 : 0; + } + } + } else { + if (is_bool($item) || is_numeric($item)) { + $item = ($item) ? 1 : 0; + } + } + return $item; + } + + /** + * @override + */ + public function getCreateTemporaryTableSnippetSQL() + { + return "CREATE TABLE"; + } + + /** + * @override + */ + public function getTemporaryTableName($tableName) + { + return '#' . $tableName; + } + + /** + * @override + */ + public function getDateTimeFormatString() + { + return 'Y-m-d H:i:s.000'; + } + + /** + * @override + */ + public function getDateFormatString() + { + return 'Y-m-d H:i:s.000'; + } + + /** + * @override + */ + public function getTimeFormatString() + { + return 'Y-m-d H:i:s.000'; + } + + /** + * @override + */ + public function getDateTimeTzFormatString() + { + return $this->getDateTimeFormatString(); + } + + /** + * Get the platform name for this instance + * + * @return string + */ + public function getName() + { + return 'mssql'; + } + + /** + * @override + */ + protected function initializeDoctrineTypeMappings() + { + $this->doctrineTypeMapping = array( + 'bigint' => 'bigint', + 'numeric' => 'decimal', + 'bit' => 'boolean', + 'smallint' => 'smallint', + 'decimal' => 'decimal', + 'smallmoney' => 'integer', + 'int' => 'integer', + 'tinyint' => 'smallint', + 'money' => 'integer', + 'float' => 'float', + 'real' => 'float', + 'double' => 'float', + 'double precision' => 'float', + 'datetimeoffset' => 'datetimetz', + 'smalldatetime' => 'datetime', + 'datetime' => 'datetime', + 'char' => 'string', + 'varchar' => 'string', + 'text' => 'text', + 'nchar' => 'string', + 'nvarchar' => 'string', + 'ntext' => 'text', + 'binary' => 'text', + 'varbinary' => 'blob', + 'image' => 'text', + ); + } + + /** + * Generate SQL to create a new savepoint + * + * @param string $savepoint + * @return string + */ + public function createSavePoint($savepoint) + { + return 'SAVE TRANSACTION ' . $savepoint; + } + + /** + * Generate SQL to release a savepoint + * + * @param string $savepoint + * @return string + */ + public function releaseSavePoint($savepoint) + { + return ''; + } + + /** + * Generate SQL to rollback a savepoint + * + * @param string $savepoint + * @return string + */ + public function rollbackSavePoint($savepoint) + { + return 'ROLLBACK TRANSACTION ' . $savepoint; + } + + /** + * @override + */ + public function appendLockHint($fromClause, $lockMode) + { + // @todo coorect + if ($lockMode == \Doctrine\DBAL\LockMode::PESSIMISTIC_READ) { + return $fromClause . ' WITH (tablockx)'; + } else if ($lockMode == \Doctrine\DBAL\LockMode::PESSIMISTIC_WRITE) { + return $fromClause . ' WITH (tablockx)'; + } else { + return $fromClause; + } + } + + /** + * @override + */ + public function getForUpdateSQL() + { + return ' '; + } + + protected function getReservedKeywordsClass() + { + return 'Doctrine\DBAL\Platforms\Keywords\MsSQLKeywords'; + } + + /** + * {@inheritDoc} + */ + public function quoteSingleIdentifier($str) + { + return "[" . str_replace("]", "][", $str) . "]"; + } + + public function getTruncateTableSQL($tableName, $cascade = false) + { + return 'TRUNCATE TABLE '.$tableName; + } + + /** + * Gets the SQL Snippet used to declare a BLOB column type. + */ + public function getBlobTypeDeclarationSQL(array $field) + { + return 'VARBINARY(MAX)'; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php new file mode 100644 index 0000000..9cfa726 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php @@ -0,0 +1,519 @@ +. + */ + +namespace Doctrine\DBAL\Platforms; + +use Doctrine\DBAL\DBALException; + +/** + * The SqlitePlatform class describes the specifics and dialects of the SQLite + * database platform. + * + * @since 2.0 + * @author Roman Borschel + * @author Benjamin Eberlei + * @todo Rename: SQLitePlatform + */ +class SqlitePlatform extends AbstractPlatform +{ + /** + * returns the regular expression operator + * + * @return string + * @override + */ + public function getRegexpExpression() + { + return 'RLIKE'; + } + + /** + * Return string to call a variable with the current timestamp inside an SQL statement + * There are three special variables for current date and time. + * + * @return string sqlite function as string + * @override + */ + public function getNowExpression($type = 'timestamp') + { + switch ($type) { + case 'time': + return 'time(\'now\')'; + case 'date': + return 'date(\'now\')'; + case 'timestamp': + default: + return 'datetime(\'now\')'; + } + } + + /** + * Trim a string, leading/trailing/both and with a given char which defaults to space. + * + * @param string $str + * @param int $pos + * @param string $char + * @return string + */ + public function getTrimExpression($str, $pos = self::TRIM_UNSPECIFIED, $char = false) + { + $trimFn = ''; + $trimChar = ($char != false) ? (', ' . $char) : ''; + + if ($pos == self::TRIM_LEADING) { + $trimFn = 'LTRIM'; + } else if($pos == self::TRIM_TRAILING) { + $trimFn = 'RTRIM'; + } else { + $trimFn = 'TRIM'; + } + + return $trimFn . '(' . $str . $trimChar . ')'; + } + + /** + * return string to call a function to get a substring inside an SQL statement + * + * Note: Not SQL92, but common functionality. + * + * SQLite only supports the 2 parameter variant of this function + * + * @param string $value an sql string literal or column name/alias + * @param integer $position where to start the substring portion + * @param integer $length the substring portion length + * @return string SQL substring function with given parameters + * @override + */ + public function getSubstringExpression($value, $position, $length = null) + { + if ($length !== null) { + return 'SUBSTR(' . $value . ', ' . $position . ', ' . $length . ')'; + } + return 'SUBSTR(' . $value . ', ' . $position . ', LENGTH(' . $value . '))'; + } + + /** + * returns the position of the first occurrence of substring $substr in string $str + * + * @param string $substr literal string to find + * @param string $str literal string + * @param int $pos position to start at, beginning of string by default + * @return integer + */ + public function getLocateExpression($str, $substr, $startPos = false) + { + if ($startPos == false) { + return 'LOCATE('.$str.', '.$substr.')'; + } else { + return 'LOCATE('.$str.', '.$substr.', '.$startPos.')'; + } + } + + public function getDateDiffExpression($date1, $date2) + { + return 'ROUND(JULIANDAY('.$date1 . ')-JULIANDAY('.$date2.'))'; + } + + public function getDateAddDaysExpression($date, $days) + { + return "DATE(" . $date . ",'+". $days . " day')"; + } + + public function getDateSubDaysExpression($date, $days) + { + return "DATE(" . $date . ",'-". $days . " day')"; + } + + public function getDateAddMonthExpression($date, $months) + { + return "DATE(" . $date . ",'+". $months . " month')"; + } + + public function getDateSubMonthExpression($date, $months) + { + return "DATE(" . $date . ",'-". $months . " month')"; + } + + protected function _getTransactionIsolationLevelSQL($level) + { + switch ($level) { + case \Doctrine\DBAL\Connection::TRANSACTION_READ_UNCOMMITTED: + return 0; + case \Doctrine\DBAL\Connection::TRANSACTION_READ_COMMITTED: + case \Doctrine\DBAL\Connection::TRANSACTION_REPEATABLE_READ: + case \Doctrine\DBAL\Connection::TRANSACTION_SERIALIZABLE: + return 1; + default: + return parent::_getTransactionIsolationLevelSQL($level); + } + } + + public function getSetTransactionIsolationSQL($level) + { + return 'PRAGMA read_uncommitted = ' . $this->_getTransactionIsolationLevelSQL($level); + } + + /** + * @override + */ + public function prefersIdentityColumns() + { + return true; + } + + /** + * @override + */ + public function getBooleanTypeDeclarationSQL(array $field) + { + return 'BOOLEAN'; + } + + /** + * @override + */ + public function getIntegerTypeDeclarationSQL(array $field) + { + return $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** + * @override + */ + public function getBigIntTypeDeclarationSQL(array $field) + { + return $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** + * @override + */ + public function getTinyIntTypeDeclarationSql(array $field) + { + return $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** + * @override + */ + public function getSmallIntTypeDeclarationSQL(array $field) + { + return $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** + * @override + */ + public function getMediumIntTypeDeclarationSql(array $field) + { + return $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** + * @override + */ + public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATETIME'; + } + + /** + * @override + */ + public function getDateTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATE'; + } + + /** + * @override + */ + public function getTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'TIME'; + } + + /** + * @override + */ + protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef) + { + return 'INTEGER'; + } + + /** + * create a new table + * + * @param string $name Name of the database that should be created + * @param array $fields Associative array that contains the definition of each field of the new table + * The indexes of the array entries are the names of the fields of the table an + * the array entry values are associative arrays like those that are meant to be + * passed with the field definitions to get[Type]Declaration() functions. + * array( + * 'id' => array( + * 'type' => 'integer', + * 'unsigned' => 1 + * 'notnull' => 1 + * 'default' => 0 + * ), + * 'name' => array( + * 'type' => 'text', + * 'length' => 12 + * ), + * 'password' => array( + * 'type' => 'text', + * 'length' => 12 + * ) + * ); + * @param array $options An associative array of table options: + * + * @return void + * @override + */ + protected function _getCreateTableSQL($name, array $columns, array $options = array()) + { + $name = str_replace(".", "__", $name); + $queryFields = $this->getColumnDeclarationListSQL($columns); + + if (isset($options['primary']) && ! empty($options['primary'])) { + $keyColumns = array_unique(array_values($options['primary'])); + $keyColumns = array_map(array($this, 'quoteIdentifier'), $keyColumns); + $queryFields.= ', PRIMARY KEY('.implode(', ', $keyColumns).')'; + } + + $query[] = 'CREATE TABLE ' . $name . ' (' . $queryFields . ')'; + + if (isset($options['indexes']) && ! empty($options['indexes'])) { + foreach ($options['indexes'] as $index => $indexDef) { + $query[] = $this->getCreateIndexSQL($indexDef, $name); + } + } + if (isset($options['unique']) && ! empty($options['unique'])) { + foreach ($options['unique'] as $index => $indexDef) { + $query[] = $this->getCreateIndexSQL($indexDef, $name); + } + } + return $query; + } + + /** + * {@inheritdoc} + */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) + { + return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)') + : ($length ? 'VARCHAR(' . $length . ')' : 'TEXT'); + } + + public function getClobTypeDeclarationSQL(array $field) + { + return 'CLOB'; + } + + public function getListTableConstraintsSQL($table) + { + $table = str_replace(".", "__", $table); + return "SELECT sql FROM sqlite_master WHERE type='index' AND tbl_name = '$table' AND sql NOT NULL ORDER BY name"; + } + + public function getListTableColumnsSQL($table, $currentDatabase = null) + { + $table = str_replace(".", "__", $table); + return "PRAGMA table_info($table)"; + } + + public function getListTableIndexesSQL($table, $currentDatabase = null) + { + $table = str_replace(".", "__", $table); + return "PRAGMA index_list($table)"; + } + + public function getListTablesSQL() + { + return "SELECT name FROM sqlite_master WHERE type = 'table' AND name != 'sqlite_sequence' AND name != 'geometry_columns' AND name != 'spatial_ref_sys' " + . "UNION ALL SELECT name FROM sqlite_temp_master " + . "WHERE type = 'table' ORDER BY name"; + } + + public function getListViewsSQL($database) + { + return "SELECT name, sql FROM sqlite_master WHERE type='view' AND sql NOT NULL"; + } + + public function getCreateViewSQL($name, $sql) + { + return 'CREATE VIEW ' . $name . ' AS ' . $sql; + } + + public function getDropViewSQL($name) + { + return 'DROP VIEW '. $name; + } + + /** + * SQLite does support foreign key constraints, but only in CREATE TABLE statements... + * This really limits their usefulness and requires SQLite specific handling, so + * we simply say that SQLite does NOT support foreign keys for now... + * + * @return boolean FALSE + * @override + */ + public function supportsForeignKeyConstraints() + { + return false; + } + + public function supportsAlterTable() + { + return false; + } + + public function supportsIdentityColumns() + { + return true; + } + + /** + * Get the platform name for this instance + * + * @return string + */ + public function getName() + { + return 'sqlite'; + } + + /** + * @inheritdoc + */ + public function getTruncateTableSQL($tableName, $cascade = false) + { + $tableName = str_replace(".", "__", $tableName); + return 'DELETE FROM '.$tableName; + } + + /** + * User-defined function for Sqlite that is used with PDO::sqliteCreateFunction() + * + * @param int|float $value + * @return float + */ + static public function udfSqrt($value) + { + return sqrt($value); + } + + /** + * User-defined function for Sqlite that implements MOD(a, b) + */ + static public function udfMod($a, $b) + { + return ($a % $b); + } + + /** + * @param string $str + * @param string $substr + * @param int $offset + */ + static public function udfLocate($str, $substr, $offset = 0) + { + $pos = strpos($str, $substr, $offset); + if ($pos !== false) { + return $pos+1; + } + return 0; + } + + public function getForUpdateSql() + { + return ''; + } + + protected function initializeDoctrineTypeMappings() + { + $this->doctrineTypeMapping = array( + 'boolean' => 'boolean', + 'tinyint' => 'boolean', + 'smallint' => 'smallint', + 'mediumint' => 'integer', + 'int' => 'integer', + 'integer' => 'integer', + 'serial' => 'integer', + 'bigint' => 'bigint', + 'bigserial' => 'bigint', + 'clob' => 'text', + 'tinytext' => 'text', + 'mediumtext' => 'text', + 'longtext' => 'text', + 'text' => 'text', + 'varchar' => 'string', + 'longvarchar' => 'string', + 'varchar2' => 'string', + 'nvarchar' => 'string', + 'image' => 'string', + 'ntext' => 'string', + 'char' => 'string', + 'date' => 'date', + 'datetime' => 'datetime', + 'timestamp' => 'datetime', + 'time' => 'time', + 'float' => 'float', + 'double' => 'float', + 'double precision' => 'float', + 'real' => 'float', + 'decimal' => 'decimal', + 'numeric' => 'decimal', + 'blob' => 'blob', + ); + } + + protected function getReservedKeywordsClass() + { + return 'Doctrine\DBAL\Platforms\Keywords\SQLiteKeywords'; + } + + /** + * Gets the SQL Snippet used to declare a BLOB column type. + */ + public function getBlobTypeDeclarationSQL(array $field) + { + return 'BLOB'; + } + + public function getTemporaryTableName($tableName) + { + $tableName = str_replace(".", "__", $tableName); + return $tableName; + } + + /** + * Sqlite Platform emulates schema by underscoring each dot and generating tables + * into the default database. + * + * This hack is implemented to be able to use SQLite as testdriver when + * using schema supporting databases. + * + * @return bool + */ + public function canEmulateSchemas() + { + return true; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Portability/Connection.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Portability/Connection.php new file mode 100644 index 0000000..93ee9fc --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Portability/Connection.php @@ -0,0 +1,113 @@ +. + */ + + +namespace Doctrine\DBAL\Portability; + +use Doctrine\Common\EventManager; +use Doctrine\DBAL\Configuration; +use Doctrine\DBAL\Driver; +use Doctrine\DBAL\Cache\QueryCacheProfile; + +class Connection extends \Doctrine\DBAL\Connection +{ + const PORTABILITY_ALL = 255; + const PORTABILITY_NONE = 0; + const PORTABILITY_RTRIM = 1; + const PORTABILITY_EMPTY_TO_NULL = 4; + const PORTABILITY_FIX_CASE = 8; + + const PORTABILITY_ORACLE = 9; + const PORTABILITY_POSTGRESQL = 13; + const PORTABILITY_SQLITE = 13; + const PORTABILITY_OTHERVENDORS = 12; + + /** + * @var int + */ + private $portability = self::PORTABILITY_NONE; + + /** + * @var int + */ + private $case; + + public function connect() + { + $ret = parent::connect(); + if ($ret) { + $params = $this->getParams(); + if (isset($params['portability'])) { + if ($this->_platform->getName() === "oracle") { + $params['portability'] = $params['portability'] & self::PORTABILITY_ORACLE; + } else if ($this->_platform->getName() === "postgresql") { + $params['portability'] = $params['portability'] & self::PORTABILITY_POSTGRESQL; + } else if ($this->_platform->getName() === "sqlite") { + $params['portability'] = $params['portability'] & self::PORTABILITY_SQLITE; + } else { + $params['portability'] = $params['portability'] & self::PORTABILITY_OTHERVENDORS; + } + $this->portability = $params['portability']; + } + if (isset($params['fetch_case']) && $this->portability & self::PORTABILITY_FIX_CASE) { + if ($this->_conn instanceof \Doctrine\DBAL\Driver\PDOConnection) { + // make use of c-level support for case handling + $this->_conn->setAttribute(\PDO::ATTR_CASE, $params['fetch_case']); + } else { + $this->case = ($params['fetch_case'] == \PDO::CASE_LOWER) ? CASE_LOWER : CASE_UPPER; + } + } + } + return $ret; + } + + public function getPortability() + { + return $this->portability; + } + + public function getFetchCase() + { + return $this->case; + } + + public function executeQuery($query, array $params = array(), $types = array(), QueryCacheProfile $qcp = null) + { + return new Statement(parent::executeQuery($query, $params, $types, $qcp), $this); + } + + /** + * Prepares an SQL statement. + * + * @param string $statement The SQL statement to prepare. + * @return Doctrine\DBAL\Driver\Statement The prepared statement. + */ + public function prepare($statement) + { + return new Statement(parent::prepare($statement), $this); + } + + public function query() + { + $this->connect(); + + $stmt = call_user_func_array(array($this->_conn, 'query'), func_get_args()); + return new Statement($stmt, $this); + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Portability/Statement.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Portability/Statement.php new file mode 100644 index 0000000..70622f6 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Portability/Statement.php @@ -0,0 +1,191 @@ +. + */ + +namespace Doctrine\DBAL\Portability; + +use PDO; + +/** + * Portability Wrapper for a Statement + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.0 + * @author Benjamin Eberlei + */ +class Statement implements \IteratorAggregate, \Doctrine\DBAL\Driver\Statement +{ + + /** + * @var int + */ + private $portability; + + /** + * @var Doctrine\DBAL\Driver\Statement + */ + private $stmt; + + /** + * @var int + */ + private $case; + + /** + * @var int + */ + private $defaultFetchStyle = PDO::FETCH_BOTH; + + /** + * Wraps Statement and applies portability measures + * + * @param Doctrine\DBAL\Driver\Statement $stmt + * @param Doctrine\DBAL\Connection $conn + */ + public function __construct($stmt, Connection $conn) + { + $this->stmt = $stmt; + $this->portability = $conn->getPortability(); + $this->case = $conn->getFetchCase(); + } + + public function bindParam($column, &$variable, $type = null) + { + return $this->stmt->bindParam($column, $variable, $type); + } + + public function bindValue($param, $value, $type = null) + { + return $this->stmt->bindValue($param, $value, $type); + } + + public function closeCursor() + { + return $this->stmt->closeCursor(); + } + + public function columnCount() + { + return $this->stmt->columnCount(); + } + + public function errorCode() + { + return $this->stmt->errorCode(); + } + + public function errorInfo() + { + return $this->stmt->errorInfo(); + } + + public function execute($params = null) + { + return $this->stmt->execute($params); + } + + public function setFetchMode($fetchStyle, $arg1 = null, $arg2 = null) + { + $this->defaultFetchStyle = $fetchStyle; + $this->stmt->setFetchMode($fetchStyle, $arg1, $arg2); + } + + public function getIterator() + { + $data = $this->fetchAll($this->defaultFetchStyle); + return new \ArrayIterator($data); + } + + public function fetch($fetchStyle = PDO::FETCH_BOTH) + { + $row = $this->stmt->fetch($fetchStyle); + + $row = $this->fixRow($row, + $this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM), + !is_null($this->case) && ($fetchStyle == PDO::FETCH_ASSOC || $fetchStyle == PDO::FETCH_BOTH) && ($this->portability & Connection::PORTABILITY_FIX_CASE) + ); + + return $row; + } + + public function fetchAll($fetchStyle = PDO::FETCH_BOTH, $columnIndex = 0) + { + if ($columnIndex != 0) { + $rows = $this->stmt->fetchAll($fetchStyle, $columnIndex); + } else { + $rows = $this->stmt->fetchAll($fetchStyle); + } + + $iterateRow = $this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM); + $fixCase = !is_null($this->case) && ($fetchStyle == PDO::FETCH_ASSOC || $fetchStyle == PDO::FETCH_BOTH) && ($this->portability & Connection::PORTABILITY_FIX_CASE); + if (!$iterateRow && !$fixCase) { + return $rows; + } + + foreach ($rows AS $num => $row) { + $rows[$num] = $this->fixRow($row, $iterateRow, $fixCase); + } + + return $rows; + } + + protected function fixRow($row, $iterateRow, $fixCase) + { + if (!$row) { + return $row; + } + + if ($fixCase) { + $row = array_change_key_case($row, $this->case); + } + + if ($iterateRow) { + foreach ($row AS $k => $v) { + if (($this->portability & Connection::PORTABILITY_EMPTY_TO_NULL) && $v === '') { + $row[$k] = null; + } else if (($this->portability & Connection::PORTABILITY_RTRIM) && is_string($v)) { + $row[$k] = rtrim($v); + } + } + } + return $row; + } + + public function fetchColumn($columnIndex = 0) + { + $value = $this->stmt->fetchColumn($columnIndex); + + if ($this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM)) { + if (($this->portability & Connection::PORTABILITY_EMPTY_TO_NULL) && $value === '') { + $value = null; + } else if (($this->portability & Connection::PORTABILITY_RTRIM) && is_string($value)) { + $value = rtrim($value); + } + } + + return $value; + } + + public function rowCount() + { + return $this->stmt->rowCount(); + } + +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/CompositeExpression.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/CompositeExpression.php new file mode 100644 index 0000000..5da1889 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/CompositeExpression.php @@ -0,0 +1,130 @@ +. + */ + +namespace Doctrine\DBAL\Query\Expression; + +/** + * Composite expression is responsible to build a group of similar expression. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.1 + * @author Guilherme Blanco + * @author Benjamin Eberlei + */ +class CompositeExpression implements \Countable +{ + /** + * Constant that represents an AND composite expression + */ + const TYPE_AND = 'AND'; + + /** + * Constant that represents an OR composite expression + */ + const TYPE_OR = 'OR'; + + /** + * @var string Holds the instance type of composite expression + */ + private $type; + + /** + * @var array Each expression part of the composite expression + */ + private $parts = array(); + + /** + * Constructor. + * + * @param string $type Instance type of composite expression + * @param array $parts Composition of expressions to be joined on composite expression + */ + public function __construct($type, array $parts = array()) + { + $this->type = $type; + + $this->addMultiple($parts); + } + + /** + * Adds multiple parts to composite expression. + * + * @param array $args + * + * @return CompositeExpression + */ + public function addMultiple(array $parts = array()) + { + foreach ((array) $parts as $part) { + $this->add($part); + } + + return $this; + } + + /** + * Adds an expression to composite expression. + * + * @param mixed $part + * @return CompositeExpression + */ + public function add($part) + { + if ( ! empty($part) || ($part instanceof self && $part->count() > 0)) { + $this->parts[] = $part; + } + + return $this; + } + + /** + * Retrieves the amount of expressions on composite expression. + * + * @return integer + */ + public function count() + { + return count($this->parts); + } + + /** + * Retrieve the string representation of this composite expression. + * + * @return string + */ + public function __toString() + { + if (count($this->parts) === 1) { + return (string) $this->parts[0]; + } + + return '(' . implode(') ' . $this->type . ' (', $this->parts) . ')'; + } + + /** + * Return type of this composite expression (AND/OR) + * + * @return string + */ + public function getType() + { + return $this->type; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/ExpressionBuilder.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/ExpressionBuilder.php new file mode 100644 index 0000000..35f0762 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/ExpressionBuilder.php @@ -0,0 +1,264 @@ +. + */ + +namespace Doctrine\DBAL\Query\Expression; + +use Doctrine\DBAL\Connection; + +/** + * ExpressionBuilder class is responsible to dynamically create SQL query parts. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.1 + * @author Guilherme Blanco + * @author Benjamin Eberlei + */ +class ExpressionBuilder +{ + const EQ = '='; + const NEQ = '<>'; + const LT = '<'; + const LTE = '<='; + const GT = '>'; + const GTE = '>='; + + /** + * @var Doctrine\DBAL\Connection DBAL Connection + */ + private $connection = null; + + /** + * Initializes a new ExpressionBuilder. + * + * @param Doctrine\DBAL\Connection $connection DBAL Connection + */ + public function __construct(Connection $connection) + { + $this->connection = $connection; + } + + /** + * Creates a conjunction of the given boolean expressions. + * + * Example: + * + * [php] + * // (u.type = ?) AND (u.role = ?) + * $expr->andX('u.type = ?', 'u.role = ?')); + * + * @param mixed $x Optional clause. Defaults = null, but requires + * at least one defined when converting to string. + * @return CompositeExpression + */ + public function andX($x = null) + { + return new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args()); + } + + /** + * Creates a disjunction of the given boolean expressions. + * + * Example: + * + * [php] + * // (u.type = ?) OR (u.role = ?) + * $qb->where($qb->expr()->orX('u.type = ?', 'u.role = ?')); + * + * @param mixed $x Optional clause. Defaults = null, but requires + * at least one defined when converting to string. + * @return CompositeExpression + */ + public function orX($x = null) + { + return new CompositeExpression(CompositeExpression::TYPE_OR, func_get_args()); + } + + /** + * Creates a comparison expression. + * + * @param mixed $x Left expression + * @param string $operator One of the ExpressionBuikder::* constants. + * @param mixed $y Right expression + * @return string + */ + public function comparison($x, $operator, $y) + { + return $x . ' ' . $operator . ' ' . $y; + } + + /** + * Creates an equality comparison expression with the given arguments. + * + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a = . Example: + * + * [php] + * // u.id = ? + * $expr->eq('u.id', '?'); + * + * @param mixed $x Left expression + * @param mixed $y Right expression + * @return string + */ + public function eq($x, $y) + { + return $this->comparison($x, self::EQ, $y); + } + + /** + * Creates a non equality comparison expression with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a <> . Example: + * + * [php] + * // u.id <> 1 + * $q->where($q->expr()->neq('u.id', '1')); + * + * @param mixed $x Left expression + * @param mixed $y Right expression + * @return string + */ + public function neq($x, $y) + { + return $this->comparison($x, self::NEQ, $y); + } + + /** + * Creates a lower-than comparison expression with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a < . Example: + * + * [php] + * // u.id < ? + * $q->where($q->expr()->lt('u.id', '?')); + * + * @param mixed $x Left expression + * @param mixed $y Right expression + * @return string + */ + public function lt($x, $y) + { + return $this->comparison($x, self::LT, $y); + } + + /** + * Creates a lower-than-equal comparison expression with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a <= . Example: + * + * [php] + * // u.id <= ? + * $q->where($q->expr()->lte('u.id', '?')); + * + * @param mixed $x Left expression + * @param mixed $y Right expression + * @return string + */ + public function lte($x, $y) + { + return $this->comparison($x, self::LTE, $y); + } + + /** + * Creates a greater-than comparison expression with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a > . Example: + * + * [php] + * // u.id > ? + * $q->where($q->expr()->gt('u.id', '?')); + * + * @param mixed $x Left expression + * @param mixed $y Right expression + * @return string + */ + public function gt($x, $y) + { + return $this->comparison($x, self::GT, $y); + } + + /** + * Creates a greater-than-equal comparison expression with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a >= . Example: + * + * [php] + * // u.id >= ? + * $q->where($q->expr()->gte('u.id', '?')); + * + * @param mixed $x Left expression + * @param mixed $y Right expression + * @return string + */ + public function gte($x, $y) + { + return $this->comparison($x, self::GTE, $y); + } + + /** + * Creates an IS NULL expression with the given arguments. + * + * @param string $x Field in string format to be restricted by IS NULL + * + * @return string + */ + public function isNull($x) + { + return $x . ' IS NULL'; + } + + /** + * Creates an IS NOT NULL expression with the given arguments. + * + * @param string $x Field in string format to be restricted by IS NOT NULL + * + * @return string + */ + public function isNotNull($x) + { + return $x . ' IS NOT NULL'; + } + + /** + * Creates a LIKE() comparison expression with the given arguments. + * + * @param string $x Field in string format to be inspected by LIKE() comparison. + * @param mixed $y Argument to be used in LIKE() comparison. + * + * @return string + */ + public function like($x, $y) + { + return $this->comparison($x, 'LIKE', $y); + } + + /** + * Quotes a given input parameter. + * + * @param mixed $input Parameter to be quoted. + * @param string $type Type of the parameter. + * + * @return string + */ + public function literal($input, $type = null) + { + return $this->connection->quote($input, $type); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryBuilder.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryBuilder.php new file mode 100644 index 0000000..4fb3a06 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryBuilder.php @@ -0,0 +1,1091 @@ +. + */ + +namespace Doctrine\DBAL\Query; + +use Doctrine\DBAL\Query\Expression\CompositeExpression, + Doctrine\DBAL\Connection; + +/** + * QueryBuilder class is responsible to dynamically create SQL queries. + * + * Important: Verify that every feature you use will work with your database vendor. + * SQL Query Builder does not attempt to validate the generated SQL at all. + * + * The query builder does no validation whatsoever if certain features even work with the + * underlying database vendor. Limit queries and joins are NOT applied to UPDATE and DELETE statements + * even if some vendors such as MySQL support it. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.1 + * @author Guilherme Blanco + * @author Benjamin Eberlei + */ +class QueryBuilder +{ + /* The query types. */ + const SELECT = 0; + const DELETE = 1; + const UPDATE = 2; + + /** The builder states. */ + const STATE_DIRTY = 0; + const STATE_CLEAN = 1; + + /** + * @var Doctrine\DBAL\Connection DBAL Connection + */ + private $connection = null; + + /** + * @var array The array of SQL parts collected. + */ + private $sqlParts = array( + 'select' => array(), + 'from' => array(), + 'join' => array(), + 'set' => array(), + 'where' => null, + 'groupBy' => array(), + 'having' => null, + 'orderBy' => array() + ); + + /** + * @var string The complete SQL string for this query. + */ + private $sql; + + /** + * @var array The query parameters. + */ + private $params = array(); + + /** + * @var array The parameter type map of this query. + */ + private $paramTypes = array(); + + /** + * @var integer The type of query this is. Can be select, update or delete. + */ + private $type = self::SELECT; + + /** + * @var integer The state of the query object. Can be dirty or clean. + */ + private $state = self::STATE_CLEAN; + + /** + * @var integer The index of the first result to retrieve. + */ + private $firstResult = null; + + /** + * @var integer The maximum number of results to retrieve. + */ + private $maxResults = null; + + /** + * The counter of bound parameters used with {@see bindValue) + * + * @var int + */ + private $boundCounter = 0; + + /** + * Initializes a new QueryBuilder. + * + * @param Doctrine\DBAL\Connection $connection DBAL Connection + */ + public function __construct(Connection $connection) + { + $this->connection = $connection; + } + + /** + * Gets an ExpressionBuilder used for object-oriented construction of query expressions. + * This producer method is intended for convenient inline usage. Example: + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u') + * ->from('users', 'u') + * ->where($qb->expr()->eq('u.id', 1)); + * + * + * For more complex expression construction, consider storing the expression + * builder object in a local variable. + * + * @return Doctrine\DBAL\Query\ExpressionBuilder + */ + public function expr() + { + return $this->connection->getExpressionBuilder(); + } + + /** + * Get the type of the currently built query. + * + * @return integer + */ + public function getType() + { + return $this->type; + } + + /** + * Get the associated DBAL Connection for this query builder. + * + * @return Doctrine\DBAL\Connection + */ + public function getConnection() + { + return $this->connection; + } + + /** + * Get the state of this query builder instance. + * + * @return integer Either QueryBuilder::STATE_DIRTY or QueryBuilder::STATE_CLEAN. + */ + public function getState() + { + return $this->state; + } + + /** + * Execute this query using the bound parameters and their types. + * + * Uses {@see Connection::executeQuery} for select statements and {@see Connection::executeUpdate} + * for insert, update and delete statements. + * + * @return mixed + */ + public function execute() + { + if ($this->type == self::SELECT) { + return $this->connection->executeQuery($this->getSQL(), $this->params, $this->paramTypes); + } else { + return $this->connection->executeUpdate($this->getSQL(), $this->params, $this->paramTypes); + } + } + + /** + * Get the complete SQL string formed by the current specifications of this QueryBuilder. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->from('User', 'u') + * echo $qb->getSQL(); // SELECT u FROM User u + * + * + * @return string The sql query string. + */ + public function getSQL() + { + if ($this->sql !== null && $this->state === self::STATE_CLEAN) { + return $this->sql; + } + + $sql = ''; + + switch ($this->type) { + case self::DELETE: + $sql = $this->getSQLForDelete(); + break; + + case self::UPDATE: + $sql = $this->getSQLForUpdate(); + break; + + case self::SELECT: + default: + $sql = $this->getSQLForSelect(); + break; + } + + $this->state = self::STATE_CLEAN; + $this->sql = $sql; + + return $sql; + } + + /** + * Sets a query parameter for the query being constructed. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u') + * ->from('users', 'u') + * ->where('u.id = :user_id') + * ->setParameter(':user_id', 1); + * + * + * @param string|integer $key The parameter position or name. + * @param mixed $value The parameter value. + * @param string|null $type PDO::PARAM_* + * @return QueryBuilder This QueryBuilder instance. + */ + public function setParameter($key, $value, $type = null) + { + if ($type !== null) { + $this->paramTypes[$key] = $type; + } + + $this->params[$key] = $value; + + return $this; + } + + /** + * Sets a collection of query parameters for the query being constructed. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u') + * ->from('users', 'u') + * ->where('u.id = :user_id1 OR u.id = :user_id2') + * ->setParameters(array( + * ':user_id1' => 1, + * ':user_id2' => 2 + * )); + * + * + * @param array $params The query parameters to set. + * @return QueryBuilder This QueryBuilder instance. + */ + public function setParameters(array $params, array $types = array()) + { + $this->paramTypes = $types; + $this->params = $params; + + return $this; + } + + /** + * Gets all defined query parameters for the query being constructed. + * + * @return array The currently defined query parameters. + */ + public function getParameters() + { + return $this->params; + } + + /** + * Gets a (previously set) query parameter of the query being constructed. + * + * @param mixed $key The key (index or name) of the bound parameter. + * @return mixed The value of the bound parameter. + */ + public function getParameter($key) + { + return isset($this->params[$key]) ? $this->params[$key] : null; + } + + /** + * Sets the position of the first result to retrieve (the "offset"). + * + * @param integer $firstResult The first result to return. + * @return Doctrine\DBAL\Query\QueryBuilder This QueryBuilder instance. + */ + public function setFirstResult($firstResult) + { + $this->state = self::STATE_DIRTY; + $this->firstResult = $firstResult; + return $this; + } + + /** + * Gets the position of the first result the query object was set to retrieve (the "offset"). + * Returns NULL if {@link setFirstResult} was not applied to this QueryBuilder. + * + * @return integer The position of the first result. + */ + public function getFirstResult() + { + return $this->firstResult; + } + + /** + * Sets the maximum number of results to retrieve (the "limit"). + * + * @param integer $maxResults The maximum number of results to retrieve. + * @return Doctrine\DBAL\Query\QueryBuilder This QueryBuilder instance. + */ + public function setMaxResults($maxResults) + { + $this->state = self::STATE_DIRTY; + $this->maxResults = $maxResults; + return $this; + } + + /** + * Gets the maximum number of results the query object was set to retrieve (the "limit"). + * Returns NULL if {@link setMaxResults} was not applied to this query builder. + * + * @return integer Maximum number of results. + */ + public function getMaxResults() + { + return $this->maxResults; + } + + /** + * Either appends to or replaces a single, generic query part. + * + * The available parts are: 'select', 'from', 'set', 'where', + * 'groupBy', 'having' and 'orderBy'. + * + * @param string $sqlPartName + * @param string $sqlPart + * @param string $append + * @return Doctrine\DBAL\Query\QueryBuilder This QueryBuilder instance. + */ + public function add($sqlPartName, $sqlPart, $append = false) + { + $isArray = is_array($sqlPart); + $isMultiple = is_array($this->sqlParts[$sqlPartName]); + + if ($isMultiple && !$isArray) { + $sqlPart = array($sqlPart); + } + + $this->state = self::STATE_DIRTY; + + if ($append) { + if ($sqlPartName == "orderBy" || $sqlPartName == "groupBy" || $sqlPartName == "select" || $sqlPartName == "set") { + foreach ($sqlPart AS $part) { + $this->sqlParts[$sqlPartName][] = $part; + } + } else if ($isArray && is_array($sqlPart[key($sqlPart)])) { + $key = key($sqlPart); + $this->sqlParts[$sqlPartName][$key][] = $sqlPart[$key]; + } else if ($isMultiple) { + $this->sqlParts[$sqlPartName][] = $sqlPart; + } else { + $this->sqlParts[$sqlPartName] = $sqlPart; + } + + return $this; + } + + $this->sqlParts[$sqlPartName] = $sqlPart; + + return $this; + } + + /** + * Specifies an item that is to be returned in the query result. + * Replaces any previously specified selections, if any. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.id', 'p.id') + * ->from('users', 'u') + * ->leftJoin('u', 'phonenumbers', 'p', 'u.id = p.user_id'); + * + * + * @param mixed $select The selection expressions. + * @return QueryBuilder This QueryBuilder instance. + */ + public function select($select = null) + { + $this->type = self::SELECT; + + if (empty($select)) { + return $this; + } + + $selects = is_array($select) ? $select : func_get_args(); + + return $this->add('select', $selects, false); + } + + /** + * Adds an item that is to be returned in the query result. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.id') + * ->addSelect('p.id') + * ->from('users', 'u') + * ->leftJoin('u', 'phonenumbers', 'u.id = p.user_id'); + * + * + * @param mixed $select The selection expression. + * @return QueryBuilder This QueryBuilder instance. + */ + public function addSelect($select = null) + { + $this->type = self::SELECT; + + if (empty($select)) { + return $this; + } + + $selects = is_array($select) ? $select : func_get_args(); + + return $this->add('select', $selects, true); + } + + /** + * Turns the query being built into a bulk delete query that ranges over + * a certain table. + * + * + * $qb = $conn->createQueryBuilder() + * ->delete('users', 'u') + * ->where('u.id = :user_id'); + * ->setParameter(':user_id', 1); + * + * + * @param string $delete The table whose rows are subject to the deletion. + * @param string $alias The table alias used in the constructed query. + * @return QueryBuilder This QueryBuilder instance. + */ + public function delete($delete = null, $alias = null) + { + $this->type = self::DELETE; + + if ( ! $delete) { + return $this; + } + + return $this->add('from', array( + 'table' => $delete, + 'alias' => $alias + )); + } + + /** + * Turns the query being built into a bulk update query that ranges over + * a certain table + * + * + * $qb = $conn->createQueryBuilder() + * ->update('users', 'u') + * ->set('u.password', md5('password')) + * ->where('u.id = ?'); + * + * + * @param string $update The table whose rows are subject to the update. + * @param string $alias The table alias used in the constructed query. + * @return QueryBuilder This QueryBuilder instance. + */ + public function update($update = null, $alias = null) + { + $this->type = self::UPDATE; + + if ( ! $update) { + return $this; + } + + return $this->add('from', array( + 'table' => $update, + 'alias' => $alias + )); + } + + /** + * Create and add a query root corresponding to the table identified by the + * given alias, forming a cartesian product with any existing query roots. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.id') + * ->from('users', 'u') + * + * + * @param string $from The table + * @param string $alias The alias of the table + * @return QueryBuilder This QueryBuilder instance. + */ + public function from($from, $alias) + { + return $this->add('from', array( + 'table' => $from, + 'alias' => $alias + ), true); + } + + /** + * Creates and adds a join to the query. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->join('u', 'phonenumbers', 'p', 'p.is_primary = 1'); + * + * + * @param string $fromAlias The alias that points to a from clause + * @param string $join The table name to join + * @param string $alias The alias of the join table + * @param string $condition The condition for the join + * @return QueryBuilder This QueryBuilder instance. + */ + public function join($fromAlias, $join, $alias, $condition = null) + { + return $this->innerJoin($fromAlias, $join, $alias, $condition); + } + + /** + * Creates and adds a join to the query. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->innerJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1'); + * + * + * @param string $fromAlias The alias that points to a from clause + * @param string $join The table name to join + * @param string $alias The alias of the join table + * @param string $condition The condition for the join + * @return QueryBuilder This QueryBuilder instance. + */ + public function innerJoin($fromAlias, $join, $alias, $condition = null) + { + return $this->add('join', array( + $fromAlias => array( + 'joinType' => 'inner', + 'joinTable' => $join, + 'joinAlias' => $alias, + 'joinCondition' => $condition + ) + ), true); + } + + /** + * Creates and adds a left join to the query. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->leftJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1'); + * + * + * @param string $fromAlias The alias that points to a from clause + * @param string $join The table name to join + * @param string $alias The alias of the join table + * @param string $condition The condition for the join + * @return QueryBuilder This QueryBuilder instance. + */ + public function leftJoin($fromAlias, $join, $alias, $condition = null) + { + return $this->add('join', array( + $fromAlias => array( + 'joinType' => 'left', + 'joinTable' => $join, + 'joinAlias' => $alias, + 'joinCondition' => $condition + ) + ), true); + } + + /** + * Creates and adds a right join to the query. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->rightJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1'); + * + * + * @param string $fromAlias The alias that points to a from clause + * @param string $join The table name to join + * @param string $alias The alias of the join table + * @param string $condition The condition for the join + * @return QueryBuilder This QueryBuilder instance. + */ + public function rightJoin($fromAlias, $join, $alias, $condition = null) + { + return $this->add('join', array( + $fromAlias => array( + 'joinType' => 'right', + 'joinTable' => $join, + 'joinAlias' => $alias, + 'joinCondition' => $condition + ) + ), true); + } + + /** + * Sets a new value for a column in a bulk update query. + * + * + * $qb = $conn->createQueryBuilder() + * ->update('users', 'u') + * ->set('u.password', md5('password')) + * ->where('u.id = ?'); + * + * + * @param string $key The column to set. + * @param string $value The value, expression, placeholder, etc. + * @return QueryBuilder This QueryBuilder instance. + */ + public function set($key, $value) + { + return $this->add('set', $key .' = ' . $value, true); + } + + /** + * Specifies one or more restrictions to the query result. + * Replaces any previously specified restrictions, if any. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->where('u.id = ?'); + * + * // You can optionally programatically build and/or expressions + * $qb = $conn->createQueryBuilder(); + * + * $or = $qb->expr()->orx(); + * $or->add($qb->expr()->eq('u.id', 1)); + * $or->add($qb->expr()->eq('u.id', 2)); + * + * $qb->update('users', 'u') + * ->set('u.password', md5('password')) + * ->where($or); + * + * + * @param mixed $predicates The restriction predicates. + * @return QueryBuilder This QueryBuilder instance. + */ + public function where($predicates) + { + if ( ! (func_num_args() == 1 && $predicates instanceof CompositeExpression) ) { + $predicates = new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args()); + } + + return $this->add('where', $predicates); + } + + /** + * Adds one or more restrictions to the query results, forming a logical + * conjunction with any previously specified restrictions. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u') + * ->from('users', 'u') + * ->where('u.username LIKE ?') + * ->andWhere('u.is_active = 1'); + * + * + * @param mixed $where The query restrictions. + * @return QueryBuilder This QueryBuilder instance. + * @see where() + */ + public function andWhere($where) + { + $where = $this->getQueryPart('where'); + $args = func_get_args(); + + if ($where instanceof CompositeExpression && $where->getType() === CompositeExpression::TYPE_AND) { + $where->addMultiple($args); + } else { + array_unshift($args, $where); + $where = new CompositeExpression(CompositeExpression::TYPE_AND, $args); + } + + return $this->add('where', $where, true); + } + + /** + * Adds one or more restrictions to the query results, forming a logical + * disjunction with any previously specified restrictions. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->where('u.id = 1') + * ->orWhere('u.id = 2'); + * + * + * @param mixed $where The WHERE statement + * @return QueryBuilder $qb + * @see where() + */ + public function orWhere($where) + { + $where = $this->getQueryPart('where'); + $args = func_get_args(); + + if ($where instanceof CompositeExpression && $where->getType() === CompositeExpression::TYPE_OR) { + $where->addMultiple($args); + } else { + array_unshift($args, $where); + $where = new CompositeExpression(CompositeExpression::TYPE_OR, $args); + } + + return $this->add('where', $where, true); + } + + /** + * Specifies a grouping over the results of the query. + * Replaces any previously specified groupings, if any. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->groupBy('u.id'); + * + * + * @param mixed $groupBy The grouping expression. + * @return QueryBuilder This QueryBuilder instance. + */ + public function groupBy($groupBy) + { + if (empty($groupBy)) { + return $this; + } + + $groupBy = is_array($groupBy) ? $groupBy : func_get_args(); + + return $this->add('groupBy', $groupBy, false); + } + + + /** + * Adds a grouping expression to the query. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->groupBy('u.lastLogin'); + * ->addGroupBy('u.createdAt') + * + * + * @param mixed $groupBy The grouping expression. + * @return QueryBuilder This QueryBuilder instance. + */ + public function addGroupBy($groupBy) + { + if (empty($groupBy)) { + return $this; + } + + $groupBy = is_array($groupBy) ? $groupBy : func_get_args(); + + return $this->add('groupBy', $groupBy, true); + } + + /** + * Specifies a restriction over the groups of the query. + * Replaces any previous having restrictions, if any. + * + * @param mixed $having The restriction over the groups. + * @return QueryBuilder This QueryBuilder instance. + */ + public function having($having) + { + if ( ! (func_num_args() == 1 && $having instanceof CompositeExpression)) { + $having = new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args()); + } + + return $this->add('having', $having); + } + + /** + * Adds a restriction over the groups of the query, forming a logical + * conjunction with any existing having restrictions. + * + * @param mixed $having The restriction to append. + * @return QueryBuilder This QueryBuilder instance. + */ + public function andHaving($having) + { + $having = $this->getQueryPart('having'); + $args = func_get_args(); + + if ($having instanceof CompositeExpression && $having->getType() === CompositeExpression::TYPE_AND) { + $having->addMultiple($args); + } else { + array_unshift($args, $having); + $having = new CompositeExpression(CompositeExpression::TYPE_AND, $args); + } + + return $this->add('having', $having); + } + + /** + * Adds a restriction over the groups of the query, forming a logical + * disjunction with any existing having restrictions. + * + * @param mixed $having The restriction to add. + * @return QueryBuilder This QueryBuilder instance. + */ + public function orHaving($having) + { + $having = $this->getQueryPart('having'); + $args = func_get_args(); + + if ($having instanceof CompositeExpression && $having->getType() === CompositeExpression::TYPE_OR) { + $having->addMultiple($args); + } else { + array_unshift($args, $having); + $having = new CompositeExpression(CompositeExpression::TYPE_OR, $args); + } + + return $this->add('having', $having); + } + + /** + * Specifies an ordering for the query results. + * Replaces any previously specified orderings, if any. + * + * @param string $sort The ordering expression. + * @param string $order The ordering direction. + * @return QueryBuilder This QueryBuilder instance. + */ + public function orderBy($sort, $order = null) + { + return $this->add('orderBy', $sort . ' ' . (! $order ? 'ASC' : $order), false); + } + + /** + * Adds an ordering to the query results. + * + * @param string $sort The ordering expression. + * @param string $order The ordering direction. + * @return QueryBuilder This QueryBuilder instance. + */ + public function addOrderBy($sort, $order = null) + { + return $this->add('orderBy', $sort . ' ' . (! $order ? 'ASC' : $order), true); + } + + /** + * Get a query part by its name. + * + * @param string $queryPartName + * @return mixed $queryPart + */ + public function getQueryPart($queryPartName) + { + return $this->sqlParts[$queryPartName]; + } + + /** + * Get all query parts. + * + * @return array $sqlParts + */ + public function getQueryParts() + { + return $this->sqlParts; + } + + /** + * Reset SQL parts + * + * @param array $queryPartNames + * @return QueryBuilder + */ + public function resetQueryParts($queryPartNames = null) + { + if (is_null($queryPartNames)) { + $queryPartNames = array_keys($this->sqlParts); + } + + foreach ($queryPartNames as $queryPartName) { + $this->resetQueryPart($queryPartName); + } + + return $this; + } + + /** + * Reset single SQL part + * + * @param string $queryPartName + * @return QueryBuilder + */ + public function resetQueryPart($queryPartName) + { + $this->sqlParts[$queryPartName] = is_array($this->sqlParts[$queryPartName]) + ? array() : null; + + $this->state = self::STATE_DIRTY; + + return $this; + } + + /** + * Converts this instance into a SELECT string in SQL. + * + * @return string + */ + private function getSQLForSelect() + { + $query = 'SELECT ' . implode(', ', $this->sqlParts['select']) . ' FROM '; + + $fromClauses = array(); + + // Loop through all FROM clauses + foreach ($this->sqlParts['from'] as $from) { + $fromClause = $from['table'] . ' ' . $from['alias']; + + if (isset($this->sqlParts['join'][$from['alias']])) { + foreach ($this->sqlParts['join'][$from['alias']] as $join) { + $fromClause .= ' ' . strtoupper($join['joinType']) + . ' JOIN ' . $join['joinTable'] . ' ' . $join['joinAlias'] + . ' ON ' . ((string) $join['joinCondition']); + } + } + + $fromClauses[$from['alias']] = $fromClause; + } + + // loop through all JOIN clasues for validation purpose + foreach ($this->sqlParts['join'] as $fromAlias => $joins) { + if ( ! isset($fromClauses[$fromAlias]) ) { + throw QueryException::unknownFromAlias($fromAlias, array_keys($fromClauses)); + } + } + + $query .= implode(', ', $fromClauses) + . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '') + . ($this->sqlParts['groupBy'] ? ' GROUP BY ' . implode(', ', $this->sqlParts['groupBy']) : '') + . ($this->sqlParts['having'] !== null ? ' HAVING ' . ((string) $this->sqlParts['having']) : '') + . ($this->sqlParts['orderBy'] ? ' ORDER BY ' . implode(', ', $this->sqlParts['orderBy']) : ''); + + return ($this->maxResults === null && $this->firstResult == null) + ? $query + : $this->connection->getDatabasePlatform()->modifyLimitQuery($query, $this->maxResults, $this->firstResult); + } + + /** + * Converts this instance into an UPDATE string in SQL. + * + * @return string + */ + private function getSQLForUpdate() + { + $table = $this->sqlParts['from']['table'] . ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : ''); + $query = 'UPDATE ' . $table + . ' SET ' . implode(", ", $this->sqlParts['set']) + . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : ''); + + return $query; + } + + /** + * Converts this instance into a DELETE string in SQL. + * + * @return string + */ + private function getSQLForDelete() + { + $table = $this->sqlParts['from']['table'] . ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : ''); + $query = 'DELETE FROM ' . $table . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : ''); + + return $query; + } + + /** + * Gets a string representation of this QueryBuilder which corresponds to + * the final SQL query being constructed. + * + * @return string The string representation of this QueryBuilder. + */ + public function __toString() + { + return $this->getSQL(); + } + + /** + * Create a new named parameter and bind the value $value to it. + * + * This method provides a shortcut for PDOStatement::bindValue + * when using prepared statements. + * + * The parameter $value specifies the value that you want to bind. If + * $placeholder is not provided bindValue() will automatically create a + * placeholder for you. An automatic placeholder will be of the name + * ':dcValue1', ':dcValue2' etc. + * + * For more information see {@link http://php.net/pdostatement-bindparam} + * + * Example: + * + * $value = 2; + * $q->eq( 'id', $q->bindValue( $value ) ); + * $stmt = $q->executeQuery(); // executed with 'id = 2' + * + * + * @license New BSD License + * @link http://www.zetacomponents.org + * @param mixed $value + * @param mixed $type + * @param string $placeHolder the name to bind with. The string must start with a colon ':'. + * @return string the placeholder name used. + */ + public function createNamedParameter( $value, $type = \PDO::PARAM_STR, $placeHolder = null ) + { + if ( $placeHolder === null ) { + $this->boundCounter++; + $placeHolder = ":dcValue" . $this->boundCounter; + } + $this->setParameter(substr($placeHolder, 1), $value, $type); + + return $placeHolder; + } + + /** + * Create a new positional parameter and bind the given value to it. + * + * Attention: If you are using positional parameters with the query builder you have + * to be very careful to bind all parameters in the order they appear in the SQL + * statement , otherwise they get bound in the wrong order which can lead to serious + * bugs in your code. + * + * Example: + * + * $qb = $conn->createQueryBuilder(); + * $qb->select('u.*') + * ->from('users', 'u') + * ->where('u.username = ' . $qb->createPositionalParameter('Foo', PDO::PARAM_STR)) + * ->orWhere('u.username = ' . $qb->createPositionalParameter('Bar', PDO::PARAM_STR)) + * + * + * @param mixed $value + * @param mixed $type + * @return string + */ + public function createPositionalParameter($value, $type = \PDO::PARAM_STR) + { + $this->boundCounter++; + $this->setParameter($this->boundCounter, $value, $type); + return "?"; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryException.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryException.php new file mode 100644 index 0000000..fe2cc2f --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryException.php @@ -0,0 +1,40 @@ +. + */ + +namespace Doctrine\DBAL\Query; + +use Doctrine\DBAL\DBALException; + +/** + * Driver interface. + * Interface that all DBAL drivers must implement. + * + * @since 2.1.4 + */ +class QueryException extends DBALException +{ + static public function unknownFromAlias($alias, $registeredAliases) + { + return new self("The given alias '" . $alias . "' is not part of " . + "any FROM clause table. The currently registered FROM-clause " . + "aliases are: " . implode(", ", $registeredAliases) . ". Join clauses " . + "are bound to from clauses to provide support for mixing of multiple " . + "from and join clauses."); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/README.markdown b/vendor/doctrine/dbal/lib/Doctrine/DBAL/README.markdown new file mode 100644 index 0000000..e69de29 diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtils.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtils.php new file mode 100644 index 0000000..b3704df --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtils.php @@ -0,0 +1,179 @@ +. + */ + + +namespace Doctrine\DBAL; + +use Doctrine\DBAL\Connection; + +/** + * Utility class that parses sql statements with regard to types and parameters. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.0 + * @author Benjamin Eberlei + */ +class SQLParserUtils +{ + /** + * Get an array of the placeholders in an sql statements as keys and their positions in the query string. + * + * Returns an integer => integer pair (indexed from zero) for a positional statement + * and a string => int[] pair for a named statement. + * + * @param string $statement + * @param bool $isPositional + * @return array + */ + static public function getPlaceholderPositions($statement, $isPositional = true) + { + $match = ($isPositional) ? '?' : ':'; + if (strpos($statement, $match) === false) { + return array(); + } + + $count = 0; + $inLiteral = false; // a valid query never starts with quotes + $stmtLen = strlen($statement); + $paramMap = array(); + for ($i = 0; $i < $stmtLen; $i++) { + if ($statement[$i] == $match && !$inLiteral) { + // real positional parameter detected + if ($isPositional) { + $paramMap[$count] = $i; + } else { + $name = ""; + // TODO: Something faster/better to match this than regex? + for ($j = $i; ($j < $stmtLen && preg_match('(([:a-zA-Z0-9_]{1}))', $statement[$j])); $j++) { + $name .= $statement[$j]; + } + $paramMap[$name][] = $i; // named parameters can be duplicated! + $i = $j; + } + ++$count; + } else if ($statement[$i] == "'" || $statement[$i] == '"') { + $inLiteral = ! $inLiteral; // switch state! + } + } + + return $paramMap; + } + + /** + * For a positional query this method can rewrite the sql statement with regard to array parameters. + * + * @param string $query + * @param array $params + * @param array $types + */ + static public function expandListParameters($query, $params, $types) + { + $isPositional = is_int(key($params)); + $arrayPositions = array(); + $bindIndex = -1; + foreach ($types AS $name => $type) { + ++$bindIndex; + if ($type === Connection::PARAM_INT_ARRAY || $type === Connection::PARAM_STR_ARRAY) { + if ($isPositional) { + $name = $bindIndex; + } + + $arrayPositions[$name] = false; + } + } + + if ((!$arrayPositions && $isPositional) || (count($params) != count($types))) { + return array($query, $params, $types); + } + + $paramPos = self::getPlaceholderPositions($query, $isPositional); + if ($isPositional) { + $paramOffset = 0; + $queryOffset = 0; + foreach ($paramPos AS $needle => $needlePos) { + if (!isset($arrayPositions[$needle])) { + continue; + } + + $needle += $paramOffset; + $needlePos += $queryOffset; + $len = count($params[$needle]); + + $params = array_merge( + array_slice($params, 0, $needle), + $params[$needle], + array_slice($params, $needle + 1) + ); + + $types = array_merge( + array_slice($types, 0, $needle), + array_fill(0, $len, $types[$needle] - Connection::ARRAY_PARAM_OFFSET), // array needles are at PDO::PARAM_* + 100 + array_slice($types, $needle + 1) + ); + + $expandStr = implode(", ", array_fill(0, $len, "?")); + $query = substr($query, 0, $needlePos) . $expandStr . substr($query, $needlePos + 1); + + $paramOffset += ($len - 1); // Grows larger by number of parameters minus the replaced needle. + $queryOffset += (strlen($expandStr) - 1); + } + + } else { + $queryOffset= 0; + $typesOrd = array(); + $paramsOrd = array(); + foreach ($paramPos as $needle => $needlePos) { + $paramLen = strlen($needle); + $token = substr($needle,0,1); + $needle = substr($needle,1); + $value = $params[$needle]; + + if (!isset($arrayPositions[$needle])) { + foreach ($needlePos as $pos) { + $pos += $queryOffset; + $queryOffset -= ($paramLen - 1); + $paramsOrd[] = $value; + $typesOrd[] = $types[$needle]; + $query = substr($query, 0, $pos) . '?' . substr($query, ($pos + $paramLen)); + } + } else { + $len = count($value); + $expandStr = implode(", ", array_fill(0, $len, "?")); + foreach ($needlePos as $pos) { + + foreach ($value as $val) { + $paramsOrd[] = $val; + $typesOrd[] = $types[$needle] - Connection::ARRAY_PARAM_OFFSET; + } + + $pos += $queryOffset; + $queryOffset += (strlen($expandStr) - $paramLen); + $query = substr($query, 0, $pos) . $expandStr . substr($query, ($pos + $paramLen)); + } + } + } + + $types = $typesOrd; + $params = $paramsOrd; + } + + return array($query, $params, $types); + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractAsset.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractAsset.php new file mode 100644 index 0000000..a14218a --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractAsset.php @@ -0,0 +1,204 @@ +. + */ + +namespace Doctrine\DBAL\Schema; + +use Doctrine\DBAL\Platforms\AbstractPlatform; + +/** + * The abstract asset allows to reset the name of all assets without publishing this to the public userland. + * + * This encapsulation hack is necessary to keep a consistent state of the database schema. Say we have a list of tables + * array($tableName => Table($tableName)); if you want to rename the table, you have to make sure + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + */ +abstract class AbstractAsset +{ + /** + * @var string + */ + protected $_name; + + /** + * Namespace of the asset. If none isset the default namespace is assumed. + * + * @var string + */ + protected $_namespace; + + /** + * @var bool + */ + protected $_quoted = false; + + /** + * Set name of this asset + * + * @param string $name + */ + protected function _setName($name) + { + if ($this->isQuoted($name)) { + $this->_quoted = true; + $name = $this->trimQuotes($name); + } + if (strpos($name, ".") !== false) { + $parts = explode(".", $name); + $this->_namespace = $parts[0]; + $name = $parts[1]; + } + $this->_name = $name; + } + + /** + * Is this asset in the default namespace? + * + * @param string $defaultNamespaceName + * @return bool + */ + public function isInDefaultNamespace($defaultNamespaceName) + { + return $this->_namespace == $defaultNamespaceName || $this->_namespace === null; + } + + /** + * Get namespace name of this asset. + * + * If NULL is returned this means the default namespace is used. + * + * @return string + */ + public function getNamespaceName() + { + return $this->_namespace; + } + + /** + * The shortest name is stripped of the default namespace. All other + * namespaced elements are returned as full-qualified names. + * + * @param string + * @return string + */ + public function getShortestName($defaultNamespaceName) + { + $shortestName = $this->getName(); + if ($this->_namespace == $defaultNamespaceName) { + $shortestName = $this->_name; + } + return strtolower($shortestName); + } + + /** + * The normalized name is full-qualified and lowerspaced. Lowerspacing is + * actually wrong, but we have to do it to keep our sanity. If you are + * using database objects that only differentiate in the casing (FOO vs + * Foo) then you will NOT be able to use Doctrine Schema abstraction. + * + * Every non-namespaced element is prefixed with the default namespace + * name which is passed as argument to this method. + * + * @return string + */ + public function getFullQualifiedName($defaultNamespaceName) + { + $name = $this->getName(); + if (!$this->_namespace) { + $name = $defaultNamespaceName . "." . $name; + } + return strtolower($name); + } + + /** + * Check if this identifier is quoted. + * + * @param string $identifier + * @return bool + */ + protected function isQuoted($identifier) + { + return (isset($identifier[0]) && ($identifier[0] == '`' || $identifier[0] == '"')); + } + + /** + * Trim quotes from the identifier. + * + * @param string $identifier + * @return string + */ + protected function trimQuotes($identifier) + { + return str_replace(array('`', '"'), '', $identifier); + } + + /** + * Return name of this schema asset. + * + * @return string + */ + public function getName() + { + if ($this->_namespace) { + return $this->_namespace . "." . $this->_name; + } + return $this->_name; + } + + /** + * Get the quoted representation of this asset but only if it was defined with one. Otherwise + * return the plain unquoted value as inserted. + * + * @param AbstractPlatform $platform + * @return string + */ + public function getQuotedName(AbstractPlatform $platform) + { + $keywords = $platform->getReservedKeywordsList(); + $parts = explode(".", $this->getName()); + foreach ($parts AS $k => $v) { + $parts[$k] = ($this->_quoted || $keywords->isKeyword($v)) ? $platform->quoteIdentifier($v) : $v; + } + + return implode(".", $parts); + } + + /** + * Generate an identifier from a list of column names obeying a certain string length. + * + * This is especially important for Oracle, since it does not allow identifiers larger than 30 chars, + * however building idents automatically for foreign keys, composite keys or such can easily create + * very long names. + * + * @param array $columnNames + * @param string $prefix + * @param int $maxSize + * @return string + */ + protected function _generateIdentifierName($columnNames, $prefix='', $maxSize=30) + { + $hash = implode("", array_map(function($column) { + return dechex(crc32($column)); + }, $columnNames)); + return substr(strtoupper($prefix . "_" . $hash), 0, $maxSize); + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php new file mode 100644 index 0000000..57fd67a --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php @@ -0,0 +1,890 @@ +. + */ + +namespace Doctrine\DBAL\Schema; + +use Doctrine\DBAL\Events; +use Doctrine\DBAL\Event\SchemaColumnDefinitionEventArgs; +use Doctrine\DBAL\Event\SchemaIndexDefinitionEventArgs; +use Doctrine\DBAL\Types; +use Doctrine\DBAL\DBALException; +use Doctrine\DBAL\Platforms\AbstractPlatform; + +/** + * Base class for schema managers. Schema managers are used to inspect and/or + * modify the database schema/structure. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @author Konsta Vesterinen + * @author Lukas Smith (PEAR MDB2 library) + * @author Roman Borschel + * @author Jonathan H. Wage + * @author Benjamin Eberlei + * @since 2.0 + */ +abstract class AbstractSchemaManager +{ + /** + * Holds instance of the Doctrine connection for this schema manager + * + * @var \Doctrine\DBAL\Connection + */ + protected $_conn; + + /** + * Holds instance of the database platform used for this schema manager + * + * @var \Doctrine\DBAL\Platforms\AbstractPlatform + */ + protected $_platform; + + /** + * Constructor. Accepts the Connection instance to manage the schema for + * + * @param \Doctrine\DBAL\Connection $conn + */ + public function __construct(\Doctrine\DBAL\Connection $conn) + { + $this->_conn = $conn; + $this->_platform = $this->_conn->getDatabasePlatform(); + } + + /** + * Return associated platform. + * + * @return \Doctrine\DBAL\Platform\AbstractPlatform + */ + public function getDatabasePlatform() + { + return $this->_platform; + } + + /** + * Try any method on the schema manager. Normally a method throws an + * exception when your DBMS doesn't support it or if an error occurs. + * This method allows you to try and method on your SchemaManager + * instance and will return false if it does not work or is not supported. + * + * + * $result = $sm->tryMethod('dropView', 'view_name'); + * + * + * @return mixed + */ + public function tryMethod() + { + $args = func_get_args(); + $method = $args[0]; + unset($args[0]); + $args = array_values($args); + + try { + return call_user_func_array(array($this, $method), $args); + } catch (\Exception $e) { + return false; + } + } + + /** + * List the available databases for this connection + * + * @return array $databases + */ + public function listDatabases() + { + $sql = $this->_platform->getListDatabasesSQL(); + + $databases = $this->_conn->fetchAll($sql); + + return $this->_getPortableDatabasesList($databases); + } + + /** + * List the available sequences for this connection + * + * @return Sequence[] + */ + public function listSequences($database = null) + { + if (is_null($database)) { + $database = $this->_conn->getDatabase(); + } + $sql = $this->_platform->getListSequencesSQL($database); + + $sequences = $this->_conn->fetchAll($sql); + + return $this->filterAssetNames($this->_getPortableSequencesList($sequences)); + } + + /** + * List the columns for a given table. + * + * In contrast to other libraries and to the old version of Doctrine, + * this column definition does try to contain the 'primary' field for + * the reason that it is not portable accross different RDBMS. Use + * {@see listTableIndexes($tableName)} to retrieve the primary key + * of a table. We're a RDBMS specifies more details these are held + * in the platformDetails array. + * + * @param string $table The name of the table. + * @param string $database + * @return Column[] + */ + public function listTableColumns($table, $database = null) + { + if (!$database) { + $database = $this->_conn->getDatabase(); + } + + $sql = $this->_platform->getListTableColumnsSQL($table, $database); + + $tableColumns = $this->_conn->fetchAll($sql); + + return $this->_getPortableTableColumnList($table, $database, $tableColumns); + } + + /** + * List the indexes for a given table returning an array of Index instances. + * + * Keys of the portable indexes list are all lower-cased. + * + * @param string $table The name of the table + * @return Index[] $tableIndexes + */ + public function listTableIndexes($table) + { + $sql = $this->_platform->getListTableIndexesSQL($table, $this->_conn->getDatabase()); + + $tableIndexes = $this->_conn->fetchAll($sql); + + return $this->_getPortableTableIndexesList($tableIndexes, $table); + } + + /** + * Return true if all the given tables exist. + * + * @param array $tableNames + * @return bool + */ + public function tablesExist($tableNames) + { + $tableNames = array_map('strtolower', (array)$tableNames); + return count($tableNames) == count(\array_intersect($tableNames, array_map('strtolower', $this->listTableNames()))); + } + + /** + * Return a list of all tables in the current database + * + * @return array + */ + public function listTableNames() + { + $sql = $this->_platform->getListTablesSQL(); + + $tables = $this->_conn->fetchAll($sql); + $tableNames = $this->_getPortableTablesList($tables); + return $this->filterAssetNames($tableNames); + } + + /** + * Filter asset names if they are configured to return only a subset of all + * the found elements. + * + * @param array $assetNames + * @return array + */ + protected function filterAssetNames($assetNames) + { + $filterExpr = $this->getFilterSchemaAssetsExpression(); + if (!$filterExpr) { + return $assetNames; + } + return array_values ( + array_filter($assetNames, function ($assetName) use ($filterExpr) { + $assetName = ($assetName instanceof AbstractAsset) ? $assetName->getName() : $assetName; + return preg_match('(' . $filterExpr . ')', $assetName); + }) + ); + } + + protected function getFilterSchemaAssetsExpression() + { + return $this->_conn->getConfiguration()->getFilterSchemaAssetsExpression(); + } + + /** + * List the tables for this connection + * + * @return Table[] + */ + public function listTables() + { + $tableNames = $this->listTableNames(); + + $tables = array(); + foreach ($tableNames AS $tableName) { + $tables[] = $this->listTableDetails($tableName); + } + + return $tables; + } + + /** + * @param string $tableName + * @return Table + */ + public function listTableDetails($tableName) + { + $columns = $this->listTableColumns($tableName); + $foreignKeys = array(); + if ($this->_platform->supportsForeignKeyConstraints()) { + $foreignKeys = $this->listTableForeignKeys($tableName); + } + $indexes = $this->listTableIndexes($tableName); + + return new Table($tableName, $columns, $indexes, $foreignKeys, false, array()); + } + + /** + * List the views this connection has + * + * @return View[] + */ + public function listViews() + { + $database = $this->_conn->getDatabase(); + $sql = $this->_platform->getListViewsSQL($database); + $views = $this->_conn->fetchAll($sql); + + return $this->_getPortableViewsList($views); + } + + /** + * List the foreign keys for the given table + * + * @param string $table The name of the table + * @return ForeignKeyConstraint[] + */ + public function listTableForeignKeys($table, $database = null) + { + if (is_null($database)) { + $database = $this->_conn->getDatabase(); + } + $sql = $this->_platform->getListTableForeignKeysSQL($table, $database); + $tableForeignKeys = $this->_conn->fetchAll($sql); + + return $this->_getPortableTableForeignKeysList($tableForeignKeys); + } + + /* drop*() Methods */ + + /** + * Drops a database. + * + * NOTE: You can not drop the database this SchemaManager is currently connected to. + * + * @param string $database The name of the database to drop + */ + public function dropDatabase($database) + { + $this->_execSql($this->_platform->getDropDatabaseSQL($database)); + } + + /** + * Drop the given table + * + * @param string $table The name of the table to drop + */ + public function dropTable($table) + { + $this->_execSql($this->_platform->getDropTableSQL($table)); + } + + /** + * Drop the index from the given table + * + * @param Index|string $index The name of the index + * @param string|Table $table The name of the table + */ + public function dropIndex($index, $table) + { + if($index instanceof Index) { + $index = $index->getQuotedName($this->_platform); + } + + $this->_execSql($this->_platform->getDropIndexSQL($index, $table)); + } + + /** + * Drop the constraint from the given table + * + * @param Constraint $constraint + * @param string $table The name of the table + */ + public function dropConstraint(Constraint $constraint, $table) + { + $this->_execSql($this->_platform->getDropConstraintSQL($constraint, $table)); + } + + /** + * Drops a foreign key from a table. + * + * @param ForeignKeyConstraint|string $table The name of the table with the foreign key. + * @param Table|string $name The name of the foreign key. + * @return boolean $result + */ + public function dropForeignKey($foreignKey, $table) + { + $this->_execSql($this->_platform->getDropForeignKeySQL($foreignKey, $table)); + } + + /** + * Drops a sequence with a given name. + * + * @param string $name The name of the sequence to drop. + */ + public function dropSequence($name) + { + $this->_execSql($this->_platform->getDropSequenceSQL($name)); + } + + /** + * Drop a view + * + * @param string $name The name of the view + * @return boolean $result + */ + public function dropView($name) + { + $this->_execSql($this->_platform->getDropViewSQL($name)); + } + + /* create*() Methods */ + + /** + * Creates a new database. + * + * @param string $database The name of the database to create. + */ + public function createDatabase($database) + { + $this->_execSql($this->_platform->getCreateDatabaseSQL($database)); + } + + /** + * Create a new table. + * + * @param Table $table + * @param int $createFlags + */ + public function createTable(Table $table) + { + $createFlags = AbstractPlatform::CREATE_INDEXES|AbstractPlatform::CREATE_FOREIGNKEYS; + $this->_execSql($this->_platform->getCreateTableSQL($table, $createFlags)); + } + + /** + * Create a new sequence + * + * @param Sequence $sequence + * @throws Doctrine\DBAL\ConnectionException if something fails at database level + */ + public function createSequence($sequence) + { + $this->_execSql($this->_platform->getCreateSequenceSQL($sequence)); + } + + /** + * Create a constraint on a table + * + * @param Constraint $constraint + * @param string|Table $table + */ + public function createConstraint(Constraint $constraint, $table) + { + $this->_execSql($this->_platform->getCreateConstraintSQL($constraint, $table)); + } + + /** + * Create a new index on a table + * + * @param Index $index + * @param string $table name of the table on which the index is to be created + */ + public function createIndex(Index $index, $table) + { + $this->_execSql($this->_platform->getCreateIndexSQL($index, $table)); + } + + /** + * Create a new foreign key + * + * @param ForeignKeyConstraint $foreignKey ForeignKey instance + * @param string|Table $table name of the table on which the foreign key is to be created + */ + public function createForeignKey(ForeignKeyConstraint $foreignKey, $table) + { + $this->_execSql($this->_platform->getCreateForeignKeySQL($foreignKey, $table)); + } + + /** + * Create a new view + * + * @param View $view + */ + public function createView(View $view) + { + $this->_execSql($this->_platform->getCreateViewSQL($view->getQuotedName($this->_platform), $view->getSql())); + } + + /* dropAndCreate*() Methods */ + + /** + * Drop and create a constraint + * + * @param Constraint $constraint + * @param string $table + * @see dropConstraint() + * @see createConstraint() + */ + public function dropAndCreateConstraint(Constraint $constraint, $table) + { + $this->tryMethod('dropConstraint', $constraint, $table); + $this->createConstraint($constraint, $table); + } + + /** + * Drop and create a new index on a table + * + * @param string|Table $table name of the table on which the index is to be created + * @param Index $index + */ + public function dropAndCreateIndex(Index $index, $table) + { + $this->tryMethod('dropIndex', $index->getQuotedName($this->_platform), $table); + $this->createIndex($index, $table); + } + + /** + * Drop and create a new foreign key + * + * @param ForeignKeyConstraint $foreignKey associative array that defines properties of the foreign key to be created. + * @param string|Table $table name of the table on which the foreign key is to be created + */ + public function dropAndCreateForeignKey(ForeignKeyConstraint $foreignKey, $table) + { + $this->tryMethod('dropForeignKey', $foreignKey, $table); + $this->createForeignKey($foreignKey, $table); + } + + /** + * Drop and create a new sequence + * + * @param Sequence $sequence + * @throws Doctrine\DBAL\ConnectionException if something fails at database level + */ + public function dropAndCreateSequence(Sequence $sequence) + { + $this->tryMethod('dropSequence', $sequence->getQuotedName($this->_platform)); + $this->createSequence($sequence); + } + + /** + * Drop and create a new table. + * + * @param Table $table + */ + public function dropAndCreateTable(Table $table) + { + $this->tryMethod('dropTable', $table->getQuotedName($this->_platform)); + $this->createTable($table); + } + + /** + * Drop and creates a new database. + * + * @param string $database The name of the database to create. + */ + public function dropAndCreateDatabase($database) + { + $this->tryMethod('dropDatabase', $database); + $this->createDatabase($database); + } + + /** + * Drop and create a new view + * + * @param View $view + */ + public function dropAndCreateView(View $view) + { + $this->tryMethod('dropView', $view->getQuotedName($this->_platform)); + $this->createView($view); + } + + /* alterTable() Methods */ + + /** + * Alter an existing tables schema + * + * @param TableDiff $tableDiff + */ + public function alterTable(TableDiff $tableDiff) + { + $queries = $this->_platform->getAlterTableSQL($tableDiff); + if (is_array($queries) && count($queries)) { + foreach ($queries AS $ddlQuery) { + $this->_execSql($ddlQuery); + } + } + } + + /** + * Rename a given table to another name + * + * @param string $name The current name of the table + * @param string $newName The new name of the table + */ + public function renameTable($name, $newName) + { + $tableDiff = new TableDiff($name); + $tableDiff->newName = $newName; + $this->alterTable($tableDiff); + } + + /** + * Methods for filtering return values of list*() methods to convert + * the native DBMS data definition to a portable Doctrine definition + */ + + protected function _getPortableDatabasesList($databases) + { + $list = array(); + foreach ($databases as $key => $value) { + if ($value = $this->_getPortableDatabaseDefinition($value)) { + $list[] = $value; + } + } + return $list; + } + + protected function _getPortableDatabaseDefinition($database) + { + return $database; + } + + protected function _getPortableFunctionsList($functions) + { + $list = array(); + foreach ($functions as $key => $value) { + if ($value = $this->_getPortableFunctionDefinition($value)) { + $list[] = $value; + } + } + return $list; + } + + protected function _getPortableFunctionDefinition($function) + { + return $function; + } + + protected function _getPortableTriggersList($triggers) + { + $list = array(); + foreach ($triggers as $key => $value) { + if ($value = $this->_getPortableTriggerDefinition($value)) { + $list[] = $value; + } + } + return $list; + } + + protected function _getPortableTriggerDefinition($trigger) + { + return $trigger; + } + + protected function _getPortableSequencesList($sequences) + { + $list = array(); + foreach ($sequences as $key => $value) { + if ($value = $this->_getPortableSequenceDefinition($value)) { + $list[] = $value; + } + } + return $list; + } + + /** + * @param array $sequence + * @return Sequence + */ + protected function _getPortableSequenceDefinition($sequence) + { + throw DBALException::notSupported('Sequences'); + } + + /** + * Independent of the database the keys of the column list result are lowercased. + * + * The name of the created column instance however is kept in its case. + * + * @param string $table The name of the table. + * @param string $database + * @param array $tableColumns + * @return array + */ + protected function _getPortableTableColumnList($table, $database, $tableColumns) + { + $eventManager = $this->_platform->getEventManager(); + + $list = array(); + foreach ($tableColumns as $key => $tableColumn) { + $column = null; + $defaultPrevented = false; + + if (null !== $eventManager && $eventManager->hasListeners(Events::onSchemaColumnDefinition)) { + $eventArgs = new SchemaColumnDefinitionEventArgs($tableColumn, $table, $database, $this->_conn); + $eventManager->dispatchEvent(Events::onSchemaColumnDefinition, $eventArgs); + + $defaultPrevented = $eventArgs->isDefaultPrevented(); + $column = $eventArgs->getColumn(); + } + + if (!$defaultPrevented) { + $column = $this->_getPortableTableColumnDefinition($tableColumn); + } + + if ($column) { + $name = strtolower($column->getQuotedName($this->_platform)); + $list[$name] = $column; + } + } + return $list; + } + + /** + * Get Table Column Definition + * + * @param array $tableColumn + * @return Column + */ + abstract protected function _getPortableTableColumnDefinition($tableColumn); + + /** + * Aggregate and group the index results according to the required data result. + * + * @param array $tableIndexRows + * @param string $tableName + * @return array + */ + protected function _getPortableTableIndexesList($tableIndexRows, $tableName=null) + { + $result = array(); + foreach($tableIndexRows AS $tableIndex) { + $indexName = $keyName = $tableIndex['key_name']; + if($tableIndex['primary']) { + $keyName = 'primary'; + } + $keyName = strtolower($keyName); + + if(!isset($result[$keyName])) { + $result[$keyName] = array( + 'name' => $indexName, + 'columns' => array($tableIndex['column_name']), + 'unique' => $tableIndex['non_unique'] ? false : true, + 'primary' => $tableIndex['primary'], + ); + } else { + $result[$keyName]['columns'][] = $tableIndex['column_name']; + } + } + + $eventManager = $this->_platform->getEventManager(); + + $indexes = array(); + foreach($result AS $indexKey => $data) { + $index = null; + $defaultPrevented = false; + + if (null !== $eventManager && $eventManager->hasListeners(Events::onSchemaIndexDefinition)) { + $eventArgs = new SchemaIndexDefinitionEventArgs($data, $tableName, $this->_conn); + $eventManager->dispatchEvent(Events::onSchemaIndexDefinition, $eventArgs); + + $defaultPrevented = $eventArgs->isDefaultPrevented(); + $index = $eventArgs->getIndex(); + } + + if (!$defaultPrevented) { + $index = new Index($data['name'], $data['columns'], $data['unique'], $data['primary']); + } + + if ($index) { + $indexes[$indexKey] = $index; + } + } + + return $indexes; + } + + protected function _getPortableTablesList($tables) + { + $list = array(); + foreach ($tables as $key => $value) { + if ($value = $this->_getPortableTableDefinition($value)) { + $list[] = $value; + } + } + return $list; + } + + protected function _getPortableTableDefinition($table) + { + return $table; + } + + protected function _getPortableUsersList($users) + { + $list = array(); + foreach ($users as $key => $value) { + if ($value = $this->_getPortableUserDefinition($value)) { + $list[] = $value; + } + } + return $list; + } + + protected function _getPortableUserDefinition($user) + { + return $user; + } + + protected function _getPortableViewsList($views) + { + $list = array(); + foreach ($views as $key => $value) { + if ($view = $this->_getPortableViewDefinition($value)) { + $viewName = strtolower($view->getQuotedName($this->_platform)); + $list[$viewName] = $view; + } + } + return $list; + } + + protected function _getPortableViewDefinition($view) + { + return false; + } + + protected function _getPortableTableForeignKeysList($tableForeignKeys) + { + $list = array(); + foreach ($tableForeignKeys as $key => $value) { + if ($value = $this->_getPortableTableForeignKeyDefinition($value)) { + $list[] = $value; + } + } + return $list; + } + + protected function _getPortableTableForeignKeyDefinition($tableForeignKey) + { + return $tableForeignKey; + } + + protected function _execSql($sql) + { + foreach ((array) $sql as $query) { + $this->_conn->executeUpdate($query); + } + } + + /** + * Create a schema instance for the current database. + * + * @return Schema + */ + public function createSchema() + { + $sequences = array(); + if($this->_platform->supportsSequences()) { + $sequences = $this->listSequences(); + } + $tables = $this->listTables(); + + return new Schema($tables, $sequences, $this->createSchemaConfig()); + } + + /** + * Create the configuration for this schema. + * + * @return SchemaConfig + */ + public function createSchemaConfig() + { + $schemaConfig = new SchemaConfig(); + $schemaConfig->setMaxIdentifierLength($this->_platform->getMaxIdentifierLength()); + + $searchPaths = $this->getSchemaSearchPaths(); + if (isset($searchPaths[0])) { + $schemaConfig->setName($searchPaths[0]); + } + + return $schemaConfig; + } + + /** + * The search path for namespaces in the currently connected database. + * + * The first entry is usually the default namespace in the Schema. All + * further namespaces contain tables/sequences which can also be addressed + * with a short, not full-qualified name. + * + * For databases that don't support subschema/namespaces this method + * returns the name of the currently connected database. + * + * @return array + */ + public function getSchemaSearchPaths() + { + return array($this->_conn->getDatabase()); + } + + /** + * Given a table comment this method tries to extract a typehint for Doctrine Type, or returns + * the type given as default. + * + * @param string $comment + * @param string $currentType + * @return string + */ + public function extractDoctrineTypeFromComment($comment, $currentType) + { + if (preg_match("(\(DC2Type:([a-zA-Z0-9]+)\))", $comment, $match)) { + $currentType = $match[1]; + } + return $currentType; + } + + public function removeDoctrineTypeFromComment($comment, $type) + { + return str_replace('(DC2Type:'.$type.')', '', $comment); + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Column.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Column.php new file mode 100644 index 0000000..cb28bc8 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Column.php @@ -0,0 +1,423 @@ +. + */ + +namespace Doctrine\DBAL\Schema; + +use \Doctrine\DBAL\Types\Type; +use Doctrine\DBAL\Schema\Visitor\Visitor; + +/** + * Object representation of a database column + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + */ +class Column extends AbstractAsset +{ + /** + * @var \Doctrine\DBAL\Types\Type + */ + protected $_type; + + /** + * @var int + */ + protected $_length = null; + + /** + * @var int + */ + protected $_precision = 10; + + /** + * @var int + */ + protected $_scale = 0; + + /** + * @var bool + */ + protected $_unsigned = false; + + /** + * @var bool + */ + protected $_fixed = false; + + /** + * @var bool + */ + protected $_notnull = true; + + /** + * @var string + */ + protected $_default = null; + + /** + * @var bool + */ + protected $_autoincrement = false; + + /** + * @var array + */ + protected $_platformOptions = array(); + + /** + * @var string + */ + protected $_columnDefinition = null; + + /** + * @var string + */ + protected $_comment = null; + + /** + * @var array + */ + protected $_customSchemaOptions = array(); + + /** + * Create a new Column + * + * @param string $columnName + * @param Doctrine\DBAL\Types\Type $type + * @param int $length + * @param bool $notNull + * @param mixed $default + * @param bool $unsigned + * @param bool $fixed + * @param int $precision + * @param int $scale + * @param array $platformOptions + */ + public function __construct($columnName, Type $type, array $options=array()) + { + $this->_setName($columnName); + $this->setType($type); + $this->setOptions($options); + } + + /** + * @param array $options + * @return Column + */ + public function setOptions(array $options) + { + foreach ($options AS $name => $value) { + $method = "set".$name; + if (method_exists($this, $method)) { + $this->$method($value); + } + } + return $this; + } + + /** + * @param Type $type + * @return Column + */ + public function setType(Type $type) + { + $this->_type = $type; + return $this; + } + + /** + * @param int $length + * @return Column + */ + public function setLength($length) + { + if($length !== null) { + $this->_length = (int)$length; + } else { + $this->_length = null; + } + return $this; + } + + /** + * @param int $precision + * @return Column + */ + public function setPrecision($precision) + { + if (!is_numeric($precision)) { + $precision = 10; // defaults to 10 when no valid precision is given. + } + + $this->_precision = (int)$precision; + return $this; + } + + /** + * @param int $scale + * @return Column + */ + public function setScale($scale) + { + if (!is_numeric($scale)) { + $scale = 0; + } + + $this->_scale = (int)$scale; + return $this; + } + + /** + * + * @param bool $unsigned + * @return Column + */ + public function setUnsigned($unsigned) + { + $this->_unsigned = (bool)$unsigned; + return $this; + } + + /** + * + * @param bool $fixed + * @return Column + */ + public function setFixed($fixed) + { + $this->_fixed = (bool)$fixed; + return $this; + } + + /** + * @param bool $notnull + * @return Column + */ + public function setNotnull($notnull) + { + $this->_notnull = (bool)$notnull; + return $this; + } + + /** + * + * @param mixed $default + * @return Column + */ + public function setDefault($default) + { + $this->_default = $default; + return $this; + } + + /** + * + * @param array $platformOptions + * @return Column + */ + public function setPlatformOptions(array $platformOptions) + { + $this->_platformOptions = $platformOptions; + return $this; + } + + /** + * + * @param string $name + * @param mixed $value + * @return Column + */ + public function setPlatformOption($name, $value) + { + $this->_platformOptions[$name] = $value; + return $this; + } + + /** + * + * @param string + * @return Column + */ + public function setColumnDefinition($value) + { + $this->_columnDefinition = $value; + return $this; + } + + public function getType() + { + return $this->_type; + } + + public function getLength() + { + return $this->_length; + } + + public function getPrecision() + { + return $this->_precision; + } + + public function getScale() + { + return $this->_scale; + } + + public function getUnsigned() + { + return $this->_unsigned; + } + + public function getFixed() + { + return $this->_fixed; + } + + public function getNotnull() + { + return $this->_notnull; + } + + public function getDefault() + { + return $this->_default; + } + + public function getPlatformOptions() + { + return $this->_platformOptions; + } + + public function hasPlatformOption($name) + { + return isset($this->_platformOptions[$name]); + } + + public function getPlatformOption($name) + { + return $this->_platformOptions[$name]; + } + + public function getColumnDefinition() + { + return $this->_columnDefinition; + } + + public function getAutoincrement() + { + return $this->_autoincrement; + } + + public function setAutoincrement($flag) + { + $this->_autoincrement = $flag; + return $this; + } + + public function setComment($comment) + { + $this->_comment = $comment; + return $this; + } + + public function getComment() + { + return $this->_comment; + } + + /** + * @param string $name + * @param mixed $value + * @return Column + */ + public function setCustomSchemaOption($name, $value) + { + $this->_customSchemaOptions[$name] = $value; + return $this; + } + + /** + * @param string $name + * @return boolean + */ + public function hasCustomSchemaOption($name) + { + return isset($this->_customSchemaOptions[$name]); + } + + /** + * @param string $name + * @return mixed + */ + public function getCustomSchemaOption($name) + { + return $this->_customSchemaOptions[$name]; + } + + /** + * @param array $customSchemaOptions + * @return Column + */ + public function setCustomSchemaOptions(array $customSchemaOptions) + { + $this->_customSchemaOptions = $customSchemaOptions; + return $this; + } + + /** + * @return array + */ + public function getCustomSchemaOptions() + { + return $this->_customSchemaOptions; + } + + /** + * @param Visitor $visitor + */ + public function visit(\Doctrine\DBAL\Schema\Visitor $visitor) + { + $visitor->accept($this); + } + + /** + * @return array + */ + public function toArray() + { + return array_merge(array( + 'name' => $this->_name, + 'type' => $this->_type, + 'default' => $this->_default, + 'notnull' => $this->_notnull, + 'length' => $this->_length, + 'precision' => $this->_precision, + 'scale' => $this->_scale, + 'fixed' => $this->_fixed, + 'unsigned' => $this->_unsigned, + 'autoincrement' => $this->_autoincrement, + 'columnDefinition' => $this->_columnDefinition, + 'comment' => $this->_comment, + ), $this->_platformOptions, $this->_customSchemaOptions); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/ColumnDiff.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/ColumnDiff.php new file mode 100644 index 0000000..4cf8969 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/ColumnDiff.php @@ -0,0 +1,58 @@ +. + */ + +namespace Doctrine\DBAL\Schema; + +/** + * Represent the change of a column + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + */ +class ColumnDiff +{ + public $oldColumnName; + + /** + * @var Column + */ + public $column; + + /** + * @var array + */ + public $changedProperties = array(); + + public function __construct($oldColumnName, Column $column, array $changedProperties = array()) + { + $this->oldColumnName = $oldColumnName; + $this->column = $column; + $this->changedProperties = $changedProperties; + } + + public function hasChanged($propertyName) + { + return in_array($propertyName, $this->changedProperties); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Comparator.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Comparator.php new file mode 100644 index 0000000..52b8ad8 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Comparator.php @@ -0,0 +1,399 @@ +. + */ + +namespace Doctrine\DBAL\Schema; + +/** + * Compare to Schemas and return an instance of SchemaDiff + * + * @copyright Copyright (C) 2005-2009 eZ Systems AS. All rights reserved. + * @license http://ez.no/licenses/new_bsd New BSD License + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + */ +class Comparator +{ + /** + * @param Schema $fromSchema + * @param Schema $toSchema + * @return SchemaDiff + */ + static public function compareSchemas( Schema $fromSchema, Schema $toSchema ) + { + $c = new self(); + return $c->compare($fromSchema, $toSchema); + } + + /** + * Returns a SchemaDiff object containing the differences between the schemas $fromSchema and $toSchema. + * + * The returned diferences are returned in such a way that they contain the + * operations to change the schema stored in $fromSchema to the schema that is + * stored in $toSchema. + * + * @param Schema $fromSchema + * @param Schema $toSchema + * + * @return SchemaDiff + */ + public function compare(Schema $fromSchema, Schema $toSchema) + { + $diff = new SchemaDiff(); + + $foreignKeysToTable = array(); + + foreach ( $toSchema->getTables() AS $table ) { + $tableName = $table->getShortestName($toSchema->getName()); + if ( ! $fromSchema->hasTable($tableName)) { + $diff->newTables[$tableName] = $toSchema->getTable($tableName); + } else { + $tableDifferences = $this->diffTable($fromSchema->getTable($tableName), $toSchema->getTable($tableName)); + if ($tableDifferences !== false) { + $diff->changedTables[$tableName] = $tableDifferences; + } + } + } + + /* Check if there are tables removed */ + foreach ($fromSchema->getTables() AS $table) { + $tableName = $table->getShortestName($fromSchema->getName()); + + $table = $fromSchema->getTable($tableName); + if ( ! $toSchema->hasTable($tableName) ) { + $diff->removedTables[$tableName] = $table; + } + + // also remember all foreign keys that point to a specific table + foreach ($table->getForeignKeys() AS $foreignKey) { + $foreignTable = strtolower($foreignKey->getForeignTableName()); + if (!isset($foreignKeysToTable[$foreignTable])) { + $foreignKeysToTable[$foreignTable] = array(); + } + $foreignKeysToTable[$foreignTable][] = $foreignKey; + } + } + + foreach ($diff->removedTables AS $tableName => $table) { + if (isset($foreignKeysToTable[$tableName])) { + $diff->orphanedForeignKeys = array_merge($diff->orphanedForeignKeys, $foreignKeysToTable[$tableName]); + } + } + + foreach ($toSchema->getSequences() AS $sequence) { + $sequenceName = $sequence->getShortestName($toSchema->getName()); + if (!$fromSchema->hasSequence($sequenceName)) { + $diff->newSequences[] = $sequence; + } else { + if ($this->diffSequence($sequence, $fromSchema->getSequence($sequenceName))) { + $diff->changedSequences[] = $toSchema->getSequence($sequenceName); + } + } + } + + foreach ($fromSchema->getSequences() AS $sequence) { + $sequenceName = $sequence->getShortestName($fromSchema->getName()); + if (!$toSchema->hasSequence($sequenceName)) { + $diff->removedSequences[] = $sequence; + } + } + + return $diff; + } + + /** + * + * @param Sequence $sequence1 + * @param Sequence $sequence2 + */ + public function diffSequence(Sequence $sequence1, Sequence $sequence2) + { + if($sequence1->getAllocationSize() != $sequence2->getAllocationSize()) { + return true; + } + + if($sequence1->getInitialValue() != $sequence2->getInitialValue()) { + return true; + } + + return false; + } + + /** + * Returns the difference between the tables $table1 and $table2. + * + * If there are no differences this method returns the boolean false. + * + * @param Table $table1 + * @param Table $table2 + * + * @return bool|TableDiff + */ + public function diffTable(Table $table1, Table $table2) + { + $changes = 0; + $tableDifferences = new TableDiff($table1->getName()); + + $table1Columns = $table1->getColumns(); + $table2Columns = $table2->getColumns(); + + /* See if all the fields in table 1 exist in table 2 */ + foreach ( $table2Columns as $columnName => $column ) { + if ( !$table1->hasColumn($columnName) ) { + $tableDifferences->addedColumns[$columnName] = $column; + $changes++; + } + } + /* See if there are any removed fields in table 2 */ + foreach ( $table1Columns as $columnName => $column ) { + if ( !$table2->hasColumn($columnName) ) { + $tableDifferences->removedColumns[$columnName] = $column; + $changes++; + } + } + + foreach ( $table1Columns as $columnName => $column ) { + if ( $table2->hasColumn($columnName) ) { + $changedProperties = $this->diffColumn( $column, $table2->getColumn($columnName) ); + if (count($changedProperties) ) { + $columnDiff = new ColumnDiff($column->getName(), $table2->getColumn($columnName), $changedProperties); + $tableDifferences->changedColumns[$column->getName()] = $columnDiff; + $changes++; + } + } + } + + $this->detectColumnRenamings($tableDifferences); + + $table1Indexes = $table1->getIndexes(); + $table2Indexes = $table2->getIndexes(); + + foreach ($table2Indexes AS $index2Name => $index2Definition) { + foreach ($table1Indexes AS $index1Name => $index1Definition) { + if ($this->diffIndex($index1Definition, $index2Definition) === false) { + unset($table1Indexes[$index1Name]); + unset($table2Indexes[$index2Name]); + } else { + if ($index1Name == $index2Name) { + $tableDifferences->changedIndexes[$index2Name] = $table2Indexes[$index2Name]; + unset($table1Indexes[$index1Name]); + unset($table2Indexes[$index2Name]); + $changes++; + } + } + } + } + + foreach ($table1Indexes AS $index1Name => $index1Definition) { + $tableDifferences->removedIndexes[$index1Name] = $index1Definition; + $changes++; + } + + foreach ($table2Indexes AS $index2Name => $index2Definition) { + $tableDifferences->addedIndexes[$index2Name] = $index2Definition; + $changes++; + } + + $fromFkeys = $table1->getForeignKeys(); + $toFkeys = $table2->getForeignKeys(); + + foreach ($fromFkeys AS $key1 => $constraint1) { + foreach ($toFkeys AS $key2 => $constraint2) { + if($this->diffForeignKey($constraint1, $constraint2) === false) { + unset($fromFkeys[$key1]); + unset($toFkeys[$key2]); + } else { + if (strtolower($constraint1->getName()) == strtolower($constraint2->getName())) { + $tableDifferences->changedForeignKeys[] = $constraint2; + $changes++; + unset($fromFkeys[$key1]); + unset($toFkeys[$key2]); + } + } + } + } + + foreach ($fromFkeys AS $key1 => $constraint1) { + $tableDifferences->removedForeignKeys[] = $constraint1; + $changes++; + } + + foreach ($toFkeys AS $key2 => $constraint2) { + $tableDifferences->addedForeignKeys[] = $constraint2; + $changes++; + } + + return $changes ? $tableDifferences : false; + } + + /** + * Try to find columns that only changed their name, rename operations maybe cheaper than add/drop + * however ambiguouties between different possibilites should not lead to renaming at all. + * + * @param TableDiff $tableDifferences + */ + private function detectColumnRenamings(TableDiff $tableDifferences) + { + $renameCandidates = array(); + foreach ($tableDifferences->addedColumns AS $addedColumnName => $addedColumn) { + foreach ($tableDifferences->removedColumns AS $removedColumnName => $removedColumn) { + if (count($this->diffColumn($addedColumn, $removedColumn)) == 0) { + $renameCandidates[$addedColumn->getName()][] = array($removedColumn, $addedColumn, $addedColumnName); + } + } + } + + foreach ($renameCandidates AS $candidate => $candidateColumns) { + if (count($candidateColumns) == 1) { + list($removedColumn, $addedColumn) = $candidateColumns[0]; + $removedColumnName = strtolower($removedColumn->getName()); + $addedColumnName = strtolower($addedColumn->getName()); + + $tableDifferences->renamedColumns[$removedColumnName] = $addedColumn; + unset($tableDifferences->addedColumns[$addedColumnName]); + unset($tableDifferences->removedColumns[$removedColumnName]); + } + } + } + + /** + * @param ForeignKeyConstraint $key1 + * @param ForeignKeyConstraint $key2 + * @return bool + */ + public function diffForeignKey(ForeignKeyConstraint $key1, ForeignKeyConstraint $key2) + { + if (array_map('strtolower', $key1->getLocalColumns()) != array_map('strtolower', $key2->getLocalColumns())) { + return true; + } + + if (array_map('strtolower', $key1->getForeignColumns()) != array_map('strtolower', $key2->getForeignColumns())) { + return true; + } + + if ($key1->onUpdate() != $key2->onUpdate()) { + return true; + } + + if ($key1->onDelete() != $key2->onDelete()) { + return true; + } + + return false; + } + + /** + * Returns the difference between the fields $field1 and $field2. + * + * If there are differences this method returns $field2, otherwise the + * boolean false. + * + * @param Column $column1 + * @param Column $column2 + * + * @return array + */ + public function diffColumn(Column $column1, Column $column2) + { + $changedProperties = array(); + if ( $column1->getType() != $column2->getType() ) { + $changedProperties[] = 'type'; + } + + if ($column1->getNotnull() != $column2->getNotnull()) { + $changedProperties[] = 'notnull'; + } + + if ($column1->getDefault() != $column2->getDefault()) { + $changedProperties[] = 'default'; + } + + if ($column1->getUnsigned() != $column2->getUnsigned()) { + $changedProperties[] = 'unsigned'; + } + + if ($column1->getType() instanceof \Doctrine\DBAL\Types\StringType) { + // check if value of length is set at all, default value assumed otherwise. + $length1 = $column1->getLength() ?: 255; + $length2 = $column2->getLength() ?: 255; + if ($length1 != $length2) { + $changedProperties[] = 'length'; + } + + if ($column1->getFixed() != $column2->getFixed()) { + $changedProperties[] = 'fixed'; + } + } + + if ($column1->getType() instanceof \Doctrine\DBAL\Types\DecimalType) { + if (($column1->getPrecision()?:10) != ($column2->getPrecision()?:10)) { + $changedProperties[] = 'precision'; + } + if ($column1->getScale() != $column2->getScale()) { + $changedProperties[] = 'scale'; + } + } + + if ($column1->getAutoincrement() != $column2->getAutoincrement()) { + $changedProperties[] = 'autoincrement'; + } + + // only allow to delete comment if its set to '' not to null. + if ($column1->getComment() !== null && $column1->getComment() != $column2->getComment()) { + $changedProperties[] = 'comment'; + } + + $options1 = $column1->getCustomSchemaOptions(); + $options2 = $column2->getCustomSchemaOptions(); + + $commonKeys = array_keys(array_intersect_key($options1, $options2)); + + foreach ($commonKeys as $key) { + if ($options1[$key] !== $options2[$key]) { + $changedProperties[] = $key; + } + } + + $diffKeys = array_keys(array_diff_key($options1, $options2) + array_diff_key($options2, $options1)); + + $changedProperties = array_merge($changedProperties, $diffKeys); + + return $changedProperties; + } + + /** + * Finds the difference between the indexes $index1 and $index2. + * + * Compares $index1 with $index2 and returns $index2 if there are any + * differences or false in case there are no differences. + * + * @param Index $index1 + * @param Index $index2 + * @return bool + */ + public function diffIndex(Index $index1, Index $index2) + { + if ($index1->isFullfilledBy($index2) && $index2->isFullfilledBy($index1)) { + return false; + } + return true; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Constraint.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Constraint.php new file mode 100644 index 0000000..9e760ff --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Constraint.php @@ -0,0 +1,38 @@ +. + */ + +namespace Doctrine\DBAL\Schema; + +/** + * Marker interface for contraints + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + */ +interface Constraint +{ + public function getName(); + + public function getColumns(); +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/DB2SchemaManager.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/DB2SchemaManager.php new file mode 100644 index 0000000..4e41eff --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/DB2SchemaManager.php @@ -0,0 +1,214 @@ +. +*/ + +namespace Doctrine\DBAL\Schema; + +use Doctrine\DBAL\Event\SchemaIndexDefinitionEventArgs; + +/** + * IBM Db2 Schema Manager + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 1.0 + * @version $Revision$ + * @author Benjamin Eberlei + */ +class DB2SchemaManager extends AbstractSchemaManager +{ + /** + * Return a list of all tables in the current database + * + * Apparently creator is the schema not the user who created it: + * {@link http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=/com.ibm.db29.doc.sqlref/db2z_sysibmsystablestable.htm} + * + * @return array + */ + public function listTableNames() + { + $sql = $this->_platform->getListTablesSQL(); + $sql .= " AND CREATOR = UPPER('".$this->_conn->getUsername()."')"; + + $tables = $this->_conn->fetchAll($sql); + + return $this->_getPortableTablesList($tables); + } + + + /** + * Get Table Column Definition + * + * @param array $tableColumn + * @return Column + */ + protected function _getPortableTableColumnDefinition($tableColumn) + { + $tableColumn = array_change_key_case($tableColumn, \CASE_LOWER); + + $length = null; + $fixed = null; + $unsigned = false; + $scale = false; + $precision = false; + + $type = $this->_platform->getDoctrineTypeMapping($tableColumn['typename']); + + switch (strtolower($tableColumn['typename'])) { + case 'varchar': + $length = $tableColumn['length']; + $fixed = false; + break; + case 'character': + $length = $tableColumn['length']; + $fixed = true; + break; + case 'clob': + $length = $tableColumn['length']; + break; + case 'decimal': + case 'double': + case 'real': + $scale = $tableColumn['scale']; + $precision = $tableColumn['length']; + break; + } + + $options = array( + 'length' => $length, + 'unsigned' => (bool)$unsigned, + 'fixed' => (bool)$fixed, + 'default' => ($tableColumn['default'] == "NULL") ? null : $tableColumn['default'], + 'notnull' => (bool) ($tableColumn['nulls'] == 'N'), + 'scale' => null, + 'precision' => null, + 'platformOptions' => array(), + ); + + if ($scale !== null && $precision !== null) { + $options['scale'] = $scale; + $options['precision'] = $precision; + } + + return new Column($tableColumn['colname'], \Doctrine\DBAL\Types\Type::getType($type), $options); + } + + protected function _getPortableTablesList($tables) + { + $tableNames = array(); + foreach ($tables AS $tableRow) { + $tableRow = array_change_key_case($tableRow, \CASE_LOWER); + $tableNames[] = $tableRow['name']; + } + return $tableNames; + } + + protected function _getPortableTableIndexesList($tableIndexes, $tableName=null) + { + $eventManager = $this->_platform->getEventManager(); + + $tableIndexRows = array(); + $indexes = array(); + foreach($tableIndexes AS $indexKey => $data) { + $data = array_change_key_case($data, \CASE_LOWER); + $unique = ($data['uniquerule'] == "D") ? false : true; + $primary = ($data['uniquerule'] == "P"); + + $indexName = strtolower($data['name']); + if ($primary) { + $keyName = 'primary'; + } else { + $keyName = $indexName; + } + + $data = array( + 'name' => $indexName, + 'columns' => explode("+", ltrim($data['colnames'], '+')), + 'unique' => $unique, + 'primary' => $primary + ); + + $index = null; + $defaultPrevented = false; + + if (null !== $eventManager && $eventManager->hasListeners(Events::onSchemaIndexDefinition)) { + $eventArgs = new SchemaIndexDefinitionEventArgs($data, $tableName, $this->_conn); + $eventManager->dispatchEvent(Events::onSchemaIndexDefinition, $eventArgs); + + $defaultPrevented = $eventArgs->isDefaultPrevented(); + $index = $eventArgs->getIndex(); + } + + if (!$defaultPrevented) { + $index = new Index($data['name'], $data['columns'], $data['unique'], $data['primary']); + } + + if ($index) { + $indexes[$indexKey] = $index; + } + } + + return $indexes; + } + + protected function _getPortableTableForeignKeyDefinition($tableForeignKey) + { + $tableForeignKey = array_change_key_case($tableForeignKey, CASE_LOWER); + + $tableForeignKey['deleterule'] = $this->_getPortableForeignKeyRuleDef($tableForeignKey['deleterule']); + $tableForeignKey['updaterule'] = $this->_getPortableForeignKeyRuleDef($tableForeignKey['updaterule']); + + return new ForeignKeyConstraint( + array_map('trim', (array)$tableForeignKey['fkcolnames']), + $tableForeignKey['reftbname'], + array_map('trim', (array)$tableForeignKey['pkcolnames']), + $tableForeignKey['relname'], + array( + 'onUpdate' => $tableForeignKey['updaterule'], + 'onDelete' => $tableForeignKey['deleterule'], + ) + ); + } + + protected function _getPortableForeignKeyRuleDef($def) + { + if ($def == "C") { + return "CASCADE"; + } else if ($def == "N") { + return "SET NULL"; + } + return null; + } + + protected function _getPortableViewDefinition($view) + { + $view = array_change_key_case($view, \CASE_LOWER); + // sadly this still segfaults on PDO_IBM, see http://pecl.php.net/bugs/bug.php?id=17199 + //$view['text'] = (is_resource($view['text']) ? stream_get_contents($view['text']) : $view['text']); + if (!is_resource($view['text'])) { + $pos = strpos($view['text'], ' AS '); + $sql = substr($view['text'], $pos+4); + } else { + $sql = ''; + } + + return new View($view['name'], $sql); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/ForeignKeyConstraint.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/ForeignKeyConstraint.php new file mode 100644 index 0000000..398c727 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/ForeignKeyConstraint.php @@ -0,0 +1,164 @@ +. + */ + +namespace Doctrine\DBAL\Schema; + +use Doctrine\DBAL\Schema\Visitor\Visitor; + +class ForeignKeyConstraint extends AbstractAsset implements Constraint +{ + /** + * @var Table + */ + protected $_localTable; + + /** + * @var array + */ + protected $_localColumnNames; + + /** + * @var string + */ + protected $_foreignTableName; + + /** + * @var array + */ + protected $_foreignColumnNames; + + /** + * @var string + */ + protected $_cascade = ''; + + /** + * @var array + */ + protected $_options; + + /** + * + * @param array $localColumnNames + * @param string $foreignTableName + * @param array $foreignColumnNames + * @param string $cascade + * @param string|null $name + */ + public function __construct(array $localColumnNames, $foreignTableName, array $foreignColumnNames, $name=null, array $options=array()) + { + $this->_setName($name); + $this->_localColumnNames = $localColumnNames; + $this->_foreignTableName = $foreignTableName; + $this->_foreignColumnNames = $foreignColumnNames; + $this->_options = $options; + } + + /** + * @return string + */ + public function getLocalTableName() + { + return $this->_localTable->getName(); + } + + /** + * @param Table $table + */ + public function setLocalTable(Table $table) + { + $this->_localTable = $table; + } + + /** + * @return array + */ + public function getLocalColumns() + { + return $this->_localColumnNames; + } + + public function getColumns() + { + return $this->_localColumnNames; + } + + /** + * @return string + */ + public function getForeignTableName() + { + return $this->_foreignTableName; + } + + /** + * @return array + */ + public function getForeignColumns() + { + return $this->_foreignColumnNames; + } + + public function hasOption($name) + { + return isset($this->_options[$name]); + } + + public function getOption($name) + { + return $this->_options[$name]; + } + + /** + * Foreign Key onUpdate status + * + * @return string|null + */ + public function onUpdate() + { + return $this->_onEvent('onUpdate'); + } + + /** + * Foreign Key onDelete status + * + * @return string|null + */ + public function onDelete() + { + return $this->_onEvent('onDelete'); + } + + /** + * @param string $event + * @return string|null + */ + private function _onEvent($event) + { + if (isset($this->_options[$event])) { + $onEvent = strtoupper($this->_options[$event]); + if (!in_array($onEvent, array('NO ACTION', 'RESTRICT'))) { + return $onEvent; + } + } + return false; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Index.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Index.php new file mode 100644 index 0000000..5a8e6c3 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Index.php @@ -0,0 +1,188 @@ +. + */ + +namespace Doctrine\DBAL\Schema; + +use Doctrine\DBAL\Schema\Visitor\Visitor; + +class Index extends AbstractAsset implements Constraint +{ + /** + * @var array + */ + protected $_columns; + + /** + * @var bool + */ + protected $_isUnique = false; + + /** + * @var bool + */ + protected $_isPrimary = false; + + /** + * @param string $indexName + * @param array $column + * @param bool $isUnique + * @param bool $isPrimary + */ + public function __construct($indexName, array $columns, $isUnique=false, $isPrimary=false) + { + $isUnique = ($isPrimary)?true:$isUnique; + + $this->_setName($indexName); + $this->_isUnique = $isUnique; + $this->_isPrimary = $isPrimary; + + foreach($columns AS $column) { + $this->_addColumn($column); + } + } + + /** + * @param string $column + */ + protected function _addColumn($column) + { + if(is_string($column)) { + $this->_columns[] = $column; + } else { + throw new \InvalidArgumentException("Expecting a string as Index Column"); + } + } + + /** + * @return array + */ + public function getColumns() + { + return $this->_columns; + } + + /** + * Is the index neither unique nor primary key? + * + * @return bool + */ + public function isSimpleIndex() + { + return !$this->_isPrimary && !$this->_isUnique; + } + + /** + * @return bool + */ + public function isUnique() + { + return $this->_isUnique; + } + + /** + * @return bool + */ + public function isPrimary() + { + return $this->_isPrimary; + } + + /** + * @param string $columnName + * @param int $pos + * @return bool + */ + public function hasColumnAtPosition($columnName, $pos=0) + { + $columnName = strtolower($columnName); + $indexColumns = \array_map('strtolower', $this->getColumns()); + return \array_search($columnName, $indexColumns) === $pos; + } + + /** + * Check if this index exactly spans the given column names in the correct order. + * + * @param array $columnNames + * @return boolean + */ + public function spansColumns(array $columnNames) + { + $sameColumns = true; + for ($i = 0; $i < count($this->_columns); $i++) { + if (!isset($columnNames[$i]) || strtolower($this->_columns[$i]) != strtolower($columnNames[$i])) { + $sameColumns = false; + } + } + return $sameColumns; + } + + /** + * Check if the other index already fullfills all the indexing and constraint needs of the current one. + * + * @param Index $other + * @return bool + */ + public function isFullfilledBy(Index $other) + { + // allow the other index to be equally large only. It being larger is an option + // but it creates a problem with scenarios of the kind PRIMARY KEY(foo,bar) UNIQUE(foo) + if (count($other->getColumns()) != count($this->getColumns())) { + return false; + } + + // Check if columns are the same, and even in the same order + $sameColumns = $this->spansColumns($other->getColumns()); + + if ($sameColumns) { + if (!$this->isUnique() && !$this->isPrimary()) { + // this is a special case: If the current key is neither primary or unique, any uniqe or + // primary key will always have the same effect for the index and there cannot be any constraint + // overlaps. This means a primary or unique index can always fullfill the requirements of just an + // index that has no constraints. + return true; + } else if ($other->isPrimary() != $this->isPrimary()) { + return false; + } else if ($other->isUnique() != $this->isUnique()) { + return false; + } + return true; + } + return false; + } + + /** + * Detect if the other index is a non-unique, non primary index that can be overwritten by this one. + * + * @param Index $other + * @return bool + */ + public function overrules(Index $other) + { + if ($other->isPrimary()) { + return false; + } else if ($this->isSimpleIndex() && $other->isUnique()) { + return false; + } + + if ($this->spansColumns($other->getColumns()) && ($this->isPrimary() || $this->isUnique())) { + return true; + } + return false; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php new file mode 100644 index 0000000..5796f94 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php @@ -0,0 +1,211 @@ +. + */ + +namespace Doctrine\DBAL\Schema; + +/** + * Schema manager for the MySql RDBMS. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @author Konsta Vesterinen + * @author Lukas Smith (PEAR MDB2 library) + * @author Roman Borschel + * @author Benjamin Eberlei + * @version $Revision$ + * @since 2.0 + */ +class MySqlSchemaManager extends AbstractSchemaManager +{ + protected function _getPortableViewDefinition($view) + { + return new View($view['TABLE_NAME'], $view['VIEW_DEFINITION']); + } + + protected function _getPortableTableDefinition($table) + { + return array_shift($table); + } + + protected function _getPortableUserDefinition($user) + { + return array( + 'user' => $user['User'], + 'password' => $user['Password'], + ); + } + + protected function _getPortableTableIndexesList($tableIndexes, $tableName=null) + { + foreach($tableIndexes AS $k => $v) { + $v = array_change_key_case($v, CASE_LOWER); + if($v['key_name'] == 'PRIMARY') { + $v['primary'] = true; + } else { + $v['primary'] = false; + } + $tableIndexes[$k] = $v; + } + + return parent::_getPortableTableIndexesList($tableIndexes, $tableName); + } + + protected function _getPortableSequenceDefinition($sequence) + { + return end($sequence); + } + + protected function _getPortableDatabaseDefinition($database) + { + return $database['Database']; + } + + /** + * Gets a portable column definition. + * + * The database type is mapped to a corresponding Doctrine mapping type. + * + * @param $tableColumn + * @return array + */ + protected function _getPortableTableColumnDefinition($tableColumn) + { + $tableColumn = array_change_key_case($tableColumn, CASE_LOWER); + + $dbType = strtolower($tableColumn['type']); + $dbType = strtok($dbType, '(), '); + if (isset($tableColumn['length'])) { + $length = $tableColumn['length']; + $decimal = ''; + } else { + $length = strtok('(), '); + $decimal = strtok('(), ') ? strtok('(), '):null; + } + $type = array(); + $unsigned = $fixed = null; + + if ( ! isset($tableColumn['name'])) { + $tableColumn['name'] = ''; + } + + $scale = null; + $precision = null; + + $type = $this->_platform->getDoctrineTypeMapping($dbType); + $type = $this->extractDoctrineTypeFromComment($tableColumn['comment'], $type); + $tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type); + + switch ($dbType) { + case 'char': + $fixed = true; + break; + case 'float': + case 'double': + case 'real': + case 'numeric': + case 'decimal': + if(preg_match('([A-Za-z]+\(([0-9]+)\,([0-9]+)\))', $tableColumn['type'], $match)) { + $precision = $match[1]; + $scale = $match[2]; + $length = null; + } + break; + case 'tinyint': + case 'smallint': + case 'mediumint': + case 'int': + case 'integer': + case 'bigint': + case 'tinyblob': + case 'mediumblob': + case 'longblob': + case 'blob': + case 'year': + $length = null; + break; + } + + $length = ((int) $length == 0) ? null : (int) $length; + $def = array( + 'type' => $type, + 'length' => $length, + 'unsigned' => (bool) $unsigned, + 'fixed' => (bool) $fixed + ); + + $options = array( + 'length' => $length, + 'unsigned' => (bool)$unsigned, + 'fixed' => (bool)$fixed, + 'default' => isset($tableColumn['default']) ? $tableColumn['default'] : null, + 'notnull' => (bool) ($tableColumn['null'] != 'YES'), + 'scale' => null, + 'precision' => null, + 'autoincrement' => (bool) (strpos($tableColumn['extra'], 'auto_increment') !== false), + 'comment' => (isset($tableColumn['comment'])) ? $tableColumn['comment'] : null + ); + + if ($scale !== null && $precision !== null) { + $options['scale'] = $scale; + $options['precision'] = $precision; + } + + return new Column($tableColumn['field'], \Doctrine\DBAL\Types\Type::getType($type), $options); + } + + protected function _getPortableTableForeignKeysList($tableForeignKeys) + { + $list = array(); + foreach ($tableForeignKeys as $key => $value) { + $value = array_change_key_case($value, CASE_LOWER); + if (!isset($list[$value['constraint_name']])) { + if (!isset($value['delete_rule']) || $value['delete_rule'] == "RESTRICT") { + $value['delete_rule'] = null; + } + if (!isset($value['update_rule']) || $value['update_rule'] == "RESTRICT") { + $value['update_rule'] = null; + } + + $list[$value['constraint_name']] = array( + 'name' => $value['constraint_name'], + 'local' => array(), + 'foreign' => array(), + 'foreignTable' => $value['referenced_table_name'], + 'onDelete' => $value['delete_rule'], + 'onUpdate' => $value['update_rule'], + ); + } + $list[$value['constraint_name']]['local'][] = $value['column_name']; + $list[$value['constraint_name']]['foreign'][] = $value['referenced_column_name']; + } + + $result = array(); + foreach($list AS $constraint) { + $result[] = new ForeignKeyConstraint( + array_values($constraint['local']), $constraint['foreignTable'], + array_values($constraint['foreign']), $constraint['name'], + array( + 'onDelete' => $constraint['onDelete'], + 'onUpdate' => $constraint['onUpdate'], + ) + ); + } + + return $result; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php new file mode 100644 index 0000000..3bbefb6 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php @@ -0,0 +1,286 @@ +. + */ + +namespace Doctrine\DBAL\Schema; + +/** + * Oracle Schema Manager + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @author Konsta Vesterinen + * @author Lukas Smith (PEAR MDB2 library) + * @author Benjamin Eberlei + * @version $Revision$ + * @since 2.0 + */ +class OracleSchemaManager extends AbstractSchemaManager +{ + protected function _getPortableViewDefinition($view) + { + $view = \array_change_key_case($view, CASE_LOWER); + + return new View($view['view_name'], $view['text']); + } + + protected function _getPortableUserDefinition($user) + { + $user = \array_change_key_case($user, CASE_LOWER); + + return array( + 'user' => $user['username'], + ); + } + + protected function _getPortableTableDefinition($table) + { + $table = \array_change_key_case($table, CASE_LOWER); + + return $table['table_name']; + } + + /** + * @license New BSD License + * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html + * @param array $tableIndexes + * @param string $tableName + * @return array + */ + protected function _getPortableTableIndexesList($tableIndexes, $tableName=null) + { + $indexBuffer = array(); + foreach ( $tableIndexes as $tableIndex ) { + $tableIndex = \array_change_key_case($tableIndex, CASE_LOWER); + + $keyName = strtolower($tableIndex['name']); + + if ( strtolower($tableIndex['is_primary']) == "p" ) { + $keyName = 'primary'; + $buffer['primary'] = true; + $buffer['non_unique'] = false; + } else { + $buffer['primary'] = false; + $buffer['non_unique'] = ( $tableIndex['is_unique'] == 0 ) ? true : false; + } + $buffer['key_name'] = $keyName; + $buffer['column_name'] = $tableIndex['column_name']; + $indexBuffer[] = $buffer; + } + return parent::_getPortableTableIndexesList($indexBuffer, $tableName); + } + + protected function _getPortableTableColumnDefinition($tableColumn) + { + $tableColumn = \array_change_key_case($tableColumn, CASE_LOWER); + + $dbType = strtolower($tableColumn['data_type']); + if(strpos($dbType, "timestamp(") === 0) { + if (strpos($dbType, "WITH TIME ZONE")) { + $dbType = "timestamptz"; + } else { + $dbType = "timestamp"; + } + } + + $type = array(); + $length = $unsigned = $fixed = null; + if ( ! empty($tableColumn['data_length'])) { + $length = $tableColumn['data_length']; + } + + if ( ! isset($tableColumn['column_name'])) { + $tableColumn['column_name'] = ''; + } + + if (stripos($tableColumn['data_default'], 'NULL') !== null) { + $tableColumn['data_default'] = null; + } + + $precision = null; + $scale = null; + + $type = $this->_platform->getDoctrineTypeMapping($dbType); + $type = $this->extractDoctrineTypeFromComment($tableColumn['comments'], $type); + $tableColumn['comments'] = $this->removeDoctrineTypeFromComment($tableColumn['comments'], $type); + + switch ($dbType) { + case 'number': + if ($tableColumn['data_precision'] == 20 && $tableColumn['data_scale'] == 0) { + $precision = 20; + $scale = 0; + $type = 'bigint'; + } elseif ($tableColumn['data_precision'] == 5 && $tableColumn['data_scale'] == 0) { + $type = 'smallint'; + $precision = 5; + $scale = 0; + } elseif ($tableColumn['data_precision'] == 1 && $tableColumn['data_scale'] == 0) { + $precision = 1; + $scale = 0; + $type = 'boolean'; + } elseif ($tableColumn['data_scale'] > 0) { + $precision = $tableColumn['data_precision']; + $scale = $tableColumn['data_scale']; + $type = 'decimal'; + } + $length = null; + break; + case 'pls_integer': + case 'binary_integer': + $length = null; + break; + case 'varchar': + case 'varchar2': + case 'nvarchar2': + $length = $tableColumn['char_length']; + $fixed = false; + break; + case 'char': + case 'nchar': + $length = $tableColumn['char_length']; + $fixed = true; + break; + case 'date': + case 'timestamp': + $length = null; + break; + case 'float': + $precision = $tableColumn['data_precision']; + $scale = $tableColumn['data_scale']; + $length = null; + break; + case 'clob': + case 'nclob': + $length = null; + break; + case 'blob': + case 'raw': + case 'long raw': + case 'bfile': + $length = null; + break; + case 'rowid': + case 'urowid': + default: + $length = null; + } + + $options = array( + 'notnull' => (bool) ($tableColumn['nullable'] === 'N'), + 'fixed' => (bool) $fixed, + 'unsigned' => (bool) $unsigned, + 'default' => $tableColumn['data_default'], + 'length' => $length, + 'precision' => $precision, + 'scale' => $scale, + 'comment' => (isset($tableColumn['comments'])) ? $tableColumn['comments'] : null, + 'platformDetails' => array(), + ); + + return new Column($tableColumn['column_name'], \Doctrine\DBAL\Types\Type::getType($type), $options); + } + + protected function _getPortableTableForeignKeysList($tableForeignKeys) + { + $list = array(); + foreach ($tableForeignKeys as $key => $value) { + $value = \array_change_key_case($value, CASE_LOWER); + if (!isset($list[$value['constraint_name']])) { + if ($value['delete_rule'] == "NO ACTION") { + $value['delete_rule'] = null; + } + + $list[$value['constraint_name']] = array( + 'name' => $value['constraint_name'], + 'local' => array(), + 'foreign' => array(), + 'foreignTable' => $value['references_table'], + 'onDelete' => $value['delete_rule'], + ); + } + $list[$value['constraint_name']]['local'][$value['position']] = $value['local_column']; + $list[$value['constraint_name']]['foreign'][$value['position']] = $value['foreign_column']; + } + + $result = array(); + foreach($list AS $constraint) { + $result[] = new ForeignKeyConstraint( + array_values($constraint['local']), $constraint['foreignTable'], + array_values($constraint['foreign']), $constraint['name'], + array('onDelete' => $constraint['onDelete']) + ); + } + + return $result; + } + + protected function _getPortableSequenceDefinition($sequence) + { + $sequence = \array_change_key_case($sequence, CASE_LOWER); + return new Sequence($sequence['sequence_name'], $sequence['increment_by'], $sequence['min_value']); + } + + protected function _getPortableFunctionDefinition($function) + { + $function = \array_change_key_case($function, CASE_LOWER); + return $function['name']; + } + + protected function _getPortableDatabaseDefinition($database) + { + $database = \array_change_key_case($database, CASE_LOWER); + return $database['username']; + } + + public function createDatabase($database = null) + { + if (is_null($database)) { + $database = $this->_conn->getDatabase(); + } + + $params = $this->_conn->getParams(); + $username = $database; + $password = $params['password']; + + $query = 'CREATE USER ' . $username . ' IDENTIFIED BY ' . $password; + $result = $this->_conn->executeUpdate($query); + + $query = 'GRANT CREATE SESSION, CREATE TABLE, UNLIMITED TABLESPACE, CREATE SEQUENCE, CREATE TRIGGER TO ' . $username; + $result = $this->_conn->executeUpdate($query); + + return true; + } + + public function dropAutoincrement($table) + { + $sql = $this->_platform->getDropAutoincrementSql($table); + foreach ($sql as $query) { + $this->_conn->executeUpdate($query); + } + + return true; + } + + public function dropTable($name) + { + $this->dropAutoincrement($name); + + return parent::dropTable($name); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php new file mode 100644 index 0000000..87b5301 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php @@ -0,0 +1,359 @@ +. + */ + +namespace Doctrine\DBAL\Schema; + +/** + * PostgreSQL Schema Manager + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @author Konsta Vesterinen + * @author Lukas Smith (PEAR MDB2 library) + * @author Benjamin Eberlei + * @since 2.0 + */ +class PostgreSqlSchemaManager extends AbstractSchemaManager +{ + /** + * @var array + */ + private $existingSchemaPaths; + + /** + * Get all the existing schema names. + * + * @return array + */ + public function getSchemaNames() + { + $rows = $this->_conn->fetchAll("SELECT nspname as schema_name FROM pg_namespace WHERE nspname !~ '^pg_.*' and nspname != 'information_schema'"); + return array_map(function($v) { return $v['schema_name']; }, $rows); + } + + /** + * Return an array of schema search paths + * + * This is a PostgreSQL only function. + * + * @return array + */ + public function getSchemaSearchPaths() + { + $params = $this->_conn->getParams(); + $schema = explode(",", $this->_conn->fetchColumn('SHOW search_path')); + if (isset($params['user'])) { + $schema = str_replace('"$user"', $params['user'], $schema); + } + return $schema; + } + + /** + * Get names of all existing schemas in the current users search path. + * + * This is a PostgreSQL only function. + * + * @return array + */ + public function getExistingSchemaSearchPaths() + { + if ($this->existingSchemaPaths === null) { + $this->determineExistingSchemaSearchPaths(); + } + return $this->existingSchemaPaths; + } + + /** + * Use this to set or reset the order of the existing schemas in the current search path of the user + * + * This is a PostgreSQL only function. + * + * @return type + */ + public function determineExistingSchemaSearchPaths() + { + $names = $this->getSchemaNames(); + $paths = $this->getSchemaSearchPaths(); + + $this->existingSchemaPaths = array_filter($paths, function ($v) use ($names) { + return in_array($v, $names); + }); + } + + protected function _getPortableTableForeignKeyDefinition($tableForeignKey) + { + $onUpdate = null; + $onDelete = null; + + if (preg_match('(ON UPDATE ([a-zA-Z0-9]+( (NULL|ACTION|DEFAULT))?))', $tableForeignKey['condef'], $match)) { + $onUpdate = $match[1]; + } + if (preg_match('(ON DELETE ([a-zA-Z0-9]+( (NULL|ACTION|DEFAULT))?))', $tableForeignKey['condef'], $match)) { + $onDelete = $match[1]; + } + + if (preg_match('/FOREIGN KEY \((.+)\) REFERENCES (.+)\((.+)\)/', $tableForeignKey['condef'], $values)) { + // PostgreSQL returns identifiers that are keywords with quotes, we need them later, don't get + // the idea to trim them here. + $localColumns = array_map('trim', explode(",", $values[1])); + $foreignColumns = array_map('trim', explode(",", $values[3])); + $foreignTable = $values[2]; + } + + return new ForeignKeyConstraint( + $localColumns, $foreignTable, $foreignColumns, $tableForeignKey['conname'], + array('onUpdate' => $onUpdate, 'onDelete' => $onDelete) + ); + } + + public function dropDatabase($database) + { + $params = $this->_conn->getParams(); + $params["dbname"] = "postgres"; + $tmpPlatform = $this->_platform; + $tmpConn = $this->_conn; + + $this->_conn = \Doctrine\DBAL\DriverManager::getConnection($params); + $this->_platform = $this->_conn->getDatabasePlatform(); + + parent::dropDatabase($database); + + $this->_platform = $tmpPlatform; + $this->_conn = $tmpConn; + } + + public function createDatabase($database) + { + $params = $this->_conn->getParams(); + $params["dbname"] = "postgres"; + $tmpPlatform = $this->_platform; + $tmpConn = $this->_conn; + + $this->_conn = \Doctrine\DBAL\DriverManager::getConnection($params); + $this->_platform = $this->_conn->getDatabasePlatform(); + + parent::createDatabase($database); + + $this->_platform = $tmpPlatform; + $this->_conn = $tmpConn; + } + + protected function _getPortableTriggerDefinition($trigger) + { + return $trigger['trigger_name']; + } + + protected function _getPortableViewDefinition($view) + { + return new View($view['viewname'], $view['definition']); + } + + protected function _getPortableUserDefinition($user) + { + return array( + 'user' => $user['usename'], + 'password' => $user['passwd'] + ); + } + + protected function _getPortableTableDefinition($table) + { + $schemas = $this->getExistingSchemaSearchPaths(); + $firstSchema = array_shift($schemas); + + if ($table['schema_name'] == $firstSchema) { + return $table['table_name']; + } else { + return $table['schema_name'] . "." . $table['table_name']; + } + } + + /** + * @license New BSD License + * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html + * @param array $tableIndexes + * @param string $tableName + * @return array + */ + protected function _getPortableTableIndexesList($tableIndexes, $tableName=null) + { + $buffer = array(); + foreach ($tableIndexes AS $row) { + $colNumbers = explode(' ', $row['indkey']); + $colNumbersSql = 'IN (' . join(' ,', $colNumbers) . ' )'; + $columnNameSql = "SELECT attnum, attname FROM pg_attribute + WHERE attrelid={$row['indrelid']} AND attnum $colNumbersSql ORDER BY attnum ASC;"; + + $stmt = $this->_conn->executeQuery($columnNameSql); + $indexColumns = $stmt->fetchAll(); + + // required for getting the order of the columns right. + foreach ($colNumbers AS $colNum) { + foreach ($indexColumns as $colRow) { + if ($colNum == $colRow['attnum']) { + $buffer[] = array( + 'key_name' => $row['relname'], + 'column_name' => trim($colRow['attname']), + 'non_unique' => !$row['indisunique'], + 'primary' => $row['indisprimary'] + ); + } + } + } + } + return parent::_getPortableTableIndexesList($buffer, $tableName); + } + + protected function _getPortableDatabaseDefinition($database) + { + return $database['datname']; + } + + protected function _getPortableSequenceDefinition($sequence) + { + if ($sequence['schemaname'] != 'public') { + $sequenceName = $sequence['schemaname'] . "." . $sequence['relname']; + } else { + $sequenceName = $sequence['relname']; + } + + $data = $this->_conn->fetchAll('SELECT min_value, increment_by FROM ' . $sequenceName); + return new Sequence($sequenceName, $data[0]['increment_by'], $data[0]['min_value']); + } + + protected function _getPortableTableColumnDefinition($tableColumn) + { + $tableColumn = array_change_key_case($tableColumn, CASE_LOWER); + + if (strtolower($tableColumn['type']) === 'varchar') { + // get length from varchar definition + $length = preg_replace('~.*\(([0-9]*)\).*~', '$1', $tableColumn['complete_type']); + $tableColumn['length'] = $length; + } + + $matches = array(); + + $autoincrement = false; + if (preg_match("/^nextval\('(.*)'(::.*)?\)$/", $tableColumn['default'], $matches)) { + $tableColumn['sequence'] = $matches[1]; + $tableColumn['default'] = null; + $autoincrement = true; + } + + if (stripos($tableColumn['default'], 'NULL') === 0) { + $tableColumn['default'] = null; + } + + $length = (isset($tableColumn['length'])) ? $tableColumn['length'] : null; + if ($length == '-1' && isset($tableColumn['atttypmod'])) { + $length = $tableColumn['atttypmod'] - 4; + } + if ((int) $length <= 0) { + $length = null; + } + $fixed = null; + + if (!isset($tableColumn['name'])) { + $tableColumn['name'] = ''; + } + + $precision = null; + $scale = null; + + $dbType = strtolower($tableColumn['type']); + if (strlen($tableColumn['domain_type']) && !$this->_platform->hasDoctrineTypeMappingFor($tableColumn['type'])) { + $dbType = strtolower($tableColumn['domain_type']); + $tableColumn['complete_type'] = $tableColumn['domain_complete_type']; + } + + $type = $this->_platform->getDoctrineTypeMapping($dbType); + $type = $this->extractDoctrineTypeFromComment($tableColumn['comment'], $type); + $tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type); + + switch ($dbType) { + case 'smallint': + case 'int2': + $length = null; + break; + case 'int': + case 'int4': + case 'integer': + $length = null; + break; + case 'bigint': + case 'int8': + $length = null; + break; + case 'bool': + case 'boolean': + $length = null; + break; + case 'text': + $fixed = false; + break; + case 'varchar': + case 'interval': + case '_varchar': + $fixed = false; + break; + case 'char': + case 'bpchar': + $fixed = true; + break; + case 'float': + case 'float4': + case 'float8': + case 'double': + case 'double precision': + case 'real': + case 'decimal': + case 'money': + case 'numeric': + if (preg_match('([A-Za-z]+\(([0-9]+)\,([0-9]+)\))', $tableColumn['complete_type'], $match)) { + $precision = $match[1]; + $scale = $match[2]; + $length = null; + } + break; + case 'year': + $length = null; + break; + } + + if ($tableColumn['default'] && preg_match("('([^']+)'::)", $tableColumn['default'], $match)) { + $tableColumn['default'] = $match[1]; + } + + $options = array( + 'length' => $length, + 'notnull' => (bool) $tableColumn['isnotnull'], + 'default' => $tableColumn['default'], + 'primary' => (bool) ($tableColumn['pri'] == 't'), + 'precision' => $precision, + 'scale' => $scale, + 'fixed' => $fixed, + 'unsigned' => false, + 'autoincrement' => $autoincrement, + 'comment' => $tableColumn['comment'], + ); + + return new Column($tableColumn['field'], \Doctrine\DBAL\Types\Type::getType($type), $options); + } + +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SQLServerSchemaManager.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SQLServerSchemaManager.php new file mode 100644 index 0000000..0a2de79 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SQLServerSchemaManager.php @@ -0,0 +1,247 @@ +. + */ + +namespace Doctrine\DBAL\Schema; + +use Doctrine\DBAL\Event\SchemaIndexDefinitionEventArgs; +use Doctrine\DBAL\Events; + +/** + * SQL Server Schema Manager + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @author Konsta Vesterinen + * @author Lukas Smith (PEAR MDB2 library) + * @author Juozas Kaziukenas + * @since 2.0 + */ +class SQLServerSchemaManager extends AbstractSchemaManager +{ + /** + * @override + */ + protected function _getPortableTableColumnDefinition($tableColumn) + { + $dbType = strtolower($tableColumn['TYPE_NAME']); + + $autoincrement = false; + if (stripos($dbType, 'identity')) { + $dbType = trim(str_ireplace('identity', '', $dbType)); + $autoincrement = true; + } + + $type = array(); + $unsigned = $fixed = null; + + if (!isset($tableColumn['name'])) { + $tableColumn['name'] = ''; + } + + $default = $tableColumn['COLUMN_DEF']; + + while ($default != ($default2 = preg_replace("/^\((.*)\)$/", '$1', $default))) { + $default = trim($default2, "'"); + } + + $length = (int) $tableColumn['LENGTH']; + + $type = $this->_platform->getDoctrineTypeMapping($dbType); + switch ($type) { + case 'char': + if ($tableColumn['LENGTH'] == '1') { + $type = 'boolean'; + if (preg_match('/^(is|has)/', $tableColumn['name'])) { + $type = array_reverse($type); + } + } + $fixed = true; + break; + case 'text': + $fixed = false; + break; + } + switch ($dbType) { + case 'nchar': + case 'nvarchar': + case 'ntext': + // Unicode data requires 2 bytes per character + $length = $length / 2; + break; + } + + $options = array( + 'length' => ($length == 0 || !in_array($type, array('text', 'string'))) ? null : $length, + 'unsigned' => (bool) $unsigned, + 'fixed' => (bool) $fixed, + 'default' => $default !== 'NULL' ? $default : null, + 'notnull' => (bool) ($tableColumn['IS_NULLABLE'] != 'YES'), + 'scale' => $tableColumn['SCALE'], + 'precision' => $tableColumn['PRECISION'], + 'autoincrement' => $autoincrement, + ); + + return new Column($tableColumn['COLUMN_NAME'], \Doctrine\DBAL\Types\Type::getType($type), $options); + } + + /** + * @override + */ + protected function _getPortableTableIndexesList($tableIndexRows, $tableName=null) + { + $result = array(); + foreach ($tableIndexRows AS $tableIndex) { + $indexName = $keyName = $tableIndex['index_name']; + if (strpos($tableIndex['index_description'], 'primary key') !== false) { + $keyName = 'primary'; + } + $keyName = strtolower($keyName); + + $result[$keyName] = array( + 'name' => $indexName, + 'columns' => explode(', ', $tableIndex['index_keys']), + 'unique' => strpos($tableIndex['index_description'], 'unique') !== false, + 'primary' => strpos($tableIndex['index_description'], 'primary key') !== false, + ); + } + + $eventManager = $this->_platform->getEventManager(); + + $indexes = array(); + foreach ($result AS $indexKey => $data) { + $index = null; + $defaultPrevented = false; + + if (null !== $eventManager && $eventManager->hasListeners(Events::onSchemaIndexDefinition)) { + $eventArgs = new SchemaIndexDefinitionEventArgs($data, $tableName, $this->_conn); + $eventManager->dispatchEvent(Events::onSchemaIndexDefinition, $eventArgs); + + $defaultPrevented = $eventArgs->isDefaultPrevented(); + $index = $eventArgs->getIndex(); + } + + if (!$defaultPrevented) { + $index = new Index($data['name'], $data['columns'], $data['unique'], $data['primary']); + } + + if ($index) { + $indexes[$indexKey] = $index; + } + } + + return $indexes; + } + + /** + * @override + */ + public function _getPortableTableForeignKeyDefinition($tableForeignKey) + { + return new ForeignKeyConstraint( + (array) $tableForeignKey['ColumnName'], + $tableForeignKey['ReferenceTableName'], + (array) $tableForeignKey['ReferenceColumnName'], + $tableForeignKey['ForeignKey'], + array( + 'onUpdate' => str_replace('_', ' ', $tableForeignKey['update_referential_action_desc']), + 'onDelete' => str_replace('_', ' ', $tableForeignKey['delete_referential_action_desc']), + ) + ); + } + + /** + * @override + */ + protected function _getPortableTableDefinition($table) + { + return $table['name']; + } + + /** + * @override + */ + protected function _getPortableDatabaseDefinition($database) + { + return $database['name']; + } + + /** + * @override + */ + protected function _getPortableViewDefinition($view) + { + // @todo + return new View($view['name'], null); + } + + /** + * List the indexes for a given table returning an array of Index instances. + * + * Keys of the portable indexes list are all lower-cased. + * + * @param string $table The name of the table + * @return Index[] $tableIndexes + */ + public function listTableIndexes($table) + { + $sql = $this->_platform->getListTableIndexesSQL($table, $this->_conn->getDatabase()); + + try { + $tableIndexes = $this->_conn->fetchAll($sql); + } catch(\PDOException $e) { + if ($e->getCode() == "IMSSP") { + return array(); + } else { + throw $e; + } + } + + return $this->_getPortableTableIndexesList($tableIndexes, $table); + } + + /** + * @override + */ + public function alterTable(TableDiff $tableDiff) + { + if(count($tableDiff->removedColumns) > 0) { + foreach($tableDiff->removedColumns as $col){ + $columnConstraintSql = $this->getColumnConstraintSQL($tableDiff->name, $col->getName()); + foreach ($this->_conn->fetchAll($columnConstraintSql) as $constraint) { + $this->_conn->exec("ALTER TABLE $tableDiff->name DROP CONSTRAINT " . $constraint['Name']); + } + } + } + + return parent::alterTable($tableDiff); + } + + /** + * This function retrieves the constraints for a given column. + */ + private function getColumnConstraintSQL($table, $column) + { + return "SELECT SysObjects.[Name] + FROM SysObjects INNER JOIN (SELECT [Name],[ID] FROM SysObjects WHERE XType = 'U') AS Tab + ON Tab.[ID] = Sysobjects.[Parent_Obj] + INNER JOIN sys.default_constraints DefCons ON DefCons.[object_id] = Sysobjects.[ID] + INNER JOIN SysColumns Col ON Col.[ColID] = DefCons.[parent_column_id] AND Col.[ID] = Tab.[ID] + WHERE Col.[Name] = " . $this->_conn->quote($column) ." AND Tab.[Name] = " . $this->_conn->quote($table) . " + ORDER BY Col.[Name]"; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Schema.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Schema.php new file mode 100644 index 0000000..2c1b642 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Schema.php @@ -0,0 +1,367 @@ +. + */ + +namespace Doctrine\DBAL\Schema; + +use Doctrine\DBAL\Schema\Visitor\CreateSchemaSqlCollector; +use Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector; +use Doctrine\DBAL\Schema\Visitor\Visitor; + +/** + * Object representation of a database schema + * + * Different vendors have very inconsistent naming with regard to the concept + * of a "schema". Doctrine understands a schema as the entity that conceptually + * wraps a set of database objects such as tables, sequences, indexes and + * foreign keys that belong to each other into a namespace. A Doctrine Schema + * has nothing to do with the "SCHEMA" defined as in PostgreSQL, it is more + * related to the concept of "DATABASE" that exists in MySQL and PostgreSQL. + * + * Every asset in the doctrine schema has a name. A name consists of either a + * namespace.local name pair or just a local unqualified name. + * + * The abstraction layer that covers a PostgreSQL schema is the namespace of an + * database object (asset). A schema can have a name, which will be used as + * default namespace for the unqualified database objects that are created in + * the schema. + * + * In the case of MySQL where cross-database queries are allowed this leads to + * databases being "misinterpreted" as namespaces. This is intentional, however + * the CREATE/DROP SQL visitors will just filter this queries and do not + * execute them. Only the queries for the currently connected database are + * executed. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + */ +class Schema extends AbstractAsset +{ + /** + * @var array + */ + protected $_tables = array(); + + /** + * @var array + */ + protected $_sequences = array(); + + /** + * @var SchemaConfig + */ + protected $_schemaConfig = false; + + /** + * @param array $tables + * @param array $sequences + * @param array $views + * @param array $triggers + * @param SchemaConfig $schemaConfig + */ + public function __construct(array $tables=array(), array $sequences=array(), SchemaConfig $schemaConfig=null) + { + if ($schemaConfig == null) { + $schemaConfig = new SchemaConfig(); + } + $this->_schemaConfig = $schemaConfig; + $this->_setName($schemaConfig->getName() ?: 'public'); + + foreach ($tables AS $table) { + $this->_addTable($table); + } + foreach ($sequences AS $sequence) { + $this->_addSequence($sequence); + } + } + + /** + * @return bool + */ + public function hasExplicitForeignKeyIndexes() + { + return $this->_schemaConfig->hasExplicitForeignKeyIndexes(); + } + + /** + * @param Table $table + */ + protected function _addTable(Table $table) + { + $tableName = $table->getFullQualifiedName($this->getName()); + if(isset($this->_tables[$tableName])) { + throw SchemaException::tableAlreadyExists($tableName); + } + + $this->_tables[$tableName] = $table; + $table->setSchemaConfig($this->_schemaConfig); + } + + /** + * @param Sequence $sequence + */ + protected function _addSequence(Sequence $sequence) + { + $seqName = $sequence->getFullQualifiedName($this->getName()); + if (isset($this->_sequences[$seqName])) { + throw SchemaException::sequenceAlreadyExists($seqName); + } + $this->_sequences[$seqName] = $sequence; + } + + /** + * Get all tables of this schema. + * + * @return array + */ + public function getTables() + { + return $this->_tables; + } + + /** + * @param string $tableName + * @return Table + */ + public function getTable($tableName) + { + $tableName = $this->getFullQualifiedAssetName($tableName); + if (!isset($this->_tables[$tableName])) { + throw SchemaException::tableDoesNotExist($tableName); + } + + return $this->_tables[$tableName]; + } + + /** + * @return string + */ + private function getFullQualifiedAssetName($name) + { + if ($this->isQuoted($name)) { + $name = $this->trimQuotes($name); + } + if (strpos($name, ".") === false) { + $name = $this->getName() . "." . $name; + } + return strtolower($name); + } + + /** + * Does this schema have a table with the given name? + * + * @param string $tableName + * @return Schema + */ + public function hasTable($tableName) + { + $tableName = $this->getFullQualifiedAssetName($tableName); + return isset($this->_tables[$tableName]); + } + + /** + * Get all table names, prefixed with a schema name, even the default one + * if present. + * + * @return array + */ + public function getTableNames() + { + return array_keys($this->_tables); + } + + public function hasSequence($sequenceName) + { + $sequenceName = $this->getFullQualifiedAssetName($sequenceName); + return isset($this->_sequences[$sequenceName]); + } + + /** + * @throws SchemaException + * @param string $sequenceName + * @return Doctrine\DBAL\Schema\Sequence + */ + public function getSequence($sequenceName) + { + $sequenceName = $this->getFullQualifiedAssetName($sequenceName); + if(!$this->hasSequence($sequenceName)) { + throw SchemaException::sequenceDoesNotExist($sequenceName); + } + return $this->_sequences[$sequenceName]; + } + + /** + * @return Doctrine\DBAL\Schema\Sequence[] + */ + public function getSequences() + { + return $this->_sequences; + } + + /** + * Create a new table + * + * @param string $tableName + * @return Table + */ + public function createTable($tableName) + { + $table = new Table($tableName); + $this->_addTable($table); + return $table; + } + + /** + * Rename a table + * + * @param string $oldTableName + * @param string $newTableName + * @return Schema + */ + public function renameTable($oldTableName, $newTableName) + { + $table = $this->getTable($oldTableName); + $table->_setName($newTableName); + + $this->dropTable($oldTableName); + $this->_addTable($table); + return $this; + } + + /** + * Drop a table from the schema. + * + * @param string $tableName + * @return Schema + */ + public function dropTable($tableName) + { + $tableName = $this->getFullQualifiedAssetName($tableName); + $table = $this->getTable($tableName); + unset($this->_tables[$tableName]); + return $this; + } + + /** + * Create a new sequence + * + * @param string $sequenceName + * @param int $allocationSize + * @param int $initialValue + * @return Sequence + */ + public function createSequence($sequenceName, $allocationSize=1, $initialValue=1) + { + $seq = new Sequence($sequenceName, $allocationSize, $initialValue); + $this->_addSequence($seq); + return $seq; + } + + /** + * @param string $sequenceName + * @return Schema + */ + public function dropSequence($sequenceName) + { + $sequenceName = $this->getFullQualifiedAssetName($sequenceName); + unset($this->_sequences[$sequenceName]); + return $this; + } + + /** + * Return an array of necessary sql queries to create the schema on the given platform. + * + * @param AbstractPlatform $platform + * @return array + */ + public function toSql(\Doctrine\DBAL\Platforms\AbstractPlatform $platform) + { + $sqlCollector = new CreateSchemaSqlCollector($platform); + $this->visit($sqlCollector); + + return $sqlCollector->getQueries(); + } + + /** + * Return an array of necessary sql queries to drop the schema on the given platform. + * + * @param AbstractPlatform $platform + * @return array + */ + public function toDropSql(\Doctrine\DBAL\Platforms\AbstractPlatform $platform) + { + $dropSqlCollector = new DropSchemaSqlCollector($platform); + $this->visit($dropSqlCollector); + + return $dropSqlCollector->getQueries(); + } + + /** + * @param Schema $toSchema + * @param AbstractPlatform $platform + */ + public function getMigrateToSql(Schema $toSchema, \Doctrine\DBAL\Platforms\AbstractPlatform $platform) + { + $comparator = new Comparator(); + $schemaDiff = $comparator->compare($this, $toSchema); + return $schemaDiff->toSql($platform); + } + + /** + * @param Schema $fromSchema + * @param AbstractPlatform $platform + */ + public function getMigrateFromSql(Schema $fromSchema, \Doctrine\DBAL\Platforms\AbstractPlatform $platform) + { + $comparator = new Comparator(); + $schemaDiff = $comparator->compare($fromSchema, $this); + return $schemaDiff->toSql($platform); + } + + /** + * @param Visitor $visitor + */ + public function visit(Visitor $visitor) + { + $visitor->acceptSchema($this); + + foreach ($this->_tables AS $table) { + $table->visit($visitor); + } + foreach ($this->_sequences AS $sequence) { + $sequence->visit($visitor); + } + } + + /** + * Cloning a Schema triggers a deep clone of all related assets. + * + * @return void + */ + public function __clone() + { + foreach ($this->_tables AS $k => $table) { + $this->_tables[$k] = clone $table; + } + foreach ($this->_sequences AS $k => $sequence) { + $this->_sequences[$k] = clone $sequence; + } + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaConfig.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaConfig.php new file mode 100644 index 0000000..d4961f4 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaConfig.php @@ -0,0 +1,98 @@ +. + */ + +namespace Doctrine\DBAL\Schema; + +/** + * Configuration for a Schema + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + */ +class SchemaConfig +{ + /** + * @var bool + */ + protected $_hasExplicitForeignKeyIndexes = false; + + /** + * @var int + */ + protected $_maxIdentifierLength = 63; + + /** + * @var string + */ + protected $_name; + + /** + * @return bool + */ + public function hasExplicitForeignKeyIndexes() + { + return $this->_hasExplicitForeignKeyIndexes; + } + + /** + * @param bool $flag + */ + public function setExplicitForeignKeyIndexes($flag) + { + $this->_hasExplicitForeignKeyIndexes = (bool)$flag; + } + + /** + * @param int $length + */ + public function setMaxIdentifierLength($length) + { + $this->_maxIdentifierLength = (int)$length; + } + + /** + * @return int + */ + public function getMaxIdentifierLength() + { + return $this->_maxIdentifierLength; + } + + /** + * Get default namespace of schema objects. + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * set default namespace name of schema objects. + * + * @param _name the value to set. + */ + public function setName($name) + { + $this->_name = $name; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaDiff.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaDiff.php new file mode 100644 index 0000000..64033c1 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaDiff.php @@ -0,0 +1,176 @@ +. + */ + +namespace Doctrine\DBAL\Schema; + +use \Doctrine\DBAL\Platforms\AbstractPlatform; + +/** + * Schema Diff + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @copyright Copyright (C) 2005-2009 eZ Systems AS. All rights reserved. + * @license http://ez.no/licenses/new_bsd New BSD License + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + */ +class SchemaDiff +{ + /** + * All added tables + * + * @var array(string=>ezcDbSchemaTable) + */ + public $newTables = array(); + + /** + * All changed tables + * + * @var array(string=>ezcDbSchemaTableDiff) + */ + public $changedTables = array(); + + /** + * All removed tables + * + * @var array(string=>Table) + */ + public $removedTables = array(); + + /** + * @var array + */ + public $newSequences = array(); + + /** + * @var array + */ + public $changedSequences = array(); + + /** + * @var array + */ + public $removedSequences = array(); + + /** + * @var array + */ + public $orphanedForeignKeys = array(); + + /** + * Constructs an SchemaDiff object. + * + * @param array(string=>Table) $newTables + * @param array(string=>TableDiff) $changedTables + * @param array(string=>bool) $removedTables + */ + public function __construct($newTables = array(), $changedTables = array(), $removedTables = array()) + { + $this->newTables = $newTables; + $this->changedTables = $changedTables; + $this->removedTables = $removedTables; + } + + /** + * The to save sql mode ensures that the following things don't happen: + * + * 1. Tables are deleted + * 2. Sequences are deleted + * 3. Foreign Keys which reference tables that would otherwise be deleted. + * + * This way it is ensured that assets are deleted which might not be relevant to the metadata schema at all. + * + * @param AbstractPlatform $platform + * @return array + */ + public function toSaveSql(AbstractPlatform $platform) + { + return $this->_toSql($platform, true); + } + + /** + * @param AbstractPlatform $platform + * @return array + */ + public function toSql(AbstractPlatform $platform) + { + return $this->_toSql($platform, false); + } + + /** + * @param AbstractPlatform $platform + * @param bool $saveMode + * @return array + */ + protected function _toSql(AbstractPlatform $platform, $saveMode = false) + { + $sql = array(); + + if ($platform->supportsForeignKeyConstraints() && $saveMode == false) { + foreach ($this->orphanedForeignKeys AS $orphanedForeignKey) { + $sql[] = $platform->getDropForeignKeySQL($orphanedForeignKey, $orphanedForeignKey->getLocalTableName()); + } + } + + if ($platform->supportsSequences() == true) { + foreach ($this->changedSequences AS $sequence) { + $sql[] = $platform->getAlterSequenceSQL($sequence); + } + + if ($saveMode === false) { + foreach ($this->removedSequences AS $sequence) { + $sql[] = $platform->getDropSequenceSQL($sequence); + } + } + + foreach ($this->newSequences AS $sequence) { + $sql[] = $platform->getCreateSequenceSQL($sequence); + } + } + + $foreignKeySql = array(); + foreach ($this->newTables AS $table) { + $sql = array_merge( + $sql, + $platform->getCreateTableSQL($table, AbstractPlatform::CREATE_INDEXES) + ); + + if ($platform->supportsForeignKeyConstraints()) { + foreach ($table->getForeignKeys() AS $foreignKey) { + $foreignKeySql[] = $platform->getCreateForeignKeySQL($foreignKey, $table); + } + } + } + $sql = array_merge($sql, $foreignKeySql); + + if ($saveMode === false) { + foreach ($this->removedTables AS $table) { + $sql[] = $platform->getDropTableSQL($table); + } + } + + foreach ($this->changedTables AS $tableDiff) { + $sql = array_merge($sql, $platform->getAlterTableSQL($tableDiff)); + } + + return $sql; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaException.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaException.php new file mode 100644 index 0000000..a8cb93d --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaException.php @@ -0,0 +1,126 @@ +getName()." requires a named foreign key, ". + "but the given foreign key from (".implode(", ", $foreignKey->getColumns()).") onto foreign table ". + "'".$foreignKey->getForeignTableName()."' (".implode(", ", $foreignKey->getForeignColumns()).") is currently ". + "unnamed." + ); + } + + static public function alterTableChangeNotSupported($changeName) { + return new self ("Alter table change not supported, given '$changeName'"); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Sequence.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Sequence.php new file mode 100644 index 0000000..6344cc7 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Sequence.php @@ -0,0 +1,87 @@ +. + */ + +namespace Doctrine\DBAL\Schema; + +use Doctrine\DBAL\Schema\Visitor\Visitor; + +/** + * Sequence Structure + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + */ +class Sequence extends AbstractAsset +{ + /** + * @var int + */ + protected $_allocationSize = 1; + + /** + * @var int + */ + protected $_initialValue = 1; + + /** + * + * @param string $name + * @param int $allocationSize + * @param int $initialValue + */ + public function __construct($name, $allocationSize=1, $initialValue=1) + { + $this->_setName($name); + $this->_allocationSize = (is_numeric($allocationSize))?$allocationSize:1; + $this->_initialValue = (is_numeric($initialValue))?$initialValue:1; + } + + public function getAllocationSize() + { + return $this->_allocationSize; + } + + public function getInitialValue() + { + return $this->_initialValue; + } + + public function setAllocationSize($allocationSize) + { + $this->_allocationSize = (is_numeric($allocationSize))?$allocationSize:1; + } + + public function setInitialValue($initialValue) + { + $this->_initialValue = (is_numeric($initialValue))?$initialValue:1; + } + + /** + * @param Visitor $visitor + */ + public function visit(Visitor $visitor) + { + $visitor->acceptSequence($this); + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php new file mode 100644 index 0000000..9e91299 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php @@ -0,0 +1,190 @@ +. + */ + +namespace Doctrine\DBAL\Schema; + +/** + * SqliteSchemaManager + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @author Konsta Vesterinen + * @author Lukas Smith (PEAR MDB2 library) + * @author Jonathan H. Wage + * @version $Revision$ + * @since 2.0 + */ +class SqliteSchemaManager extends AbstractSchemaManager +{ + /** + * {@inheritdoc} + * + * @override + */ + public function dropDatabase($database) + { + if (file_exists($database)) { + unlink($database); + } + } + + /** + * {@inheritdoc} + * + * @override + */ + public function createDatabase($database) + { + $params = $this->_conn->getParams(); + $driver = $params['driver']; + $options = array( + 'driver' => $driver, + 'path' => $database + ); + $conn = \Doctrine\DBAL\DriverManager::getConnection($options); + $conn->connect(); + $conn->close(); + } + + protected function _getPortableTableDefinition($table) + { + return $table['name']; + } + + /** + * @license New BSD License + * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html + * @param array $tableIndexes + * @param string $tableName + * @return array + */ + protected function _getPortableTableIndexesList($tableIndexes, $tableName=null) + { + $indexBuffer = array(); + + // fetch primary + $stmt = $this->_conn->executeQuery( "PRAGMA TABLE_INFO ('$tableName')" ); + $indexArray = $stmt->fetchAll(\PDO::FETCH_ASSOC); + foreach($indexArray AS $indexColumnRow) { + if($indexColumnRow['pk'] == "1") { + $indexBuffer[] = array( + 'key_name' => 'primary', + 'primary' => true, + 'non_unique' => false, + 'column_name' => $indexColumnRow['name'] + ); + } + } + + // fetch regular indexes + foreach($tableIndexes AS $tableIndex) { + // Ignore indexes with reserved names, e.g. autoindexes + if (strpos($tableIndex['name'], 'sqlite_') !== 0) { + $keyName = $tableIndex['name']; + $idx = array(); + $idx['key_name'] = $keyName; + $idx['primary'] = false; + $idx['non_unique'] = $tableIndex['unique']?false:true; + + $stmt = $this->_conn->executeQuery( "PRAGMA INDEX_INFO ( '{$keyName}' )" ); + $indexArray = $stmt->fetchAll(\PDO::FETCH_ASSOC); + + foreach ( $indexArray as $indexColumnRow ) { + $idx['column_name'] = $indexColumnRow['name']; + $indexBuffer[] = $idx; + } + } + } + + return parent::_getPortableTableIndexesList($indexBuffer, $tableName); + } + + protected function _getPortableTableIndexDefinition($tableIndex) + { + return array( + 'name' => $tableIndex['name'], + 'unique' => (bool) $tableIndex['unique'] + ); + } + + protected function _getPortableTableColumnDefinition($tableColumn) + { + $e = explode('(', $tableColumn['type']); + $tableColumn['type'] = $e[0]; + if (isset($e[1])) { + $length = trim($e[1], ')'); + $tableColumn['length'] = $length; + } + + $dbType = strtolower($tableColumn['type']); + $length = isset($tableColumn['length']) ? $tableColumn['length'] : null; + $unsigned = (boolean) isset($tableColumn['unsigned']) ? $tableColumn['unsigned'] : false; + $fixed = false; + $type = $this->_platform->getDoctrineTypeMapping($dbType); + $default = $tableColumn['dflt_value']; + if ($default == 'NULL') { + $default = null; + } + if ($default !== null) { + // SQLite returns strings wrapped in single quotes, so we need to strip them + $default = preg_replace("/^'(.*)'$/", '\1', $default); + } + $notnull = (bool) $tableColumn['notnull']; + + if ( ! isset($tableColumn['name'])) { + $tableColumn['name'] = ''; + } + + $precision = null; + $scale = null; + + switch ($dbType) { + case 'char': + $fixed = true; + break; + case 'float': + case 'double': + case 'real': + case 'decimal': + case 'numeric': + if (isset($tableColumn['length'])) { + list($precision, $scale) = array_map('trim', explode(', ', $tableColumn['length'])); + } + $length = null; + break; + } + + $options = array( + 'length' => $length, + 'unsigned' => (bool) $unsigned, + 'fixed' => $fixed, + 'notnull' => $notnull, + 'default' => $default, + 'precision' => $precision, + 'scale' => $scale, + 'autoincrement' => false, + ); + + return new Column($tableColumn['name'], \Doctrine\DBAL\Types\Type::getType($type), $options); + } + + protected function _getPortableViewDefinition($view) + { + return new View($view['name'], $view['sql']); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Table.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Table.php new file mode 100644 index 0000000..b7e3d04 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Table.php @@ -0,0 +1,645 @@ +. + */ + +namespace Doctrine\DBAL\Schema; + +use Doctrine\DBAL\Types\Type; +use Doctrine\DBAL\Schema\Visitor\Visitor; +use Doctrine\DBAL\DBALException; + +/** + * Object Representation of a table + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + */ +class Table extends AbstractAsset +{ + /** + * @var string + */ + protected $_name = null; + + /** + * @var array + */ + protected $_columns = array(); + + /** + * @var array + */ + protected $_indexes = array(); + + /** + * @var string + */ + protected $_primaryKeyName = false; + + /** + * @var array + */ + protected $_fkConstraints = array(); + + /** + * @var array + */ + protected $_options = array(); + + /** + * @var SchemaConfig + */ + protected $_schemaConfig = null; + + /** + * + * @param string $tableName + * @param array $columns + * @param array $indexes + * @param array $fkConstraints + * @param int $idGeneratorType + * @param array $options + */ + public function __construct($tableName, array $columns=array(), array $indexes=array(), array $fkConstraints=array(), $idGeneratorType = 0, array $options=array()) + { + if (strlen($tableName) == 0) { + throw DBALException::invalidTableName($tableName); + } + + $this->_setName($tableName); + $this->_idGeneratorType = $idGeneratorType; + + foreach ($columns AS $column) { + $this->_addColumn($column); + } + + foreach ($indexes AS $idx) { + $this->_addIndex($idx); + } + + foreach ($fkConstraints AS $constraint) { + $this->_addForeignKeyConstraint($constraint); + } + + $this->_options = $options; + } + + /** + * @param SchemaConfig $schemaConfig + */ + public function setSchemaConfig(SchemaConfig $schemaConfig) + { + $this->_schemaConfig = $schemaConfig; + } + + /** + * @return int + */ + protected function _getMaxIdentifierLength() + { + if ($this->_schemaConfig instanceof SchemaConfig) { + return $this->_schemaConfig->getMaxIdentifierLength(); + } else { + return 63; + } + } + + /** + * Set Primary Key + * + * @param array $columns + * @param string $indexName + * @return Table + */ + public function setPrimaryKey(array $columns, $indexName = false) + { + $primaryKey = $this->_createIndex($columns, $indexName ?: "primary", true, true); + + foreach ($columns AS $columnName) { + $column = $this->getColumn($columnName); + $column->setNotnull(true); + } + + return $primaryKey; + } + + /** + * @param array $columnNames + * @param string $indexName + * @return Table + */ + public function addIndex(array $columnNames, $indexName = null) + { + if($indexName == null) { + $indexName = $this->_generateIdentifierName( + array_merge(array($this->getName()), $columnNames), "idx", $this->_getMaxIdentifierLength() + ); + } + + return $this->_createIndex($columnNames, $indexName, false, false); + } + + /** + * + * @param array $columnNames + * @param string $indexName + * @return Table + */ + public function addUniqueIndex(array $columnNames, $indexName = null) + { + if ($indexName === null) { + $indexName = $this->_generateIdentifierName( + array_merge(array($this->getName()), $columnNames), "uniq", $this->_getMaxIdentifierLength() + ); + } + + return $this->_createIndex($columnNames, $indexName, true, false); + } + + /** + * Check if an index begins in the order of the given columns. + * + * @param array $columnsNames + * @return bool + */ + public function columnsAreIndexed(array $columnsNames) + { + foreach ($this->getIndexes() AS $index) { + /* @var $index Index */ + if ($index->spansColumns($columnsNames)) { + return true; + } + } + return false; + } + + /** + * + * @param array $columnNames + * @param string $indexName + * @param bool $isUnique + * @param bool $isPrimary + * @return Table + */ + private function _createIndex(array $columnNames, $indexName, $isUnique, $isPrimary) + { + if (preg_match('(([^a-zA-Z0-9_]+))', $indexName)) { + throw SchemaException::indexNameInvalid($indexName); + } + + foreach ($columnNames AS $columnName => $indexColOptions) { + if (is_numeric($columnName) && is_string($indexColOptions)) { + $columnName = $indexColOptions; + } + + if ( ! $this->hasColumn($columnName)) { + throw SchemaException::columnDoesNotExist($columnName, $this->_name); + } + } + $this->_addIndex(new Index($indexName, $columnNames, $isUnique, $isPrimary)); + return $this; + } + + /** + * @param string $columnName + * @param string $columnType + * @param array $options + * @return Column + */ + public function addColumn($columnName, $typeName, array $options=array()) + { + $column = new Column($columnName, Type::getType($typeName), $options); + + $this->_addColumn($column); + return $column; + } + + /** + * Rename Column + * + * @param string $oldColumnName + * @param string $newColumnName + * @return Table + */ + public function renameColumn($oldColumnName, $newColumnName) + { + $column = $this->getColumn($oldColumnName); + $this->dropColumn($oldColumnName); + + $column->_setName($newColumnName); + return $this; + } + + /** + * Change Column Details + * + * @param string $columnName + * @param array $options + * @return Table + */ + public function changeColumn($columnName, array $options) + { + $column = $this->getColumn($columnName); + $column->setOptions($options); + return $this; + } + + /** + * Drop Column from Table + * + * @param string $columnName + * @return Table + */ + public function dropColumn($columnName) + { + $columnName = strtolower($columnName); + $column = $this->getColumn($columnName); + unset($this->_columns[$columnName]); + return $this; + } + + + /** + * Add a foreign key constraint + * + * Name is inferred from the local columns + * + * @param Table $foreignTable + * @param array $localColumns + * @param array $foreignColumns + * @param array $options + * @param string $constraintName + * @return Table + */ + public function addForeignKeyConstraint($foreignTable, array $localColumnNames, array $foreignColumnNames, array $options=array(), $constraintName = null) + { + $constraintName = $constraintName ?: $this->_generateIdentifierName(array_merge((array)$this->getName(), $localColumnNames), "fk", $this->_getMaxIdentifierLength()); + return $this->addNamedForeignKeyConstraint($constraintName, $foreignTable, $localColumnNames, $foreignColumnNames, $options); + } + + /** + * Add a foreign key constraint + * + * Name is to be generated by the database itsself. + * + * @deprecated Use {@link addForeignKeyConstraint} + * @param Table $foreignTable + * @param array $localColumns + * @param array $foreignColumns + * @param array $options + * @return Table + */ + public function addUnnamedForeignKeyConstraint($foreignTable, array $localColumnNames, array $foreignColumnNames, array $options=array()) + { + return $this->addForeignKeyConstraint($foreignTable, $localColumnNames, $foreignColumnNames, $options); + } + + /** + * Add a foreign key constraint with a given name + * + * @deprecated Use {@link addForeignKeyConstraint} + * @param string $name + * @param Table $foreignTable + * @param array $localColumns + * @param array $foreignColumns + * @param array $options + * @return Table + */ + public function addNamedForeignKeyConstraint($name, $foreignTable, array $localColumnNames, array $foreignColumnNames, array $options=array()) + { + if ($foreignTable instanceof Table) { + $foreignTableName = $foreignTable->getName(); + + foreach ($foreignColumnNames AS $columnName) { + if ( ! $foreignTable->hasColumn($columnName)) { + throw SchemaException::columnDoesNotExist($columnName, $foreignTable->getName()); + } + } + } else { + $foreignTableName = $foreignTable; + } + + foreach ($localColumnNames AS $columnName) { + if ( ! $this->hasColumn($columnName)) { + throw SchemaException::columnDoesNotExist($columnName, $this->_name); + } + } + + $constraint = new ForeignKeyConstraint( + $localColumnNames, $foreignTableName, $foreignColumnNames, $name, $options + ); + $this->_addForeignKeyConstraint($constraint); + + return $this; + } + + /** + * @param string $name + * @param string $value + * @return Table + */ + public function addOption($name, $value) + { + $this->_options[$name] = $value; + return $this; + } + + /** + * @param Column $column + */ + protected function _addColumn(Column $column) + { + $columnName = $column->getName(); + $columnName = strtolower($columnName); + + if (isset($this->_columns[$columnName])) { + throw SchemaException::columnAlreadyExists($this->getName(), $columnName); + } + + $this->_columns[$columnName] = $column; + } + + /** + * Add index to table + * + * @param Index $indexCandidate + * @return Table + */ + protected function _addIndex(Index $indexCandidate) + { + // check for duplicates + foreach ($this->_indexes AS $existingIndex) { + if ($indexCandidate->isFullfilledBy($existingIndex)) { + return $this; + } + } + + $indexName = $indexCandidate->getName(); + $indexName = strtolower($indexName); + + if (isset($this->_indexes[$indexName]) || ($this->_primaryKeyName != false && $indexCandidate->isPrimary())) { + throw SchemaException::indexAlreadyExists($indexName, $this->_name); + } + + // remove overruled indexes + foreach ($this->_indexes AS $idxKey => $existingIndex) { + if ($indexCandidate->overrules($existingIndex)) { + unset($this->_indexes[$idxKey]); + } + } + + if ($indexCandidate->isPrimary()) { + $this->_primaryKeyName = $indexName; + } + + $this->_indexes[$indexName] = $indexCandidate; + return $this; + } + + /** + * @param ForeignKeyConstraint $constraint + */ + protected function _addForeignKeyConstraint(ForeignKeyConstraint $constraint) + { + $constraint->setLocalTable($this); + + if(strlen($constraint->getName())) { + $name = $constraint->getName(); + } else { + $name = $this->_generateIdentifierName( + array_merge((array)$this->getName(), $constraint->getLocalColumns()), "fk", $this->_getMaxIdentifierLength() + ); + } + $name = strtolower($name); + + $this->_fkConstraints[$name] = $constraint; + // add an explicit index on the foreign key columns. If there is already an index that fullfils this requirements drop the request. + // In the case of __construct calling this method during hydration from schema-details all the explicitly added indexes + // lead to duplicates. This creates compuation overhead in this case, however no duplicate indexes are ever added (based on columns). + $this->addIndex($constraint->getColumns()); + } + + /** + * Does Table have a foreign key constraint with the given name? + * * + * @param string $constraintName + * @return bool + */ + public function hasForeignKey($constraintName) + { + $constraintName = strtolower($constraintName); + return isset($this->_fkConstraints[$constraintName]); + } + + /** + * @param string $constraintName + * @return ForeignKeyConstraint + */ + public function getForeignKey($constraintName) + { + $constraintName = strtolower($constraintName); + if(!$this->hasForeignKey($constraintName)) { + throw SchemaException::foreignKeyDoesNotExist($constraintName, $this->_name); + } + + return $this->_fkConstraints[$constraintName]; + } + + public function removeForeignKey($constraintName) + { + $constraintName = strtolower($constraintName); + if(!$this->hasForeignKey($constraintName)) { + throw SchemaException::foreignKeyDoesNotExist($constraintName, $this->_name); + } + + unset($this->_fkConstraints[$constraintName]); + } + + /** + * @return Column[] + */ + public function getColumns() + { + $columns = $this->_columns; + + $pkCols = array(); + $fkCols = array(); + + if ($this->hasPrimaryKey()) { + $pkCols = $this->getPrimaryKey()->getColumns(); + } + foreach ($this->getForeignKeys() AS $fk) { + /* @var $fk ForeignKeyConstraint */ + $fkCols = array_merge($fkCols, $fk->getColumns()); + } + $colNames = array_unique(array_merge($pkCols, $fkCols, array_keys($columns))); + + uksort($columns, function($a, $b) use($colNames) { + return (array_search($a, $colNames) >= array_search($b, $colNames)); + }); + return $columns; + } + + + /** + * Does this table have a column with the given name? + * + * @param string $columnName + * @return bool + */ + public function hasColumn($columnName) + { + $columnName = $this->trimQuotes(strtolower($columnName)); + return isset($this->_columns[$columnName]); + } + + /** + * Get a column instance + * + * @param string $columnName + * @return Column + */ + public function getColumn($columnName) + { + $columnName = strtolower($this->trimQuotes($columnName)); + if (!$this->hasColumn($columnName)) { + throw SchemaException::columnDoesNotExist($columnName, $this->_name); + } + + return $this->_columns[$columnName]; + } + + /** + * @return Index|null + */ + public function getPrimaryKey() + { + if (!$this->hasPrimaryKey()) { + return null; + } + return $this->getIndex($this->_primaryKeyName); + } + + /** + * Check if this table has a primary key. + * + * @return bool + */ + public function hasPrimaryKey() + { + return ($this->_primaryKeyName && $this->hasIndex($this->_primaryKeyName)); + } + + /** + * @param string $indexName + * @return bool + */ + public function hasIndex($indexName) + { + $indexName = strtolower($indexName); + return (isset($this->_indexes[$indexName])); + } + + /** + * @param string $indexName + * @return Index + */ + public function getIndex($indexName) + { + $indexName = strtolower($indexName); + if (!$this->hasIndex($indexName)) { + throw SchemaException::indexDoesNotExist($indexName, $this->_name); + } + return $this->_indexes[$indexName]; + } + + /** + * @return array + */ + public function getIndexes() + { + return $this->_indexes; + } + + /** + * Get Constraints + * + * @return array + */ + public function getForeignKeys() + { + return $this->_fkConstraints; + } + + public function hasOption($name) + { + return isset($this->_options[$name]); + } + + public function getOption($name) + { + return $this->_options[$name]; + } + + public function getOptions() + { + return $this->_options; + } + + /** + * @param Visitor $visitor + */ + public function visit(Visitor $visitor) + { + $visitor->acceptTable($this); + + foreach ($this->getColumns() AS $column) { + $visitor->acceptColumn($this, $column); + } + + foreach ($this->getIndexes() AS $index) { + $visitor->acceptIndex($this, $index); + } + + foreach ($this->getForeignKeys() AS $constraint) { + $visitor->acceptForeignKey($this, $constraint); + } + } + + /** + * Clone of a Table triggers a deep clone of all affected assets + */ + public function __clone() + { + foreach ($this->_columns AS $k => $column) { + $this->_columns[$k] = clone $column; + } + foreach ($this->_indexes AS $k => $index) { + $this->_indexes[$k] = clone $index; + } + foreach ($this->_fkConstraints AS $k => $fk) { + $this->_fkConstraints[$k] = clone $fk; + $this->_fkConstraints[$k]->setLocalTable($this); + } + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/TableDiff.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/TableDiff.php new file mode 100644 index 0000000..5f99ce2 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/TableDiff.php @@ -0,0 +1,136 @@ +. + */ + +namespace Doctrine\DBAL\Schema; + +/** + * Table Diff + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @copyright Copyright (C) 2005-2009 eZ Systems AS. All rights reserved. + * @license http://ez.no/licenses/new_bsd New BSD License + * @since 2.0 + * @author Benjamin Eberlei + */ +class TableDiff +{ + /** + * @var string + */ + public $name = null; + + /** + * @var string + */ + public $newName = false; + + /** + * All added fields + * + * @var array(string=>Column) + */ + public $addedColumns; + + /** + * All changed fields + * + * @var array(string=>Column) + */ + public $changedColumns = array(); + + /** + * All removed fields + * + * @var array(string=>Column) + */ + public $removedColumns = array(); + + /** + * Columns that are only renamed from key to column instance name. + * + * @var array(string=>Column) + */ + public $renamedColumns = array(); + + /** + * All added indexes + * + * @var array(string=>Index) + */ + public $addedIndexes = array(); + + /** + * All changed indexes + * + * @var array(string=>Index) + */ + public $changedIndexes = array(); + + /** + * All removed indexes + * + * @var array(string=>bool) + */ + public $removedIndexes = array(); + + /** + * All added foreign key definitions + * + * @var array + */ + public $addedForeignKeys = array(); + + /** + * All changed foreign keys + * + * @var array + */ + public $changedForeignKeys = array(); + + /** + * All removed foreign keys + * + * @var array + */ + public $removedForeignKeys = array(); + + /** + * Constructs an TableDiff object. + * + * @param array(string=>Column) $addedColumns + * @param array(string=>Column) $changedColumns + * @param array(string=>bool) $removedColumns + * @param array(string=>Index) $addedIndexes + * @param array(string=>Index) $changedIndexes + * @param array(string=>bool) $removedIndexes + */ + public function __construct($tableName, $addedColumns = array(), + $changedColumns = array(), $removedColumns = array(), $addedIndexes = array(), + $changedIndexes = array(), $removedIndexes = array()) + { + $this->name = $tableName; + $this->addedColumns = $addedColumns; + $this->changedColumns = $changedColumns; + $this->removedColumns = $removedColumns; + $this->addedIndexes = $addedIndexes; + $this->changedIndexes = $changedIndexes; + $this->removedIndexes = $removedIndexes; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/View.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/View.php new file mode 100644 index 0000000..4a8329d --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/View.php @@ -0,0 +1,53 @@ +. +*/ + +namespace Doctrine\DBAL\Schema; + +/** + * Representation of a Database View + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 1.0 + * @version $Revision$ + * @author Benjamin Eberlei + */ +class View extends AbstractAsset +{ + /** + * @var string + */ + private $_sql; + + public function __construct($name, $sql) + { + $this->_setName($name); + $this->_sql = $sql; + } + + /** + * @return string + */ + public function getSql() + { + return $this->_sql; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php new file mode 100644 index 0000000..d0a5ac4 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php @@ -0,0 +1,147 @@ +. + */ + +namespace Doctrine\DBAL\Schema\Visitor; + +use Doctrine\DBAL\Platforms\AbstractPlatform, + Doctrine\DBAL\Schema\Table, + Doctrine\DBAL\Schema\Schema, + Doctrine\DBAL\Schema\Column, + Doctrine\DBAL\Schema\ForeignKeyConstraint, + Doctrine\DBAL\Schema\Constraint, + Doctrine\DBAL\Schema\Sequence, + Doctrine\DBAL\Schema\Index; + +class CreateSchemaSqlCollector implements Visitor +{ + /** + * @var array + */ + private $_createTableQueries = array(); + + /** + * @var array + */ + private $_createSequenceQueries = array(); + + /** + * @var array + */ + private $_createFkConstraintQueries = array(); + + /** + * + * @var \Doctrine\DBAL\Platforms\AbstractPlatform + */ + private $_platform = null; + + /** + * @param AbstractPlatform $platform + */ + public function __construct(AbstractPlatform $platform) + { + $this->_platform = $platform; + } + + /** + * @param Schema $schema + */ + public function acceptSchema(Schema $schema) + { + + } + + /** + * Generate DDL Statements to create the accepted table with all its dependencies. + * + * @param Table $table + */ + public function acceptTable(Table $table) + { + $this->_createTableQueries = array_merge($this->_createTableQueries, + $this->_platform->getCreateTableSQL($table) + ); + } + + public function acceptColumn(Table $table, Column $column) + { + + } + + /** + * @param Table $localTable + * @param ForeignKeyConstraint $fkConstraint + */ + public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint) + { + // Append the foreign key constraints SQL + if ($this->_platform->supportsForeignKeyConstraints()) { + $this->_createFkConstraintQueries = array_merge($this->_createFkConstraintQueries, + (array) $this->_platform->getCreateForeignKeySQL( + $fkConstraint, $localTable + ) + ); + } + } + + /** + * @param Table $table + * @param Index $index + */ + public function acceptIndex(Table $table, Index $index) + { + + } + + /** + * @param Sequence $sequence + */ + public function acceptSequence(Sequence $sequence) + { + $this->_createSequenceQueries = array_merge( + $this->_createSequenceQueries, (array)$this->_platform->getCreateSequenceSQL($sequence) + ); + } + + /** + * @return array + */ + public function resetQueries() + { + $this->_createTableQueries = array(); + $this->_createSequenceQueries = array(); + $this->_createFkConstraintQueries = array(); + } + + /** + * Get all queries collected so far. + * + * @return array + */ + public function getQueries() + { + return array_merge( + $this->_createTableQueries, + $this->_createSequenceQueries, + $this->_createFkConstraintQueries + ); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/DropSchemaSqlCollector.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/DropSchemaSqlCollector.php new file mode 100644 index 0000000..f59a7ea --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/DropSchemaSqlCollector.php @@ -0,0 +1,159 @@ +. + */ + +namespace Doctrine\DBAL\Schema\Visitor; + +use Doctrine\DBAL\Platforms\AbstractPlatform, + Doctrine\DBAL\Schema\Table, + Doctrine\DBAL\Schema\Schema, + Doctrine\DBAL\Schema\Column, + Doctrine\DBAL\Schema\ForeignKeyConstraint, + Doctrine\DBAL\Schema\Constraint, + Doctrine\DBAL\Schema\Sequence, + Doctrine\DBAL\Schema\Index; + +/** + * Gather SQL statements that allow to completly drop the current schema. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + */ +class DropSchemaSqlCollector implements Visitor +{ + /** + * @var \SplObjectStorage + */ + private $constraints; + + /** + * @var \SplObjectStorage + */ + private $sequences; + + /** + * @var \SplObjectStorage + */ + private $tables; + + /** + * + * @var \Doctrine\DBAL\Platforms\AbstractPlatform + */ + private $platform; + + /** + * @param AbstractPlatform $platform + */ + public function __construct(AbstractPlatform $platform) + { + $this->platform = $platform; + $this->clearQueries(); + } + + /** + * @param Schema $schema + */ + public function acceptSchema(Schema $schema) + { + + } + + /** + * @param Table $table + */ + public function acceptTable(Table $table) + { + $this->tables->attach($table); + } + + /** + * @param Column $column + */ + public function acceptColumn(Table $table, Column $column) + { + + } + + /** + * @param Table $localTable + * @param ForeignKeyConstraint $fkConstraint + */ + public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint) + { + if (strlen($fkConstraint->getName()) == 0) { + throw SchemaException::namedForeignKeyRequired($localTable, $fkConstraint); + } + + $this->constraints->attach($fkConstraint); + $this->constraints[$fkConstraint] = $localTable; + } + + /** + * @param Table $table + * @param Index $index + */ + public function acceptIndex(Table $table, Index $index) + { + + } + + /** + * @param Sequence $sequence + */ + public function acceptSequence(Sequence $sequence) + { + $this->sequences->attach($sequence); + } + + /** + * @return void + */ + public function clearQueries() + { + $this->constraints = new \SplObjectStorage(); + $this->sequences = new \SplObjectStorage(); + $this->tables = new \SplObjectStorage(); + } + + /** + * @return array + */ + public function getQueries() + { + $sql = array(); + foreach ($this->constraints AS $fkConstraint) { + $localTable = $this->constraints[$fkConstraint]; + $sql[] = $this->platform->getDropForeignKeySQL($fkConstraint, $localTable); + } + + foreach ($this->sequences AS $sequence) { + $sql[] = $this->platform->getDropSequenceSQL($sequence); + } + + foreach ($this->tables AS $table) { + $sql[] = $this->platform->getDropTableSQL($table); + } + + return $sql; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/Graphviz.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/Graphviz.php new file mode 100644 index 0000000..762f551 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/Graphviz.php @@ -0,0 +1,151 @@ +. + */ + +namespace Doctrine\DBAL\Schema\Visitor; + +use Doctrine\DBAL\Platforms\AbstractPlatform, + Doctrine\DBAL\Schema\Table, + Doctrine\DBAL\Schema\Schema, + Doctrine\DBAL\Schema\Column, + Doctrine\DBAL\Schema\ForeignKeyConstraint, + Doctrine\DBAL\Schema\Constraint, + Doctrine\DBAL\Schema\Sequence, + Doctrine\DBAL\Schema\Index; + +class Graphviz implements \Doctrine\DBAL\Schema\Visitor\Visitor +{ + private $output = ''; + + public function acceptColumn(Table $table, Column $column) + { + + } + + public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint) + { + $this->output .= $this->createNodeRelation( + $fkConstraint->getLocalTableName() . ":col" . current($fkConstraint->getLocalColumns()).":se", + $fkConstraint->getForeignTableName() . ":col" . current($fkConstraint->getForeignColumns()).":se", + array( + 'dir' => 'back', + 'arrowtail' => 'dot', + 'arrowhead' => 'normal', + ) + ); + } + + public function acceptIndex(Table $table, Index $index) + { + + } + + public function acceptSchema(Schema $schema) + { + $this->output = 'digraph "' . sha1( mt_rand() ) . '" {' . "\n"; + $this->output .= 'splines = true;' . "\n"; + $this->output .= 'overlap = false;' . "\n"; + $this->output .= 'outputorder=edgesfirst;'."\n"; + $this->output .= 'mindist = 0.6;' . "\n"; + $this->output .= 'sep = .2;' . "\n"; + } + + public function acceptSequence(Sequence $sequence) + { + + } + + public function acceptTable(Table $table) + { + $this->output .= $this->createNode( + $table->getName(), + array( + 'label' => $this->createTableLabel( $table ), + 'shape' => 'plaintext', + ) + ); + } + + private function createTableLabel( Table $table ) + { + // Start the table + $label = '<'; + + // The title + $label .= ''; + + // The attributes block + foreach( $table->getColumns() as $column ) { + $columnLabel = $column->getName(); + + $label .= ''; + $label .= ''; + $label .= ''; + } + + // End the table + $label .= '
    ' . $table->getName() . '
    '; + $label .= '' . $columnLabel . ''; + $label .= '' . strtolower($column->getType()) . ''; + if ($table->hasPrimaryKey() && in_array($column->getName(), $table->getPrimaryKey()->getColumns())) { + $label .= "\xe2\x9c\xb7"; + } + $label .= '
    >'; + + return $label; + } + + private function createNode( $name, $options ) + { + $node = $name . " ["; + foreach( $options as $key => $value ) + { + $node .= $key . '=' . $value . ' '; + } + $node .= "]\n"; + return $node; + } + + private function createNodeRelation( $node1, $node2, $options ) + { + $relation = $node1 . ' -> ' . $node2 . ' ['; + foreach( $options as $key => $value ) + { + $relation .= $key . '=' . $value . ' '; + } + $relation .= "]\n"; + return $relation; + } + + /** + * Write dot language output to a file. This should usually be a *.dot file. + * + * You have to convert the output into a viewable format. For example use "neato" on linux systems + * and execute: + * + * neato -Tpng -o er.png er.dot + * + * @param string $filename + * @return void + */ + public function write($filename) + { + file_put_contents($filename, $this->output . "}"); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/RemoveNamespacedAssets.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/RemoveNamespacedAssets.php new file mode 100644 index 0000000..f5db5af --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/RemoveNamespacedAssets.php @@ -0,0 +1,113 @@ +. + */ + +namespace Doctrine\DBAL\Schema\Visitor; + +use Doctrine\DBAL\Platforms\AbstractPlatform, + Doctrine\DBAL\Schema\Table, + Doctrine\DBAL\Schema\Schema, + Doctrine\DBAL\Schema\Column, + Doctrine\DBAL\Schema\ForeignKeyConstraint, + Doctrine\DBAL\Schema\Constraint, + Doctrine\DBAL\Schema\Sequence, + Doctrine\DBAL\Schema\Index; + +/** + * Remove assets from a schema that are not in the default namespace. + * + * Some databases such as MySQL support cross databases joins, but don't + * allow to call DDLs to a database from another connected database. + * Before a schema is serialized into SQL this visitor can cleanup schemas with + * non default namespaces. + * + * This visitor filters all these non-default namespaced tables and sequences + * and removes them from the SChema instance. + * + * @author Benjamin Eberlei + * @since 2.2 + */ +class RemoveNamespacedAssets implements Visitor +{ + /** + * @var Schema + */ + private $schema; + + /** + * @param Schema $schema + */ + public function acceptSchema(Schema $schema) + { + $this->schema = $schema; + } + + /** + * @param Table $table + */ + public function acceptTable(Table $table) + { + if ( ! $table->isInDefaultNamespace($this->schema->getName()) ) { + $this->schema->dropTable($table->getName()); + } + } + /** + * @param Sequence $sequence + */ + public function acceptSequence(Sequence $sequence) + { + if ( ! $sequence->isInDefaultNamespace($this->schema->getName()) ) { + $this->schema->dropSequence($sequence->getName()); + } + } + + /** + * @param Column $column + */ + public function acceptColumn(Table $table, Column $column) + { + } + + /** + * @param Table $localTable + * @param ForeignKeyConstraint $fkConstraint + */ + public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint) + { + // The table may already be deleted in a previous + // RemoveNamespacedAssets#acceptTable call. Removing Foreign keys that + // point to nowhere. + if ( ! $this->schema->hasTable($fkConstraint->getForeignTableName())) { + $localTable->removeForeignKey($fkConstraint->getName()); + return; + } + + $foreignTable = $this->schema->getTable($fkConstraint->getForeignTableName()); + if ( ! $foreignTable->isInDefaultNamespace($this->schema->getName()) ) { + $localTable->removeForeignKey($fkConstraint->getName()); + } + } + + /** + * @param Table $table + * @param Index $index + */ + public function acceptIndex(Table $table, Index $index) + { + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/Visitor.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/Visitor.php new file mode 100644 index 0000000..2dad80d --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/Visitor.php @@ -0,0 +1,75 @@ +. + */ + +namespace Doctrine\DBAL\Schema\Visitor; + +use Doctrine\DBAL\Platforms\AbstractPlatform, + Doctrine\DBAL\Schema\Table, + Doctrine\DBAL\Schema\Schema, + Doctrine\DBAL\Schema\Column, + Doctrine\DBAL\Schema\ForeignKeyConstraint, + Doctrine\DBAL\Schema\Constraint, + Doctrine\DBAL\Schema\Sequence, + Doctrine\DBAL\Schema\Index; + +/** + * Schema Visitor used for Validation or Generation purposes. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + */ +interface Visitor +{ + /** + * @param Schema $schema + */ + public function acceptSchema(Schema $schema); + + /** + * @param Table $table + */ + public function acceptTable(Table $table); + + /** + * @param Column $column + */ + public function acceptColumn(Table $table, Column $column); + + /** + * @param Table $localTable + * @param ForeignKeyConstraint $fkConstraint + */ + public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint); + + /** + * @param Table $table + * @param Index $index + */ + public function acceptIndex(Table $table, Index $index); + + /** + * @param Sequence $sequence + */ + public function acceptSequence(Sequence $sequence); +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Statement.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Statement.php new file mode 100644 index 0000000..cf625ad --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Statement.php @@ -0,0 +1,247 @@ +. + */ + +namespace Doctrine\DBAL; + +use PDO, + Doctrine\DBAL\Types\Type, + Doctrine\DBAL\Driver\Statement as DriverStatement; + +/** + * A thin wrapper around a Doctrine\DBAL\Driver\Statement that adds support + * for logging, DBAL mapping types, etc. + * + * @author Roman Borschel + * @since 2.0 + */ +class Statement implements \IteratorAggregate, DriverStatement +{ + /** + * @var string The SQL statement. + */ + protected $sql; + /** + * @var array The bound parameters. + */ + protected $params = array(); + /** + * @var Doctrine\DBAL\Driver\Statement The underlying driver statement. + */ + protected $stmt; + /** + * @var Doctrine\DBAL\Platforms\AbstractPlatform The underlying database platform. + */ + protected $platform; + /** + * @var Doctrine\DBAL\Connection The connection this statement is bound to and executed on. + */ + protected $conn; + + /** + * Creates a new Statement for the given SQL and Connection. + * + * @param string $sql The SQL of the statement. + * @param Doctrine\DBAL\Connection The connection on which the statement should be executed. + */ + public function __construct($sql, Connection $conn) + { + $this->sql = $sql; + $this->stmt = $conn->getWrappedConnection()->prepare($sql); + $this->conn = $conn; + $this->platform = $conn->getDatabasePlatform(); + } + + /** + * Binds a parameter value to the statement. + * + * The value can optionally be bound with a PDO binding type or a DBAL mapping type. + * If bound with a DBAL mapping type, the binding type is derived from the mapping + * type and the value undergoes the conversion routines of the mapping type before + * being bound. + * + * @param $name The name or position of the parameter. + * @param $value The value of the parameter. + * @param mixed $type Either a PDO binding type or a DBAL mapping type name or instance. + * @return boolean TRUE on success, FALSE on failure. + */ + public function bindValue($name, $value, $type = null) + { + $this->params[$name] = $value; + if ($type !== null) { + if (is_string($type)) { + $type = Type::getType($type); + } + if ($type instanceof Type) { + $value = $type->convertToDatabaseValue($value, $this->platform); + $bindingType = $type->getBindingType(); + } else { + $bindingType = $type; // PDO::PARAM_* constants + } + return $this->stmt->bindValue($name, $value, $bindingType); + } else { + return $this->stmt->bindValue($name, $value); + } + } + + /** + * Binds a parameter to a value by reference. + * + * Binding a parameter by reference does not support DBAL mapping types. + * + * @param string $name The name or position of the parameter. + * @param mixed $value The reference to the variable to bind + * @param integer $type The PDO binding type. + * @return boolean TRUE on success, FALSE on failure. + */ + public function bindParam($name, &$var, $type = PDO::PARAM_STR) + { + return $this->stmt->bindParam($name, $var, $type); + } + + /** + * Executes the statement with the currently bound parameters. + * + * @return boolean TRUE on success, FALSE on failure. + */ + public function execute($params = null) + { + $hasLogger = $this->conn->getConfiguration()->getSQLLogger(); + if ($hasLogger) { + $this->conn->getConfiguration()->getSQLLogger()->startQuery($this->sql, $this->params); + } + + $stmt = $this->stmt->execute($params); + + if ($hasLogger) { + $this->conn->getConfiguration()->getSQLLogger()->stopQuery(); + } + $this->params = array(); + return $stmt; + } + + /** + * Closes the cursor, freeing the database resources used by this statement. + * + * @return boolean TRUE on success, FALSE on failure. + */ + public function closeCursor() + { + return $this->stmt->closeCursor(); + } + + /** + * Returns the number of columns in the result set. + * + * @return integer + */ + public function columnCount() + { + return $this->stmt->columnCount(); + } + + /** + * Fetches the SQLSTATE associated with the last operation on the statement. + * + * @return string + */ + public function errorCode() + { + return $this->stmt->errorCode(); + } + + /** + * Fetches extended error information associated with the last operation on the statement. + * + * @return array + */ + public function errorInfo() + { + return $this->stmt->errorInfo(); + } + + public function setFetchMode($fetchStyle, $arg2 = null, $arg3 = null) + { + return $this->stmt->setFetchMode($fetchStyle, $arg2, $arg3); + } + + public function getIterator() + { + return $this->stmt; + } + + /** + * Fetches the next row from a result set. + * + * @param integer $fetchStyle + * @return mixed The return value of this function on success depends on the fetch type. + * In all cases, FALSE is returned on failure. + */ + public function fetch($fetchStyle = PDO::FETCH_BOTH) + { + return $this->stmt->fetch($fetchStyle); + } + + /** + * Returns an array containing all of the result set rows. + * + * @param integer $fetchStyle + * @param mixed $fetchArgument + * @return array An array containing all of the remaining rows in the result set. + */ + public function fetchAll($fetchStyle = PDO::FETCH_BOTH, $fetchArgument = 0) + { + if ($fetchArgument !== 0) { + return $this->stmt->fetchAll($fetchStyle, $fetchArgument); + } + return $this->stmt->fetchAll($fetchStyle); + } + + /** + * Returns a single column from the next row of a result set. + * + * @param integer $columnIndex + * @return mixed A single column from the next row of a result set or FALSE if there are no more rows. + */ + public function fetchColumn($columnIndex = 0) + { + return $this->stmt->fetchColumn($columnIndex); + } + + /** + * Returns the number of rows affected by the last execution of this statement. + * + * @return integer The number of affected rows. + */ + public function rowCount() + { + return $this->stmt->rowCount(); + } + + /** + * Gets the wrapped driver statement. + * + * @return Doctrine\DBAL\Driver\Statement + */ + public function getWrappedStatement() + { + return $this->stmt; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ImportCommand.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ImportCommand.php new file mode 100644 index 0000000..96eaa11 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ImportCommand.php @@ -0,0 +1,124 @@ +. + */ + +namespace Doctrine\DBAL\Tools\Console\Command; + +use Symfony\Component\Console\Input\InputArgument, + Symfony\Component\Console; + +/** + * Task for executing arbitrary SQL that can come from a file or directly from + * the command line. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class ImportCommand extends Console\Command\Command +{ + /** + * @see Console\Command\Command + */ + protected function configure() + { + $this + ->setName('dbal:import') + ->setDescription('Import SQL file(s) directly to Database.') + ->setDefinition(array( + new InputArgument( + 'file', InputArgument::REQUIRED | InputArgument::IS_ARRAY, 'File path(s) of SQL to be executed.' + ) + )) + ->setHelp(<<getHelper('db')->getConnection(); + + if (($fileNames = $input->getArgument('file')) !== null) { + foreach ((array) $fileNames as $fileName) { + $fileName = realpath($fileName); + + if ( ! file_exists($fileName)) { + throw new \InvalidArgumentException( + sprintf("SQL file '%s' does not exist.", $fileName) + ); + } else if ( ! is_readable($fileName)) { + throw new \InvalidArgumentException( + sprintf("SQL file '%s' does not have read permissions.", $fileName) + ); + } + + $output->write(sprintf("Processing file '%s'... ", $fileName)); + $sql = file_get_contents($fileName); + + if ($conn instanceof \Doctrine\DBAL\Driver\PDOConnection) { + // PDO Drivers + try { + $lines = 0; + + $stmt = $conn->prepare($sql); + $stmt->execute(); + + do { + // Required due to "MySQL has gone away!" issue + $stmt->fetch(); + $stmt->closeCursor(); + + $lines++; + } while ($stmt->nextRowset()); + + $output->write(sprintf('%d statements executed!', $lines) . PHP_EOL); + } catch (\PDOException $e) { + $output->write('error!' . PHP_EOL); + + throw new \RuntimeException($e->getMessage(), $e->getCode(), $e); + } + } else { + // Non-PDO Drivers (ie. OCI8 driver) + $stmt = $conn->prepare($sql); + $rs = $stmt->execute(); + + if ($rs) { + $output->writeln('OK!' . PHP_EOL); + } else { + $error = $stmt->errorInfo(); + + $output->write('error!' . PHP_EOL); + + throw new \RuntimeException($error[2], $error[0]); + } + + $stmt->closeCursor(); + } + } + } + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ReservedWordsCommand.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ReservedWordsCommand.php new file mode 100644 index 0000000..9bf0a27 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ReservedWordsCommand.php @@ -0,0 +1,133 @@ +. + */ + + +namespace Doctrine\DBAL\Tools\Console\Command; + +use Symfony\Component\Console\Input\InputArgument, + Symfony\Component\Console\Input\InputOption, + Symfony\Component\Console\Command\Command, + Symfony\Component\Console\Input\InputInterface, + Symfony\Component\Console\Output\OutputInterface; +use Doctrine\DBAL\Platforms\Keywords\ReservedKeywordsValidator; + +class ReservedWordsCommand extends Command +{ + private $keywordListClasses = array( + 'mysql' => 'Doctrine\DBAL\Platforms\Keywords\MySQLKeywords', + 'mssql' => 'Doctrine\DBAL\Platforms\Keywords\MsSQLKeywords', + 'sqlite' => 'Doctrine\DBAL\Platforms\Keywords\SQLiteKeywords', + 'pgsql' => 'Doctrine\DBAL\Platforms\Keywords\PostgreSQLKeywords', + 'oracle' => 'Doctrine\DBAL\Platforms\Keywords\OracleKeywords', + 'db2' => 'Doctrine\DBAL\Platforms\Keywords\DB2Keywords', + ); + + /** + * If you want to add or replace a keywords list use this command + * + * @param string $name + * @param string $class + */ + public function setKeywordListClass($name, $class) + { + $this->keywordListClasses[$name] = $class; + } + + /** + * @see Console\Command\Command + */ + protected function configure() + { + $this + ->setName('dbal:reserved-words') + ->setDescription('Checks if the current database contains identifiers that are reserved.') + ->setDefinition(array( + new InputOption( + 'list', 'l', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Keyword-List name.' + ) + )) + ->setHelp(<<doctrine dbal:reserved-words + +If you want to check against specific dialects you can +pass them to the command: + + doctrine dbal:reserved-words mysql pgsql + +The following keyword lists are currently shipped with Doctrine: + + * mysql + * pgsql + * sqlite + * oracle + * mssql + * db2 (Not checked by default) +EOT + ); + } + + /** + * @see Console\Command\Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + /* @var $conn Doctrine\DBAL\Connection */ + $conn = $this->getHelper('db')->getConnection(); + + $keywordLists = (array)$input->getOption('list'); + if (!$keywordLists) { + $keywordLists = array('mysql', 'pgsql', 'sqlite', 'oracle', 'mssql'); + } + + $keywords = array(); + foreach ($keywordLists AS $keywordList) { + if (!isset($this->keywordListClasses[$keywordList])) { + throw new \InvalidArgumentException( + "There exists no keyword list with name '" . $keywordList . "'. ". + "Known lists: " . implode(", ", array_keys($this->keywordListClasses)) + ); + } + $class = $this->keywordListClasses[$keywordList]; + $keywords[] = new $class; + } + + $output->write('Checking keyword violations for ' . implode(", ", $keywordLists) . "...", true); + + /* @var $schema \Doctrine\DBAL\Schema\Schema */ + $schema = $conn->getSchemaManager()->createSchema(); + $visitor = new ReservedKeywordsValidator($keywords); + $schema->visit($visitor); + + $violations = $visitor->getViolations(); + if (count($violations) == 0) { + $output->write("No reserved keywords violations have been found!", true); + } else { + $output->write('There are ' . count($violations) . ' reserved keyword violations in your database schema:', true); + foreach ($violations AS $violation) { + $output->write(' - ' . $violation, true); + } + } + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/RunSqlCommand.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/RunSqlCommand.php new file mode 100644 index 0000000..856c1a2 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/RunSqlCommand.php @@ -0,0 +1,87 @@ +. + */ + +namespace Doctrine\DBAL\Tools\Console\Command; + +use Symfony\Component\Console\Input\InputArgument, + Symfony\Component\Console\Input\InputOption, + Symfony\Component\Console; + +/** + * Task for executing arbitrary SQL that can come from a file or directly from + * the command line. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class RunSqlCommand extends Console\Command\Command +{ + /** + * @see Console\Command\Command + */ + protected function configure() + { + $this + ->setName('dbal:run-sql') + ->setDescription('Executes arbitrary SQL directly from the command line.') + ->setDefinition(array( + new InputArgument('sql', InputArgument::REQUIRED, 'The SQL statement to execute.'), + new InputOption('depth', null, InputOption::VALUE_REQUIRED, 'Dumping depth of result set.', 7) + )) + ->setHelp(<<getHelper('db')->getConnection(); + + if (($sql = $input->getArgument('sql')) === null) { + throw new \RuntimeException("Argument 'SQL' is required in order to execute this command correctly."); + } + + $depth = $input->getOption('depth'); + + if ( ! is_numeric($depth)) { + throw new \LogicException("Option 'depth' must contains an integer value"); + } + + if (preg_match('/^select/i', $sql)) { + $resultSet = $conn->fetchAll($sql); + } else { + $resultSet = $conn->executeUpdate($sql); + } + + ob_start(); + \Doctrine\Common\Util\Debug::dump($resultSet, (int) $depth); + $message = ob_get_clean(); + + $output->write($message); + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Helper/ConnectionHelper.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Helper/ConnectionHelper.php new file mode 100644 index 0000000..4437d46 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Helper/ConnectionHelper.php @@ -0,0 +1,74 @@ +. + */ + +namespace Doctrine\DBAL\Tools\Console\Helper; + +use Symfony\Component\Console\Helper\Helper, + Doctrine\DBAL\Connection; + +/** + * Doctrine CLI Connection Helper. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class ConnectionHelper extends Helper +{ + /** + * Doctrine Database Connection + * @var Connection + */ + protected $_connection; + + /** + * Constructor + * + * @param Connection $connection Doctrine Database Connection + */ + public function __construct(Connection $connection) + { + $this->_connection = $connection; + } + + /** + * Retrieves Doctrine Database Connection + * + * @return Connection + */ + public function getConnection() + { + return $this->_connection; + } + + /** + * @see Helper + */ + public function getName() + { + return 'connection'; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ArrayType.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ArrayType.php new file mode 100644 index 0000000..237070e --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ArrayType.php @@ -0,0 +1,57 @@ +. + */ + +namespace Doctrine\DBAL\Types; + +/** + * Type that maps a PHP array to a clob SQL type. + * + * @since 2.0 + */ +class ArrayType extends Type +{ + public function getSQLDeclaration(array $fieldDeclaration, \Doctrine\DBAL\Platforms\AbstractPlatform $platform) + { + return $platform->getClobTypeDeclarationSQL($fieldDeclaration); + } + + public function convertToDatabaseValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform) + { + return serialize($value); + } + + public function convertToPHPValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform) + { + if ($value === null) { + return null; + } + + $value = (is_resource($value)) ? stream_get_contents($value) : $value; + $val = unserialize($value); + if ($val === false && $value != 'b:0;') { + throw ConversionException::conversionFailed($value, $this->getName()); + } + return $val; + } + + public function getName() + { + return Type::TARRAY; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BigIntType.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BigIntType.php new file mode 100644 index 0000000..6c3f4b0 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BigIntType.php @@ -0,0 +1,48 @@ +. + */ + +namespace Doctrine\DBAL\Types; + +use Doctrine\DBAL\Platforms\AbstractPlatform; + +/** + * Type that maps a database BIGINT to a PHP string. + * + * @author robo + * @since 2.0 + */ +class BigIntType extends Type +{ + public function getName() + { + return Type::BIGINT; + } + + public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + { + return $platform->getBigIntTypeDeclarationSQL($fieldDeclaration); + } + + public function getBindingType() + { + return \PDO::PARAM_STR; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BlobType.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BlobType.php new file mode 100644 index 0000000..5be8c30 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BlobType.php @@ -0,0 +1,67 @@ +. + */ + +namespace Doctrine\DBAL\Types; + +use Doctrine\DBAL\Platforms\AbstractPlatform; + +/** + * Type that maps an SQL BLOB to a PHP resource stream + * + * @since 2.2 + */ +class BlobType extends Type +{ + /** @override */ + public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + { + return $platform->getBlobTypeDeclarationSQL($fieldDeclaration); + } + + /** + * Converts a value from its database representation to its PHP representation + * of this type. + * + * @param mixed $value The value to convert. + * @param AbstractPlatform $platform The currently used database platform. + * @return mixed The PHP representation of the value. + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if (null === $value) { + return null; + } + if (is_string($value)) { + $value = fopen('data://text/plain;base64,' . base64_encode($value), 'r'); + } else if ( ! is_resource($value)) { + throw ConversionException::conversionFailed($value, self::BLOB); + } + return $value; + } + + public function getName() + { + return Type::BLOB; + } + + public function getBindingType() + { + return \PDO::PARAM_LOB; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BooleanType.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BooleanType.php new file mode 100644 index 0000000..e3cb9a1 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BooleanType.php @@ -0,0 +1,57 @@ +. + */ + +namespace Doctrine\DBAL\Types; + +use Doctrine\DBAL\Platforms\AbstractPlatform; + +/** + * Type that maps an SQL boolean to a PHP boolean. + * + * @since 2.0 + */ +class BooleanType extends Type +{ + public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + { + return $platform->getBooleanTypeDeclarationSQL($fieldDeclaration); + } + + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + return $platform->convertBooleans($value); + } + + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return (null === $value) ? null : (bool) $value; + } + + public function getName() + { + return Type::BOOLEAN; + } + + public function getBindingType() + { + return \PDO::PARAM_BOOL; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ConversionException.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ConversionException.php new file mode 100644 index 0000000..ef3270f --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ConversionException.php @@ -0,0 +1,65 @@ +. + */ + + +/** + * Conversion Exception is thrown when the database to PHP conversion fails + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +namespace Doctrine\DBAL\Types; + +class ConversionException extends \Doctrine\DBAL\DBALException +{ + /** + * Thrown when a Database to Doctrine Type Conversion fails. + * + * @param string $value + * @param string $toType + * @return ConversionException + */ + static public function conversionFailed($value, $toType) + { + $value = (strlen($value) > 32) ? substr($value, 0, 20) . "..." : $value; + return new self('Could not convert database value "' . $value . '" to Doctrine Type ' . $toType); + } + + /** + * Thrown when a Database to Doctrine Type Conversion fails and we can make a statement + * about the expected format. + * + * @param string $value + * @param string $toType + * @return ConversionException + */ + static public function conversionFailedFormat($value, $toType, $expectedFormat) + { + $value = (strlen($value) > 32) ? substr($value, 0, 20) . "..." : $value; + return new self( + 'Could not convert database value "' . $value . '" to Doctrine Type ' . + $toType . '. Expected format: ' . $expectedFormat + ); + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeType.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeType.php new file mode 100644 index 0000000..d073173 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeType.php @@ -0,0 +1,59 @@ +. + */ + +namespace Doctrine\DBAL\Types; + +use Doctrine\DBAL\Platforms\AbstractPlatform; + +/** + * Type that maps an SQL DATETIME/TIMESTAMP to a PHP DateTime object. + * + * @since 2.0 + */ +class DateTimeType extends Type +{ + public function getName() + { + return Type::DATETIME; + } + + public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + { + return $platform->getDateTimeTypeDeclarationSQL($fieldDeclaration); + } + + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + return ($value !== null) + ? $value->format($platform->getDateTimeFormatString()) : null; + } + + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return null; + } + + $val = \DateTime::createFromFormat($platform->getDateTimeFormatString(), $value); + if (!$val) { + throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getDateTimeFormatString()); + } + return $val; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeTzType.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeTzType.php new file mode 100644 index 0000000..4dc6058 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeTzType.php @@ -0,0 +1,79 @@ +. + */ + + +namespace Doctrine\DBAL\Types; + +use Doctrine\DBAL\Platforms\AbstractPlatform; + +/** + * DateTime type saving additional timezone information. + * + * Caution: Databases are not necessarily experts at storing timezone related + * data of dates. First, of all the supported vendors only PostgreSQL and Oracle + * support storing Timezone data. But those two don't save the actual timezone + * attached to a DateTime instance (for example "Europe/Berlin" or "America/Montreal") + * but the current offset of them related to UTC. That means depending on daylight saving times + * or not you may get different offsets. + * + * This datatype makes only sense to use, if your application works with an offset, not + * with an actual timezone that uses transitions. Otherwise your DateTime instance + * attached with a timezone such as Europe/Berlin gets saved into the database with + * the offset and re-created from persistence with only the offset, not the original timezone + * attached. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 1.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class DateTimeTzType extends Type +{ + public function getName() + { + return Type::DATETIMETZ; + } + + public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + { + return $platform->getDateTimeTzTypeDeclarationSQL($fieldDeclaration); + } + + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + return ($value !== null) + ? $value->format($platform->getDateTimeTzFormatString()) : null; + } + + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return null; + } + + $val = \DateTime::createFromFormat($platform->getDateTimeTzFormatString(), $value); + if (!$val) { + throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getDateTimeTzFormatString()); + } + return $val; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateType.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateType.php new file mode 100644 index 0000000..42c4803 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateType.php @@ -0,0 +1,59 @@ +. + */ + +namespace Doctrine\DBAL\Types; + +use Doctrine\DBAL\Platforms\AbstractPlatform; + +/** + * Type that maps an SQL DATE to a PHP Date object. + * + * @since 2.0 + */ +class DateType extends Type +{ + public function getName() + { + return Type::DATE; + } + + public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + { + return $platform->getDateTypeDeclarationSQL($fieldDeclaration); + } + + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + return ($value !== null) + ? $value->format($platform->getDateFormatString()) : null; + } + + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return null; + } + + $val = \DateTime::createFromFormat('!'.$platform->getDateFormatString(), $value); + if (!$val) { + throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getDateFormatString()); + } + return $val; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DecimalType.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DecimalType.php new file mode 100644 index 0000000..1308c96 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DecimalType.php @@ -0,0 +1,45 @@ +. + */ + +namespace Doctrine\DBAL\Types; + +use Doctrine\DBAL\Platforms\AbstractPlatform; + +/** + * Type that maps an SQL DECIMAL to a PHP double. + * + * @since 2.0 + */ +class DecimalType extends Type +{ + public function getName() + { + return Type::DECIMAL; + } + + public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + { + return $platform->getDecimalTypeDeclarationSQL($fieldDeclaration); + } + + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return (null === $value) ? null : $value; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/FloatType.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/FloatType.php new file mode 100644 index 0000000..c8f7914 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/FloatType.php @@ -0,0 +1,54 @@ +. + */ + + +namespace Doctrine\DBAL\Types; + +use Doctrine\DBAL\Platforms\AbstractPlatform; + +class FloatType extends Type +{ + public function getName() + { + return Type::FLOAT; + } + + /** + * @param array $fieldDeclaration + * @param AbstractPlatform $platform + * @return string + */ + public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + { + return $platform->getFloatDeclarationSQL($fieldDeclaration); + } + + /** + * Converts a value from its database representation to its PHP representation + * of this type. + * + * @param mixed $value The value to convert. + * @param AbstractPlatform $platform The currently used database platform. + * @return mixed The PHP representation of the value. + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return (null === $value) ? null : (double) $value; + } +} diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/IntegerType.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/IntegerType.php new file mode 100644 index 0000000..dd13f0a --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/IntegerType.php @@ -0,0 +1,53 @@ +. + */ + +namespace Doctrine\DBAL\Types; + +use Doctrine\DBAL\Platforms\AbstractPlatform; + +/** + * Type that maps an SQL INT to a PHP integer. + * + * @author Roman Borschel + * @since 2.0 + */ +class IntegerType extends Type +{ + public function getName() + { + return Type::INTEGER; + } + + public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + { + return $platform->getIntegerTypeDeclarationSQL($fieldDeclaration); + } + + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return (null === $value) ? null : (int) $value; + } + + public function getBindingType() + { + return \PDO::PARAM_INT; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ObjectType.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ObjectType.php new file mode 100644 index 0000000..977c3b3 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ObjectType.php @@ -0,0 +1,57 @@ +. + */ + +namespace Doctrine\DBAL\Types; + +/** + * Type that maps a PHP object to a clob SQL type. + * + * @since 2.0 + */ +class ObjectType extends Type +{ + public function getSQLDeclaration(array $fieldDeclaration, \Doctrine\DBAL\Platforms\AbstractPlatform $platform) + { + return $platform->getClobTypeDeclarationSQL($fieldDeclaration); + } + + public function convertToDatabaseValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform) + { + return serialize($value); + } + + public function convertToPHPValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform) + { + if ($value === null) { + return null; + } + + $value = (is_resource($value)) ? stream_get_contents($value) : $value; + $val = unserialize($value); + if ($val === false && $value !== 'b:0;') { + throw ConversionException::conversionFailed($value, $this->getName()); + } + return $val; + } + + public function getName() + { + return Type::OBJECT; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/SmallIntType.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/SmallIntType.php new file mode 100644 index 0000000..5e1df69 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/SmallIntType.php @@ -0,0 +1,52 @@ +. + */ + +namespace Doctrine\DBAL\Types; + +use Doctrine\DBAL\Platforms\AbstractPlatform; + +/** + * Type that maps a database SMALLINT to a PHP integer. + * + * @author robo + */ +class SmallIntType extends Type +{ + public function getName() + { + return Type::SMALLINT; + } + + public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + { + return $platform->getSmallIntTypeDeclarationSQL($fieldDeclaration); + } + + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return (null === $value) ? null : (int) $value; + } + + public function getBindingType() + { + return \PDO::PARAM_INT; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/StringType.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/StringType.php new file mode 100644 index 0000000..a813eaa --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/StringType.php @@ -0,0 +1,50 @@ +. + */ + +namespace Doctrine\DBAL\Types; + +use Doctrine\DBAL\Platforms\AbstractPlatform; + +/** + * Type that maps an SQL VARCHAR to a PHP string. + * + * @since 2.0 + */ +class StringType extends Type +{ + /** @override */ + public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + { + return $platform->getVarcharTypeDeclarationSQL($fieldDeclaration); + } + + /** @override */ + public function getDefaultLength(AbstractPlatform $platform) + { + return $platform->getVarcharDefaultLength(); + } + + /** @override */ + public function getName() + { + return Type::STRING; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/TextType.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/TextType.php new file mode 100644 index 0000000..50b4f83 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/TextType.php @@ -0,0 +1,56 @@ +. + */ + +namespace Doctrine\DBAL\Types; + +use Doctrine\DBAL\Platforms\AbstractPlatform; + +/** + * Type that maps an SQL CLOB to a PHP string. + * + * @since 2.0 + */ +class TextType extends Type +{ + /** @override */ + public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + { + return $platform->getClobTypeDeclarationSQL($fieldDeclaration); + } + + /** + * Converts a value from its database representation to its PHP representation + * of this type. + * + * @param mixed $value The value to convert. + * @param AbstractPlatform $platform The currently used database platform. + * @return mixed The PHP representation of the value. + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return (is_resource($value)) ? stream_get_contents($value) : $value; + } + + public function getName() + { + return Type::TEXT; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeType.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeType.php new file mode 100644 index 0000000..d4c49c4 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeType.php @@ -0,0 +1,68 @@ +. + */ + +namespace Doctrine\DBAL\Types; + +use Doctrine\DBAL\Platforms\AbstractPlatform; + +/** + * Type that maps an SQL TIME to a PHP DateTime object. + * + * @since 2.0 + */ +class TimeType extends Type +{ + public function getName() + { + return Type::TIME; + } + + /** + * {@inheritdoc} + */ + public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + { + return $platform->getTimeTypeDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + return ($value !== null) + ? $value->format($platform->getTimeFormatString()) : null; + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return null; + } + + $val = \DateTime::createFromFormat($platform->getTimeFormatString(), $value); + if (!$val) { + throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getTimeFormatString()); + } + return $val; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Type.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Type.php new file mode 100644 index 0000000..320dfa9 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Type.php @@ -0,0 +1,274 @@ +. + */ + +namespace Doctrine\DBAL\Types; + +use Doctrine\DBAL\Platforms\AbstractPlatform, + Doctrine\DBAL\DBALException; + +/** + * The base class for so-called Doctrine mapping types. + * + * A Type object is obtained by calling the static {@link getType()} method. + * + * @author Roman Borschel + * @author Benjamin Eberlei + * @since 2.0 + */ +abstract class Type +{ + const TARRAY = 'array'; + const BIGINT = 'bigint'; + const BOOLEAN = 'boolean'; + const DATETIME = 'datetime'; + const DATETIMETZ = 'datetimetz'; + const DATE = 'date'; + const TIME = 'time'; + const DECIMAL = 'decimal'; + const INTEGER = 'integer'; + const OBJECT = 'object'; + const SMALLINT = 'smallint'; + const STRING = 'string'; + const TEXT = 'text'; + const BLOB = 'blob'; + const FLOAT = 'float'; + + /** Map of already instantiated type objects. One instance per type (flyweight). */ + private static $_typeObjects = array(); + + /** The map of supported doctrine mapping types. */ + private static $_typesMap = array( + self::TARRAY => 'Doctrine\DBAL\Types\ArrayType', + self::OBJECT => 'Doctrine\DBAL\Types\ObjectType', + self::BOOLEAN => 'Doctrine\DBAL\Types\BooleanType', + self::INTEGER => 'Doctrine\DBAL\Types\IntegerType', + self::SMALLINT => 'Doctrine\DBAL\Types\SmallIntType', + self::BIGINT => 'Doctrine\DBAL\Types\BigIntType', + self::STRING => 'Doctrine\DBAL\Types\StringType', + self::TEXT => 'Doctrine\DBAL\Types\TextType', + self::DATETIME => 'Doctrine\DBAL\Types\DateTimeType', + self::DATETIMETZ => 'Doctrine\DBAL\Types\DateTimeTzType', + self::DATE => 'Doctrine\DBAL\Types\DateType', + self::TIME => 'Doctrine\DBAL\Types\TimeType', + self::DECIMAL => 'Doctrine\DBAL\Types\DecimalType', + self::FLOAT => 'Doctrine\DBAL\Types\FloatType', + self::BLOB => 'Doctrine\DBAL\Types\BlobType', + ); + + /* Prevent instantiation and force use of the factory method. */ + final private function __construct() {} + + /** + * Converts a value from its PHP representation to its database representation + * of this type. + * + * @param mixed $value The value to convert. + * @param AbstractPlatform $platform The currently used database platform. + * @return mixed The database representation of the value. + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + return $value; + } + + /** + * Converts a value from its database representation to its PHP representation + * of this type. + * + * @param mixed $value The value to convert. + * @param AbstractPlatform $platform The currently used database platform. + * @return mixed The PHP representation of the value. + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return $value; + } + + /** + * Gets the default length of this type. + * + * @todo Needed? + */ + public function getDefaultLength(AbstractPlatform $platform) + { + return null; + } + + /** + * Gets the SQL declaration snippet for a field of this type. + * + * @param array $fieldDeclaration The field declaration. + * @param AbstractPlatform $platform The currently used database platform. + */ + abstract public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform); + + /** + * Gets the name of this type. + * + * @return string + * @todo Needed? + */ + abstract public function getName(); + + /** + * Factory method to create type instances. + * Type instances are implemented as flyweights. + * + * @static + * @throws DBALException + * @param string $name The name of the type (as returned by getName()). + * @return Doctrine\DBAL\Types\Type + */ + public static function getType($name) + { + if ( ! isset(self::$_typeObjects[$name])) { + if ( ! isset(self::$_typesMap[$name])) { + throw DBALException::unknownColumnType($name); + } + self::$_typeObjects[$name] = new self::$_typesMap[$name](); + } + + return self::$_typeObjects[$name]; + } + + /** + * Adds a custom type to the type map. + * + * @static + * @param string $name Name of the type. This should correspond to what getName() returns. + * @param string $className The class name of the custom type. + * @throws DBALException + */ + public static function addType($name, $className) + { + if (isset(self::$_typesMap[$name])) { + throw DBALException::typeExists($name); + } + + self::$_typesMap[$name] = $className; + } + + /** + * Checks if exists support for a type. + * + * @static + * @param string $name Name of the type + * @return boolean TRUE if type is supported; FALSE otherwise + */ + public static function hasType($name) + { + return isset(self::$_typesMap[$name]); + } + + /** + * Overrides an already defined type to use a different implementation. + * + * @static + * @param string $name + * @param string $className + * @throws DBALException + */ + public static function overrideType($name, $className) + { + if ( ! isset(self::$_typesMap[$name])) { + throw DBALException::typeNotFound($name); + } + + if (isset(self::$_typeObjects[$name])) { + unset(self::$_typeObjects[$name]); + } + + self::$_typesMap[$name] = $className; + } + + /** + * Gets the (preferred) binding type for values of this type that + * can be used when binding parameters to prepared statements. + * + * This method should return one of the PDO::PARAM_* constants, that is, one of: + * + * PDO::PARAM_BOOL + * PDO::PARAM_NULL + * PDO::PARAM_INT + * PDO::PARAM_STR + * PDO::PARAM_LOB + * + * @return integer + */ + public function getBindingType() + { + return \PDO::PARAM_STR; + } + + /** + * Get the types array map which holds all registered types and the corresponding + * type class + * + * @return array $typesMap + */ + public static function getTypesMap() + { + return self::$_typesMap; + } + + public function __toString() + { + $e = explode('\\', get_class($this)); + return str_replace('Type', '', end($e)); + } + + /** + * Does working with this column require SQL conversion functions? + * + * This is a metadata function that is required for example in the ORM. + * Usage of {@link convertToDatabaseValueSQL} and + * {@link convertToPHPValueSQL} works for any type and mostly + * does nothing. This method can additionally be used for optimization purposes. + * + * @return bool + */ + public function canRequireSQLConversion() + { + return false; + } + + /** + * Modifies the SQL expression (identifier, parameter) to convert to a database value. + * + * @param string $sqlExpr + * @param AbstractPlatform $platform + * @return string + */ + public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform) + { + return $sqlExpr; + } + + /** + * Modifies the SQL expression (identifier, parameter) to convert to a PHP value. + * + * @param string $sqlExpr + * @param AbstractPlatform $platform + * @return string + */ + public function convertToPHPValueSQL($sqlExpr, $platform) + { + return $sqlExpr; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/VarDateTimeType.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/VarDateTimeType.php new file mode 100644 index 0000000..03ea048 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/VarDateTimeType.php @@ -0,0 +1,60 @@ +. + */ + + +namespace Doctrine\DBAL\Types; + +use Doctrine\DBAL\Platforms\AbstractPlatform; + +/** + * Variable DateTime Type using date_create() instead of DateTime::createFromFormat() + * + * This type has performance implications as it runs twice as long as the regular + * {@see DateTimeType}, however in certain PostgreSQL configurations with + * TIMESTAMP(n) columns where n > 0 it is necessary to use this type. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class VarDateTimeType extends DateTimeType +{ + /** + * @throws ConversionException + * @param string $value + * @param AbstractPlatform $platform + * @return DateTime + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return null; + } + + $val = date_create($value); + if (!$val) { + throw ConversionException::conversionFailed($value, $this->getName()); + } + return $val; + } +} \ No newline at end of file diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Version.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Version.php new file mode 100644 index 0000000..883b217 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Version.php @@ -0,0 +1,55 @@ +. + */ + +namespace Doctrine\DBAL; + +/** + * Class to store and retrieve the version of Doctrine + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class Version +{ + /** + * Current Doctrine Version + */ + const VERSION = '2.2.3-DEV'; + + /** + * Compares a Doctrine version with the current one. + * + * @param string $version Doctrine version to compare. + * @return int Returns -1 if older, 0 if it is the same, 1 if version + * passed as argument is newer. + */ + public static function compare($version) + { + $currentVersion = str_replace(' ', '', strtolower(self::VERSION)); + $version = str_replace(' ', '', $version); + + return version_compare($version, $currentVersion); + } +} diff --git a/vendor/doctrine/dbal/phpunit.xml.dist b/vendor/doctrine/dbal/phpunit.xml.dist new file mode 100644 index 0000000..fe1d515 --- /dev/null +++ b/vendor/doctrine/dbal/phpunit.xml.dist @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + ./tests/Doctrine/Tests/DBAL + + + \ No newline at end of file diff --git a/vendor/doctrine/dbal/run-all.sh b/vendor/doctrine/dbal/run-all.sh new file mode 100755 index 0000000..80712ee --- /dev/null +++ b/vendor/doctrine/dbal/run-all.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# This script is a small convenience wrapper for running the doctrine testsuite against a large bunch of databases. +# Just create the phpunit.xmls as described in the array below and configure the specific files section +# to connect to that database. Just omit a file if you dont have that database and the tests will be skipped. + +configs[1]="mysql.phpunit.xml" +configs[2]='postgres.phpunit.xml' +configs[3]='sqlite.phpunit.xml' +configs[4]='oracle.phpunit.xml' +configs[5]='db2.phpunit.xml' +configs[6]='pdo-ibm.phpunit.xml' +configs[7]='sqlsrv.phpunit.xml' + +for i in "${configs[@]}"; do + if [ -f "$i" ]; + then + echo "RUNNING TESTS WITH CONFIG $i" + phpunit -c "$i" "$@" + fi; +done diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/.travis.yml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/.travis.yml new file mode 100644 index 0000000..47ab323 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/.travis.yml @@ -0,0 +1,10 @@ +language: php + +php: + - 5.3 + - 5.4 + +before_script: + - wget http://getcomposer.org/composer.phar + - php composer.phar install --dev + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/CreateDatabaseDoctrineCommand.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/CreateDatabaseDoctrineCommand.php new file mode 100644 index 0000000..c9bb508 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/CreateDatabaseDoctrineCommand.php @@ -0,0 +1,76 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Command; + +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Doctrine\DBAL\DriverManager; + +/** + * Database tool allows you to easily drop and create your configured databases. + * + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class CreateDatabaseDoctrineCommand extends DoctrineCommand +{ + protected function configure() + { + $this + ->setName('doctrine:database:create') + ->setDescription('Creates the configured databases') + ->addOption('connection', null, InputOption::VALUE_OPTIONAL, 'The connection to use for this command') + ->setHelp(<<doctrine:database:create command creates the default +connections database: + +php app/console doctrine:database:create + +You can also optionally specify the name of a connection to create the +database for: + +php app/console doctrine:database:create --connection=default +EOT + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $connection = $this->getDoctrineConnection($input->getOption('connection')); + + $params = $connection->getParams(); + $name = isset($params['path']) ? $params['path'] : $params['dbname']; + + unset($params['dbname']); + + $tmpConnection = DriverManager::getConnection($params); + + // Only quote if we don't have a path + if (!isset($params['path'])) { + $name = $tmpConnection->getDatabasePlatform()->quoteSingleIdentifier($name); + } + + try { + $tmpConnection->getSchemaManager()->createDatabase($name); + $output->writeln(sprintf('Created database for connection named %s', $name)); + } catch (\Exception $e) { + $output->writeln(sprintf('Could not create database for connection named %s', $name)); + $output->writeln(sprintf('%s', $e->getMessage())); + } + + $tmpConnection->close(); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/DoctrineCommand.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/DoctrineCommand.php new file mode 100644 index 0000000..f5d3f0e --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/DoctrineCommand.php @@ -0,0 +1,55 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Command; + +use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; +use Doctrine\ORM\Tools\EntityGenerator; + +/** + * Base class for Doctrine console commands to extend from. + * + * @author Fabien Potencier + */ +abstract class DoctrineCommand extends ContainerAwareCommand +{ + protected function getEntityGenerator() + { + $entityGenerator = new EntityGenerator(); + $entityGenerator->setGenerateAnnotations(false); + $entityGenerator->setGenerateStubMethods(true); + $entityGenerator->setRegenerateEntityIfExists(false); + $entityGenerator->setUpdateEntityIfExists(true); + $entityGenerator->setNumSpaces(4); + $entityGenerator->setAnnotationPrefix('ORM\\'); + + return $entityGenerator; + } + + protected function getEntityManager($name) + { + return $this->getContainer()->get('doctrine')->getManager($name); + } + + /** + * Get a doctrine dbal connection by symfony name. + * + * @param string $name + * @return Doctrine\DBAL\Connection + */ + protected function getDoctrineConnection($name) + { + return $this->getContainer()->get('doctrine')->getConnection($name); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/DropDatabaseDoctrineCommand.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/DropDatabaseDoctrineCommand.php new file mode 100644 index 0000000..d0f0e39 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/DropDatabaseDoctrineCommand.php @@ -0,0 +1,88 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Command; + +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Database tool allows you to easily drop and create your configured databases. + * + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class DropDatabaseDoctrineCommand extends DoctrineCommand +{ + protected function configure() + { + $this + ->setName('doctrine:database:drop') + ->setDescription('Drops the configured databases') + ->addOption('connection', null, InputOption::VALUE_OPTIONAL, 'The connection to use for this command') + ->addOption('force', null, InputOption::VALUE_NONE, 'Set this parameter to execute this action') + ->setHelp(<<doctrine:database:drop command drops the default connections +database: + +php app/console doctrine:database:drop + +The --force parameter has to be used to actually drop the database. + +You can also optionally specify the name of a connection to drop the database +for: + +php app/console doctrine:database:drop --connection=default + +Be careful: All data in a given database will be lost when executing +this command. +EOT + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $connection = $this->getDoctrineConnection($input->getOption('connection')); + + $params = $connection->getParams(); + + $name = isset($params['path']) ? $params['path'] : (isset($params['dbname']) ? $params['dbname'] : false); + + if (!$name) { + throw new \InvalidArgumentException("Connection does not contain a 'path' or 'dbname' parameter and cannot be dropped."); + } + + if ($input->getOption('force')) { + // Only quote if we don't have a path + if (!isset($params['path'])) { + $name = $connection->getDatabasePlatform()->quoteSingleIdentifier($name); + } + + try { + $connection->getSchemaManager()->dropDatabase($name); + $output->writeln(sprintf('Dropped database for connection named %s', $name)); + } catch (\Exception $e) { + $output->writeln(sprintf('Could not drop database for connection named %s', $name)); + $output->writeln(sprintf('%s', $e->getMessage())); + } + } else { + $output->writeln('ATTENTION: This operation should not be executed in a production environment.'); + $output->writeln(''); + $output->writeln(sprintf('Would drop the database named %s.', $name)); + $output->writeln('Please run the operation with --force to execute'); + $output->writeln('All data will be lost!'); + } + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/GenerateEntitiesDoctrineCommand.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/GenerateEntitiesDoctrineCommand.php new file mode 100644 index 0000000..4cbc64b --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/GenerateEntitiesDoctrineCommand.php @@ -0,0 +1,134 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Command; + +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 Doctrine\ORM\Tools\EntityRepositoryGenerator; +use Doctrine\Bundle\DoctrineBundle\Mapping\DisconnectedMetadataFactory; + +/** + * Generate entity classes from mapping information + * + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class GenerateEntitiesDoctrineCommand extends DoctrineCommand +{ + protected function configure() + { + $this + ->setName('doctrine:generate:entities') + ->setAliases(array('generate:doctrine:entities')) + ->setDescription('Generates entity classes and method stubs from your mapping information') + ->addArgument('name', InputArgument::REQUIRED, 'A bundle name, a namespace, or a class name') + ->addOption('path', null, InputOption::VALUE_REQUIRED, 'The path where to generate entities when it cannot be guessed') + ->addOption('no-backup', null, InputOption::VALUE_NONE, 'Do not backup existing entities files.') + ->setHelp(<<doctrine:generate:entities command generates entity classes +and method stubs from your mapping information: + +You have to limit generation of entities: + +* To a bundle: + + php app/console doctrine:generate:entities MyCustomBundle + +* To a single entity: + + php app/console doctrine:generate:entities MyCustomBundle:User + php app/console doctrine:generate:entities MyCustomBundle/Entity/User + +* To a namespace + + php app/console doctrine:generate:entities MyCustomBundle/Entity + +If the entities are not stored in a bundle, and if the classes do not exist, +the command has no way to guess where they should be generated. In this case, +you must provide the --path option: + + php app/console doctrine:generate:entities Blog/Entity --path=src/ + +By default, the unmodified version of each entity is backed up and saved +(e.g. Product.php~). To prevent this task from creating the backup file, +pass the --no-backup option: + + php app/console doctrine:generate:entities Blog/Entity --no-backup + +Important: Even if you specified Inheritance options in your +XML or YAML Mapping files the generator cannot generate the base and +child classes for you correctly, because it doesn't know which +class is supposed to extend which. You have to adjust the entity +code manually for inheritance to work! + +EOT + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $manager = new DisconnectedMetadataFactory($this->getContainer()->get('doctrine')); + + try { + $bundle = $this->getApplication()->getKernel()->getBundle($input->getArgument('name')); + + $output->writeln(sprintf('Generating entities for bundle "%s"', $bundle->getName())); + $metadata = $manager->getBundleMetadata($bundle); + } catch (\InvalidArgumentException $e) { + $name = strtr($input->getArgument('name'), '/', '\\'); + + if (false !== $pos = strpos($name, ':')) { + $name = $this->getContainer()->get('doctrine')->getEntityNamespace(substr($name, 0, $pos)).'\\'.substr($name, $pos + 1); + } + + if (class_exists($name)) { + $output->writeln(sprintf('Generating entity "%s"', $name)); + $metadata = $manager->getClassMetadata($name, $input->getOption('path')); + } else { + $output->writeln(sprintf('Generating entities for namespace "%s"', $name)); + $metadata = $manager->getNamespaceMetadata($name, $input->getOption('path')); + } + } + + $generator = $this->getEntityGenerator(); + + $backupExisting = !$input->getOption('no-backup'); + $generator->setBackupExisting($backupExisting); + + $repoGenerator = new EntityRepositoryGenerator(); + foreach ($metadata->getMetadata() as $m) { + if ($backupExisting) { + $basename = substr($m->name, strrpos($m->name, '\\') + 1); + $output->writeln(sprintf(' > backing up %s.php to %s.php~', $basename, $basename)); + } + // Getting the metadata for the entity class once more to get the correct path if the namespace has multiple occurrences + try { + $entityMetadata = $manager->getClassMetadata($m->getName(), $input->getOption('path')); + } catch (\RuntimeException $e) { + // fall back to the bundle metadata when no entity class could be found + $entityMetadata = $metadata; + } + + $output->writeln(sprintf(' > generating %s', $m->name)); + $generator->generate(array($m), $entityMetadata->getPath()); + + if ($m->customRepositoryClassName && false !== strpos($m->customRepositoryClassName, $metadata->getNamespace())) { + $repoGenerator->writeEntityRepositoryClass($m->customRepositoryClassName, $metadata->getPath()); + } + } + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/ImportMappingDoctrineCommand.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/ImportMappingDoctrineCommand.php new file mode 100644 index 0000000..38d664f --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/ImportMappingDoctrineCommand.php @@ -0,0 +1,126 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Command; + +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 Doctrine\ORM\Mapping\Driver\DatabaseDriver; +use Doctrine\ORM\Tools\DisconnectedClassMetadataFactory; +use Doctrine\ORM\Tools\Export\ClassMetadataExporter; +use Doctrine\ORM\Tools\Console\MetadataFilter; + +/** + * Import Doctrine ORM metadata mapping information from an existing database. + * + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class ImportMappingDoctrineCommand extends DoctrineCommand +{ + protected function configure() + { + $this + ->setName('doctrine:mapping:import') + ->addArgument('bundle', InputArgument::REQUIRED, 'The bundle to import the mapping information to') + ->addArgument('mapping-type', InputArgument::OPTIONAL, 'The mapping type to export the imported mapping information to') + ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command') + ->addOption('filter', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'A string pattern used to match entities that should be mapped.') + ->addOption('force', null, InputOption::VALUE_NONE, 'Force to overwrite existing mapping files.') + ->setDescription('Imports mapping information from an existing database') + ->setHelp(<<doctrine:mapping:import command imports mapping information +from an existing database: + +php app/console doctrine:mapping:import "MyCustomBundle" xml + +You can also optionally specify which entity manager to import from with the +--em option: + +php app/console doctrine:mapping:import "MyCustomBundle" xml --em=default + +If you don't want to map every entity that can be found in the database, use the +--filter option. It will try to match the targeted mapped entity with the +provided pattern string. + +php app/console doctrine:mapping:import "MyCustomBundle" xml --filter=MyMatchedEntity + +Use the --force option, if you want to override existing mapping files: + +php app/console doctrine:mapping:import "MyCustomBundle" xml --force +EOT + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $bundle = $this->getApplication()->getKernel()->getBundle($input->getArgument('bundle')); + + $destPath = $bundle->getPath(); + $type = $input->getArgument('mapping-type') ? $input->getArgument('mapping-type') : 'xml'; + if ('annotation' === $type) { + $destPath .= '/Entity'; + } else { + $destPath .= '/Resources/config/doctrine'; + } + if ('yaml' === $type) { + $type = 'yml'; + } + + $cme = new ClassMetadataExporter(); + $exporter = $cme->getExporter($type); + $exporter->setOverwriteExistingFiles($input->getOption('force')); + + if ('annotation' === $type) { + $entityGenerator = $this->getEntityGenerator(); + $exporter->setEntityGenerator($entityGenerator); + } + + $em = $this->getEntityManager($input->getOption('em')); + + $databaseDriver = new DatabaseDriver($em->getConnection()->getSchemaManager()); + $em->getConfiguration()->setMetadataDriverImpl($databaseDriver); + + $emName = $input->getOption('em'); + $emName = $emName ? $emName : 'default'; + + $cmf = new DisconnectedClassMetadataFactory(); + $cmf->setEntityManager($em); + $metadata = $cmf->getAllMetadata(); + $metadata = MetadataFilter::filter($metadata, $input->getOption('filter')); + if ($metadata) { + $output->writeln(sprintf('Importing mapping information from "%s" entity manager', $emName)); + foreach ($metadata as $class) { + $className = $class->name; + $class->name = $bundle->getNamespace().'\\Entity\\'.$className; + if ('annotation' === $type) { + $path = $destPath.'/'.$className.'.php'; + } else { + $path = $destPath.'/'.$className.'.orm.'.$type; + } + $output->writeln(sprintf(' > writing %s', $path)); + $code = $exporter->exportClassMetadata($class); + if (!is_dir($dir = dirname($path))) { + mkdir($dir, 0777, true); + } + file_put_contents($path, $code); + } + } else { + $output->writeln('Database does not have any mapping information.', 'ERROR'); + $output->writeln('', 'ERROR'); + } + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/ClearMetadataCacheDoctrineCommand.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/ClearMetadataCacheDoctrineCommand.php new file mode 100644 index 0000000..4764d14 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/ClearMetadataCacheDoctrineCommand.php @@ -0,0 +1,58 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; + +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand; + +/** + * Command to clear the metadata cache of the various cache drivers. + * + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class ClearMetadataCacheDoctrineCommand extends MetadataCommand +{ + protected function configure() + { + parent::configure(); + + $this + ->setName('doctrine:cache:clear-metadata') + ->setDescription('Clears all metadata cache for a entity manager') + ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command') + ->setHelp(<<doctrine:cache:clear-metadata command clears all metadata +cache for the default entity manager: + +php app/console doctrine:cache:clear-metadata + +You can also optionally specify the --em option to specify +which entity manager to clear the cache for: + +php app/console doctrine:cache:clear-metadata --em=default +EOT + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); + + return parent::execute($input, $output); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/ClearQueryCacheDoctrineCommand.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/ClearQueryCacheDoctrineCommand.php new file mode 100644 index 0000000..e45cef4 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/ClearQueryCacheDoctrineCommand.php @@ -0,0 +1,58 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; + +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand; + +/** + * Command to clear the query cache of the various cache drivers. + * + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class ClearQueryCacheDoctrineCommand extends QueryCommand +{ + protected function configure() + { + parent::configure(); + + $this + ->setName('doctrine:cache:clear-query') + ->setDescription('Clears all query cache for a entity manager') + ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command') + ->setHelp(<<doctrine:cache:clear-query command clears all query cache for +the default entity manager: + +php app/console doctrine:cache:clear-query + +You can also optionally specify the --em option to specify +which entity manager to clear the cache for: + +php app/console doctrine:cache:clear-query --em=default +EOT + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); + + return parent::execute($input, $output); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/ClearResultCacheDoctrineCommand.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/ClearResultCacheDoctrineCommand.php new file mode 100644 index 0000000..08c6e44 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/ClearResultCacheDoctrineCommand.php @@ -0,0 +1,73 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; + +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand; + +/** + * Command to clear the result cache of the various cache drivers. + * + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class ClearResultCacheDoctrineCommand extends ResultCommand +{ + protected function configure() + { + parent::configure(); + + $this + ->setName('doctrine:cache:clear-result') + ->setDescription('Clears result cache for a entity manager') + ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command') + ->setHelp(<<doctrine:cache:clear-result command clears all result cache +for the default entity manager: + +php app/console doctrine:cache:clear-result + +You can also optionally specify the --em option to specify +which entity manager to clear the cache for: + +php app/console doctrine:cache:clear-result --em=default + +If you don't want to clear all result cache you can specify some additional +options to control what cache is deleted: + +php app/console doctrine:cache:clear-result --id=cache_key + +Or you can specify a --regex to delete cache entries that +match it: + +php app/console doctrine:cache:clear-result --regex="user_(.*)" + +You can also specify a --prefix or +--suffix to delete cache entries for: + +php app/console doctrine:cache:clear-result --prefix="user_" --suffix="_frontend" +EOT + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); + + return parent::execute($input, $output); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/ConvertMappingDoctrineCommand.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/ConvertMappingDoctrineCommand.php new file mode 100644 index 0000000..796c091 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/ConvertMappingDoctrineCommand.php @@ -0,0 +1,68 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; + +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Output\Output; +use Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand; +use Doctrine\ORM\Tools\Export\Driver\XmlExporter; +use Doctrine\ORM\Tools\Export\Driver\YamlExporter; + +/** + * Convert Doctrine ORM metadata mapping information between the various supported + * formats. + * + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class ConvertMappingDoctrineCommand extends ConvertMappingCommand +{ + protected function configure() + { + parent::configure(); + $this + ->setName('doctrine:mapping:convert') + ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command') + ->setHelp(<<doctrine:mapping:convert command converts mapping information +between supported formats: + +php app/console doctrine:mapping:convert xml /path/to/output +EOT + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); + + return parent::execute($input, $output); + } + + + protected function getExporter($toType, $destPath) + { + $exporter = parent::getExporter($toType, $destPath); + if ($exporter instanceof XmlExporter) { + $exporter->setExtension('.orm.xml'); + } elseif ($exporter instanceof YamlExporter) { + $exporter->setExtension('.orm.yml'); + } + + return $exporter; + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/CreateSchemaDoctrineCommand.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/CreateSchemaDoctrineCommand.php new file mode 100644 index 0000000..f2ccf91 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/CreateSchemaDoctrineCommand.php @@ -0,0 +1,63 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; + +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Output\Output; +use Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand; + +/** + * Command to execute the SQL needed to generate the database schema for + * a given entity manager. + * + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class CreateSchemaDoctrineCommand extends CreateCommand +{ + protected function configure() + { + parent::configure(); + + $this + ->setName('doctrine:schema:create') + ->setDescription('Executes (or dumps) the SQL needed to generate the database schema') + ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command') + ->setHelp(<<doctrine:schema:create command executes the SQL needed to +generate the database schema for the default entity manager: + +php app/console doctrine:schema:create + +You can also generate the database schema for a specific entity manager: + +php app/console doctrine:schema:create --em=default + +Finally, instead of executing the SQL, you can output the SQL: + +php app/console doctrine:schema:create --dump-sql +EOT + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); + + parent::execute($input, $output); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/DoctrineCommandHelper.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/DoctrineCommandHelper.php new file mode 100644 index 0000000..2a440bf --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/DoctrineCommandHelper.php @@ -0,0 +1,48 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; + +use Symfony\Component\Console\Application; +use Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper; +use Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper; + +/** + * Provides some helper and convenience methods to configure doctrine commands in the context of bundles + * and multiple connections/entity managers. + * + * @author Fabien Potencier + */ +abstract class DoctrineCommandHelper +{ + /** + * Convenience method to push the helper sets of a given entity manager into the application. + * + * @param Application $application + * @param string $emName + */ + static public function setApplicationEntityManager(Application $application, $emName) + { + $em = $application->getKernel()->getContainer()->get('doctrine')->getManager($emName); + $helperSet = $application->getHelperSet(); + $helperSet->set(new ConnectionHelper($em->getConnection()), 'db'); + $helperSet->set(new EntityManagerHelper($em), 'em'); + } + + static public function setApplicationConnection(Application $application, $connName) + { + $connection = $application->getKernel()->getContainer()->get('doctrine')->getConnection($connName); + $helperSet = $application->getHelperSet(); + $helperSet->set(new ConnectionHelper($connection), 'db'); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/DropSchemaDoctrineCommand.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/DropSchemaDoctrineCommand.php new file mode 100644 index 0000000..9746f28 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/DropSchemaDoctrineCommand.php @@ -0,0 +1,63 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; + +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Output\Output; +use Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand; + +/** + * Command to drop the database schema for a set of classes based on their mappings. + * + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class DropSchemaDoctrineCommand extends DropCommand +{ + protected function configure() + { + parent::configure(); + + $this + ->setName('doctrine:schema:drop') + ->setDescription('Executes (or dumps) the SQL needed to drop the current database schema') + ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command') + ->setHelp(<<doctrine:schema:drop command generates the SQL needed to +drop the database schema of the default entity manager: + +php app/console doctrine:schema:drop --dump-sql + +Alternatively, you can execute the generated queries: + +php app/console doctrine:schema:drop --force + +You can also optionally specify the name of a entity manager to drop the +schema for: + +php app/console doctrine:schema:drop --em=default +EOT + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); + + parent::execute($input, $output); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/EnsureProductionSettingsDoctrineCommand.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/EnsureProductionSettingsDoctrineCommand.php new file mode 100644 index 0000000..c2a8024 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/EnsureProductionSettingsDoctrineCommand.php @@ -0,0 +1,58 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; + +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Output\Output; +use Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand; + +/** + * Ensure the Doctrine ORM is configured properly for a production environment. + * + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class EnsureProductionSettingsDoctrineCommand extends EnsureProductionSettingsCommand +{ + protected function configure() + { + parent::configure(); + + $this + ->setName('doctrine:ensure-production-settings') + ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command') + ->setHelp(<<doctrine:ensure-production-settings command ensures that +Doctrine is properly configured for a production environment.: + +php app/console doctrine:ensure-production-settings + +You can also optionally specify the --em option to specify +which entity manager to use: + +php app/console doctrine:ensure-production-settings --em=default +EOT + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); + + parent::execute($input, $output); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/InfoDoctrineCommand.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/InfoDoctrineCommand.php new file mode 100644 index 0000000..72db01a --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/InfoDoctrineCommand.php @@ -0,0 +1,57 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; + +use Doctrine\ORM\Mapping\MappingException; +use Doctrine\ORM\Tools\Console\Command\InfoCommand; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Show information about mapped entities + * + * @author Benjamin Eberlei + */ +class InfoDoctrineCommand extends InfoCommand +{ + protected function configure() + { + $this + ->setName('doctrine:mapping:info') + ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command') + ->setDescription('Shows basic information about all mapped entities') + ->setHelp(<<doctrine:mapping:info shows basic information about which +entities exist and possibly if their mapping information contains errors or +not. + +php app/console doctrine:mapping:info + +If you are using multiple entity managers you can pick your choice with the +--em option: + +php app/console doctrine:mapping:info --em=default +EOT + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); + + parent::execute($input, $output); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/RunDqlDoctrineCommand.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/RunDqlDoctrineCommand.php new file mode 100644 index 0000000..eaff6bb --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/RunDqlDoctrineCommand.php @@ -0,0 +1,63 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; + +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Output\Output; +use Doctrine\ORM\Tools\Console\Command\RunDqlCommand; + +/** + * Execute a Doctrine DQL query and output the results. + * + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class RunDqlDoctrineCommand extends RunDqlCommand +{ + protected function configure() + { + parent::configure(); + + $this + ->setName('doctrine:query:dql') + ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command') + ->setHelp(<<doctrine:query:dql command executes the given DQL query and +outputs the results: + +php app/console doctrine:query:dql "SELECT u FROM UserBundle:User u" + +You can also optional specify some additional options like what type of +hydration to use when executing the query: + +php app/console doctrine:query:dql "SELECT u FROM UserBundle:User u" --hydrate=array + +Additionally you can specify the first result and maximum amount of results to +show: + +php app/console doctrine:query:dql "SELECT u FROM UserBundle:User u" --first-result=0 --max-result=30 +EOT + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); + + return parent::execute($input, $output); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/RunSqlDoctrineCommand.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/RunSqlDoctrineCommand.php new file mode 100644 index 0000000..e04f44e --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/RunSqlDoctrineCommand.php @@ -0,0 +1,53 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; + +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Output\Output; +use Doctrine\DBAL\Tools\Console\Command\RunSqlCommand; + +/** + * Execute a SQL query and output the results. + * + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class RunSqlDoctrineCommand extends RunSqlCommand +{ + protected function configure() + { + parent::configure(); + + $this + ->setName('doctrine:query:sql') + ->addOption('connection', null, InputOption::VALUE_OPTIONAL, 'The connection to use for this command') + ->setHelp(<<doctrine:query:sql command executes the given DQL query and +outputs the results: + +php app/console doctrine:query:sql "SELECT * from user" +EOT + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + DoctrineCommandHelper::setApplicationConnection($this->getApplication(), $input->getOption('connection')); + + return parent::execute($input, $output); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/UpdateSchemaDoctrineCommand.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/UpdateSchemaDoctrineCommand.php new file mode 100644 index 0000000..4d7f0d2 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/UpdateSchemaDoctrineCommand.php @@ -0,0 +1,67 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; + +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Output\Output; +use Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand; + +/** + * Command to generate the SQL needed to update the database schema to match + * the current mapping information. + * + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class UpdateSchemaDoctrineCommand extends UpdateCommand +{ + protected function configure() + { + parent::configure(); + + $this + ->setName('doctrine:schema:update') + ->setDescription('Executes (or dumps) the SQL needed to update the database schema to match the current mapping metadata') + ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command') + ->setHelp(<<doctrine:schema:update command generates the SQL needed to +synchronize the database schema with the current mapping metadata of the +default entity manager. + +For example, if you add metadata for a new column to an entity, this command +would generate and output the SQL needed to add the new column to the database: + +php app/console doctrine:schema:update --dump-sql + +Alternatively, you can execute the generated queries: + +php app/console doctrine:schema:update --force + +You can also update the database schema for a specific entity manager: + +php app/console doctrine:schema:update --em=default +EOT + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); + + parent::execute($input, $output); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/ValidateSchemaCommand.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/ValidateSchemaCommand.php new file mode 100644 index 0000000..a20a9dc --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/Proxy/ValidateSchemaCommand.php @@ -0,0 +1,59 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; + +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand as DoctrineValidateSchemaCommand; + +/** + * Command to run Doctrine ValidateSchema() on the current mappings. + * + * @author Fabien Potencier + * @author Jonathan H. Wage + * @author Neil Katin + */ +class ValidateSchemaCommand extends DoctrineValidateSchemaCommand +{ + protected function configure() + { + parent::configure(); + + $this + ->setName('doctrine:schema:validate') + ->setDescription('Validates the doctrine mapping files') + ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command') + ->setHelp(<<doctrine:schema:validate checks the current mappings +for valid forward and reverse mappings. + +php app/console doctrine:schema:validate + +You can also optionally specify the --em option to specify +which entity manager use for the validation. + +php app/console doctrine:schema:validate --em=default +EOT + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); + + return parent::execute($input, $output); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/ConnectionFactory.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/ConnectionFactory.php new file mode 100644 index 0000000..29d04f2 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/ConnectionFactory.php @@ -0,0 +1,85 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle; + +use Doctrine\Common\EventManager; +use Doctrine\DBAL\Configuration; +use Doctrine\DBAL\DriverManager; +use Doctrine\DBAL\Types\Type; + +/** + * Connection + */ +class ConnectionFactory +{ + private $typesConfig = array(); + private $commentedTypes = array(); + private $initialized = false; + + /** + * Construct. + * + * @param array $typesConfig + */ + public function __construct(array $typesConfig) + { + $this->typesConfig = $typesConfig; + } + + /** + * Create a connection by name. + * + * @param array $params + * @param Configuration $config + * @param EventManager $eventManager + * + * @return \Doctrine\DBAL\Connection + */ + public function createConnection(array $params, Configuration $config = null, EventManager $eventManager = null, array $mappingTypes = array()) + { + if (!$this->initialized) { + $this->initializeTypes(); + $this->initialized = true; + } + + $connection = DriverManager::getConnection($params, $config, $eventManager); + + if (!empty($mappingTypes)) { + $platform = $connection->getDatabasePlatform(); + foreach ($mappingTypes as $dbType => $doctrineType) { + $platform->registerDoctrineTypeMapping($dbType, $doctrineType); + } + foreach ($this->commentedTypes as $type) { + $platform->markDoctrineTypeCommented(Type::getType($type)); + } + } + + return $connection; + } + + private function initializeTypes() + { + foreach ($this->typesConfig as $type => $typeConfig) { + if (Type::hasType($type)) { + Type::overrideType($type, $typeConfig['class']); + } else { + Type::addType($type, $typeConfig['class']); + } + if ($typeConfig['commented']) { + $this->commentedTypes[] = $type; + } + } + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Controller/ProfilerController.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Controller/ProfilerController.php new file mode 100644 index 0000000..66009e0 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Controller/ProfilerController.php @@ -0,0 +1,67 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Controller; + +use Symfony\Component\DependencyInjection\ContainerAware; +use Symfony\Component\HttpFoundation\Response; + +/** + * ProfilerController. + * + * @author Christophe Coevoet + */ +class ProfilerController extends ContainerAware +{ + /** + * Renders the profiler panel for the given token. + * + * @param string $token The profiler token + * @param string $connectionName + * @param integer $query + * + * @return Response A Response instance + */ + public function explainAction($token, $connectionName, $query) + { + $profiler = $this->container->get('profiler'); + $profiler->disable(); + + $profile = $profiler->loadProfile($token); + $queries = $profile->getCollector('db')->getQueries(); + + if (!isset($queries[$connectionName][$query])) { + return new Response('This query does not exist.'); + } + + $query = $queries[$connectionName][$query]; + if (!$query['explainable']) { + return new Response('This query cannot be explained.'); + } + + /** @var $connection \Doctrine\DBAL\Connection */ + $connection = $this->container->get('doctrine')->getConnection($connectionName); + try { + $results = $connection->executeQuery('EXPLAIN '.$query['sql'], $query['params'], $query['types']) + ->fetchAll(\PDO::FETCH_ASSOC); + } catch (\Exception $e) { + return new Response('This query cannot be explained.'); + } + + return $this->container->get('templating')->renderResponse('DoctrineBundle:Collector:explain.html.twig', array( + 'data' => $results, + 'query' => $query, + )); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/DependencyInjection/Configuration.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/DependencyInjection/Configuration.php new file mode 100644 index 0000000..e10b484 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/DependencyInjection/Configuration.php @@ -0,0 +1,388 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection; + +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; + +/** + * This class contains the configuration information for the bundle + * + * This information is solely responsible for how the different configuration + * sections are normalized, and merged. + * + * @author Christophe Coevoet + */ +class Configuration implements ConfigurationInterface +{ + private $debug; + + /** + * Constructor + * + * @param Boolean $debug Whether to use the debug mode + */ + public function __construct($debug) + { + $this->debug = (Boolean) $debug; + } + + /** + * Generates the configuration tree builder. + * + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder + */ + public function getConfigTreeBuilder() + { + $treeBuilder = new TreeBuilder(); + $rootNode = $treeBuilder->root('doctrine'); + + $this->addDbalSection($rootNode); + $this->addOrmSection($rootNode); + + return $treeBuilder; + } + + private function addDbalSection(ArrayNodeDefinition $node) + { + $node + ->children() + ->arrayNode('dbal') + ->beforeNormalization() + ->ifTrue(function ($v) { return is_array($v) && !array_key_exists('connections', $v) && !array_key_exists('connection', $v); }) + ->then(function ($v) { + // Key that should not be rewritten to the connection config + $excludedKeys = array('default_connection' => true, 'types' => true, 'type' => true); + $connection = array(); + foreach ($v as $key => $value) { + if (isset($excludedKeys[$key])) { + continue; + } + $connection[$key] = $v[$key]; + unset($v[$key]); + } + $v['default_connection'] = isset($v['default_connection']) ? (string) $v['default_connection'] : 'default'; + $v['connections'] = array($v['default_connection'] => $connection); + + return $v; + }) + ->end() + ->children() + ->scalarNode('default_connection')->end() + ->end() + ->fixXmlConfig('type') + ->children() + ->arrayNode('types') + ->useAttributeAsKey('name') + ->prototype('array') + ->beforeNormalization() + ->ifString() + ->then(function($v) { return array('class' => $v); }) + ->end() + ->children() + ->scalarNode('class')->isRequired()->end() + ->booleanNode('commented')->defaultTrue()->end() + ->end() + ->end() + ->end() + ->end() + ->fixXmlConfig('connection') + ->append($this->getDbalConnectionsNode()) + ->end() + ; + } + + private function getDbalConnectionsNode() + { + $treeBuilder = new TreeBuilder(); + $node = $treeBuilder->root('connections'); + + /** @var $connectionNode ArrayNodeDefinition */ + $connectionNode = $node + ->requiresAtLeastOneElement() + ->useAttributeAsKey('name') + ->prototype('array') + ; + + $this->configureDbalDriverNode($connectionNode); + + $connectionNode + ->fixXmlConfig('option') + ->fixXmlConfig('mapping_type') + ->fixXmlConfig('slave') + ->children() + ->scalarNode('driver')->defaultValue('pdo_mysql')->end() + ->scalarNode('platform_service')->end() + ->booleanNode('logging')->defaultValue($this->debug)->end() + ->booleanNode('profiling')->defaultValue($this->debug)->end() + ->scalarNode('driver_class')->end() + ->scalarNode('wrapper_class')->end() + ->arrayNode('options') + ->useAttributeAsKey('key') + ->prototype('scalar')->end() + ->end() + ->arrayNode('mapping_types') + ->useAttributeAsKey('name') + ->prototype('scalar')->end() + ->end() + ->end() + ; + + $slaveNode = $connectionNode + ->children() + ->arrayNode('slaves') + ->useAttributeAsKey('name') + ->prototype('array') + ; + $this->configureDbalDriverNode($slaveNode); + + return $node; + } + + /** + * Adds config keys related to params processed by the DBAL drivers + * + * These keys are available for slave configurations too. + * + * @param \Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition $node + */ + private function configureDbalDriverNode(ArrayNodeDefinition $node) + { + $node + ->children() + ->scalarNode('dbname')->end() + ->scalarNode('host')->defaultValue('localhost')->end() + ->scalarNode('port')->defaultNull()->end() + ->scalarNode('user')->defaultValue('root')->end() + ->scalarNode('password')->defaultNull()->end() + ->scalarNode('charset')->end() + ->scalarNode('path')->end() + ->booleanNode('memory')->end() + ->scalarNode('unix_socket')->info('The unix socket to use for MySQL')->end() + ->booleanNode('persistent')->info('True to use as persistent connection for the ibm_db2 driver')->end() + ->scalarNode('protocol')->info('The protocol to use for the ibm_db2 driver (default to TCPIP if ommited)')->end() + ->booleanNode('service')->info('True to use dbname as service name instead of SID for Oracle')->end() + ->scalarNode('sessionMode') + ->info('The session mode to use for the oci8 driver') + ->end() + ->booleanNode('pooled')->info('True to use a pooled server with the oci8 driver')->end() + ->booleanNode('MultipleActiveResultSets')->info('Configuring MultipleActiveResultSets for the pdo_sqlsrv driver')->end() + ->end() + ->beforeNormalization() + ->ifTrue(function($v) {return !isset($v['sessionMode']) && isset($v['session_mode']);}) + ->then(function($v) { + $v['sessionMode'] = $v['session_mode']; + unset($v['session_mode']); + + return $v; + }) + ->end() + ->beforeNormalization() + ->ifTrue(function($v) {return !isset($v['MultipleActiveResultSets']) && isset($v['multiple_active_result_sets']);}) + ->then(function($v) { + $v['MultipleActiveResultSets'] = $v['multiple_active_result_sets']; + unset($v['multiple_active_result_sets']); + + return $v; + }) + ->end() + ; + } + + private function addOrmSection(ArrayNodeDefinition $node) + { + $node + ->children() + ->arrayNode('orm') + ->beforeNormalization() + ->ifTrue(function ($v) { return null === $v || (is_array($v) && !array_key_exists('entity_managers', $v) && !array_key_exists('entity_manager', $v)); }) + ->then(function ($v) { + $v = (array) $v; + // Key that should not be rewritten to the connection config + $excludedKeys = array( + 'default_entity_manager' => true, 'auto_generate_proxy_classes' => true, + 'proxy_dir' => true, 'proxy_namespace' => true, 'resolve_target_entities' => true, + 'resolve_target_entity' => true, + ); + $entityManager = array(); + foreach ($v as $key => $value) { + if (isset($excludedKeys[$key])) { + continue; + } + $entityManager[$key] = $v[$key]; + unset($v[$key]); + } + $v['default_entity_manager'] = isset($v['default_entity_manager']) ? (string) $v['default_entity_manager'] : 'default'; + $v['entity_managers'] = array($v['default_entity_manager'] => $entityManager); + + return $v; + }) + ->end() + ->children() + ->scalarNode('default_entity_manager')->end() + ->booleanNode('auto_generate_proxy_classes')->defaultFalse()->end() + ->scalarNode('proxy_dir')->defaultValue('%kernel.cache_dir%/doctrine/orm/Proxies')->end() + ->scalarNode('proxy_namespace')->defaultValue('Proxies')->end() + ->end() + ->fixXmlConfig('entity_manager') + ->append($this->getOrmEntityManagersNode()) + ->fixXmlConfig('resolve_target_entity', 'resolve_target_entities') + ->append($this->getOrmTargetEntityResolverNode()) + ->end() + ->end() + ; + } + + private function getOrmTargetEntityResolverNode() + { + $treeBuilder = new TreeBuilder(); + $node = $treeBuilder->root('resolve_target_entities'); + + $node + ->useAttributeAsKey('interface') + ->prototype('scalar') + ->cannotBeEmpty() + ->end() + ; + + return $node; + } + + private function getOrmEntityManagersNode() + { + $treeBuilder = new TreeBuilder(); + $node = $treeBuilder->root('entity_managers'); + + $node + ->requiresAtLeastOneElement() + ->useAttributeAsKey('name') + ->prototype('array') + ->addDefaultsIfNotSet() + ->append($this->getOrmCacheDriverNode('query_cache_driver')) + ->append($this->getOrmCacheDriverNode('metadata_cache_driver')) + ->append($this->getOrmCacheDriverNode('result_cache_driver')) + ->children() + ->scalarNode('connection')->end() + ->scalarNode('class_metadata_factory_name')->defaultValue('Doctrine\ORM\Mapping\ClassMetadataFactory')->end() + ->scalarNode('default_repository_class')->defaultValue('Doctrine\ORM\EntityRepository')->end() + ->scalarNode('auto_mapping')->defaultFalse()->end() + ->end() + ->fixXmlConfig('hydrator') + ->children() + ->arrayNode('hydrators') + ->useAttributeAsKey('name') + ->prototype('scalar')->end() + ->end() + ->end() + ->fixXmlConfig('mapping') + ->children() + ->arrayNode('mappings') + ->useAttributeAsKey('name') + ->prototype('array') + ->beforeNormalization() + ->ifString() + ->then(function($v) { return array('type' => $v); }) + ->end() + ->treatNullLike(array()) + ->treatFalseLike(array('mapping' => false)) + ->performNoDeepMerging() + ->children() + ->scalarNode('mapping')->defaultValue(true)->end() + ->scalarNode('type')->end() + ->scalarNode('dir')->end() + ->scalarNode('alias')->end() + ->scalarNode('prefix')->end() + ->booleanNode('is_bundle')->end() + ->end() + ->end() + ->end() + ->arrayNode('dql') + ->fixXmlConfig('string_function') + ->fixXmlConfig('numeric_function') + ->fixXmlConfig('datetime_function') + ->children() + ->arrayNode('string_functions') + ->useAttributeAsKey('name') + ->prototype('scalar')->end() + ->end() + ->arrayNode('numeric_functions') + ->useAttributeAsKey('name') + ->prototype('scalar')->end() + ->end() + ->arrayNode('datetime_functions') + ->useAttributeAsKey('name') + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + ->end() + ->fixXmlConfig('filter') + ->children() + ->arrayNode('filters') + ->info('Register SQL Filters in the entity manager') + ->useAttributeAsKey('name') + ->prototype('array') + ->beforeNormalization() + ->ifString() + ->then(function($v) { return array('class' => $v); }) + ->end() + ->beforeNormalization() + // The content of the XML node is returned as the "value" key so we need to rename it + ->ifTrue(function($v) {return is_array($v) && isset($v['value']); }) + ->then(function($v) { + $v['class'] = $v['value']; + unset($v['value']); + + return $v; + }) + ->end() + ->children() + ->scalarNode('class')->isRequired()->end() + ->booleanNode('enabled')->defaultFalse()->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ; + + return $node; + } + + private function getOrmCacheDriverNode($name) + { + $treeBuilder = new TreeBuilder(); + $node = $treeBuilder->root($name); + + $node + ->addDefaultsIfNotSet() + ->beforeNormalization() + ->ifString() + ->then(function($v) { return array('type' => $v); }) + ->end() + ->children() + ->scalarNode('type')->defaultValue('array')->end() + ->scalarNode('host')->end() + ->scalarNode('port')->end() + ->scalarNode('instance_class')->end() + ->scalarNode('class')->end() + ->scalarNode('id')->end() + ->end() + ; + + return $node; + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php new file mode 100644 index 0000000..224527c --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php @@ -0,0 +1,437 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection; + +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Bridge\Doctrine\DependencyInjection\AbstractDoctrineExtension; +use Symfony\Component\Config\FileLocator; + +/** + * DoctrineExtension is an extension for the Doctrine DBAL and ORM library. + * + * @author Jonathan H. Wage + * @author Fabien Potencier + * @author Benjamin Eberlei + */ +class DoctrineExtension extends AbstractDoctrineExtension +{ + public function load(array $configs, ContainerBuilder $container) + { + $configuration = $this->getConfiguration($configs, $container); + $config = $this->processConfiguration($configuration, $configs); + + if (!empty($config['dbal'])) { + $this->dbalLoad($config['dbal'], $container); + } + + if (!empty($config['orm'])) { + $this->ormLoad($config['orm'], $container); + } + } + + /** + * Loads the DBAL configuration. + * + * Usage example: + * + * + * + * @param array $config An array of configuration settings + * @param ContainerBuilder $container A ContainerBuilder instance + */ + protected function dbalLoad(array $config, ContainerBuilder $container) + { + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('dbal.xml'); + + if (empty($config['default_connection'])) { + $keys = array_keys($config['connections']); + $config['default_connection'] = reset($keys); + } + $this->defaultConnection = $config['default_connection']; + + $container->setAlias('database_connection', sprintf('doctrine.dbal.%s_connection', $this->defaultConnection)); + $container->setAlias('doctrine.dbal.event_manager', new Alias(sprintf('doctrine.dbal.%s_connection.event_manager', $this->defaultConnection), false)); + + $container->setParameter('doctrine.dbal.connection_factory.types', $config['types']); + + $connections = array(); + foreach (array_keys($config['connections']) as $name) { + $connections[$name] = sprintf('doctrine.dbal.%s_connection', $name); + } + $container->setParameter('doctrine.connections', $connections); + $container->setParameter('doctrine.default_connection', $this->defaultConnection); + + foreach ($config['connections'] as $name => $connection) { + $this->loadDbalConnection($name, $connection, $container); + } + } + + /** + * Loads a configured DBAL connection. + * + * @param string $name The name of the connection + * @param array $connection A dbal connection configuration. + * @param ContainerBuilder $container A ContainerBuilder instance + */ + protected function loadDbalConnection($name, array $connection, ContainerBuilder $container) + { + // configuration + $configuration = $container->setDefinition(sprintf('doctrine.dbal.%s_connection.configuration', $name), new DefinitionDecorator('doctrine.dbal.connection.configuration')); + $logger = null; + if ($connection['logging']) { + $logger = new Reference('doctrine.dbal.logger'); + } + unset ($connection['logging']); + if ($connection['profiling']) { + $profilingLoggerId = 'doctrine.dbal.logger.profiling.'.$name; + $container->setDefinition($profilingLoggerId, new DefinitionDecorator('doctrine.dbal.logger.profiling')); + $logger = new Reference($profilingLoggerId); + $container->getDefinition('data_collector.doctrine')->addMethodCall('addLogger', array($name, $logger)); + + if (null !== $logger) { + $chainLogger = new DefinitionDecorator('doctrine.dbal.logger.chain'); + $chainLogger->addMethodCall('addLogger', array($logger)); + + $loggerId = 'doctrine.dbal.logger.chain.'.$name; + $container->setDefinition($loggerId, $chainLogger); + $logger = new Reference($loggerId); + } + } + unset($connection['profiling']); + + if ($logger) { + $configuration->addMethodCall('setSQLLogger', array($logger)); + } + + // event manager + $def = $container->setDefinition(sprintf('doctrine.dbal.%s_connection.event_manager', $name), new DefinitionDecorator('doctrine.dbal.connection.event_manager')); + + // connection + if (isset($connection['charset'])) { + if ((isset($connection['driver']) && stripos($connection['driver'], 'mysql') !== false) || + (isset($connection['driver_class']) && stripos($connection['driver_class'], 'mysql') !== false)) { + $mysqlSessionInit = new Definition('%doctrine.dbal.events.mysql_session_init.class%'); + $mysqlSessionInit->setArguments(array($connection['charset'])); + $mysqlSessionInit->setPublic(false); + $mysqlSessionInit->addTag('doctrine.event_subscriber', array('connection' => $name)); + + $container->setDefinition( + sprintf('doctrine.dbal.%s_connection.events.mysqlsessioninit', $name), + $mysqlSessionInit + ); + unset($connection['charset']); + } + } + + $options = $this->getConnectionOptions($connection); + + $container + ->setDefinition(sprintf('doctrine.dbal.%s_connection', $name), new DefinitionDecorator('doctrine.dbal.connection')) + ->setArguments(array( + $options, + new Reference(sprintf('doctrine.dbal.%s_connection.configuration', $name)), + new Reference(sprintf('doctrine.dbal.%s_connection.event_manager', $name)), + $connection['mapping_types'], + )) + ; + } + + protected function getConnectionOptions($connection) + { + $options = $connection; + + if (isset($options['platform_service'])) { + $options['platform'] = new Reference($options['platform_service']); + unset($options['platform_service']); + } + unset($options['mapping_types']); + + foreach (array( + 'options' => 'driverOptions', + 'driver_class' => 'driverClass', + 'wrapper_class' => 'wrapperClass', + ) as $old => $new) { + if (isset($options[$old])) { + $options[$new] = $options[$old]; + unset($options[$old]); + } + } + + if (!empty($options['slaves'])) { + $nonRewrittenKeys = array( + 'driver' => true, 'driverOptions' => true, 'driverClass' => true, 'wrapperClass' => true, + 'platform' => true, 'slaves' => true, 'master' => true, + // included by safety but should have been unset already + 'logging' => true, 'profiling' => true, 'mapping_types' => true, 'platform_service' => true, + ); + foreach ($options as $key => $value) { + if (isset($nonRewrittenKeys[$key])) { + continue; + } + $options['master'][$key] = $value; + unset($options[$key]); + } + if (empty($options['wrapperClass'])) { + // Change the wrapper class only if the user does not already forced using a custom one. + $options['wrapperClass'] = 'Doctrine\\DBAL\\Connections\\MasterSlaveConnection'; + } + } else { + unset($options['slaves']); + } + + return $options; + } + + /** + * Loads the Doctrine ORM configuration. + * + * Usage example: + * + * + * + * @param array $config An array of configuration settings + * @param ContainerBuilder $container A ContainerBuilder instance + */ + protected function ormLoad(array $config, ContainerBuilder $container) + { + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('orm.xml'); + + $this->entityManagers = array(); + foreach (array_keys($config['entity_managers']) as $name) { + $this->entityManagers[$name] = sprintf('doctrine.orm.%s_entity_manager', $name); + } + $container->setParameter('doctrine.entity_managers', $this->entityManagers); + + if (empty($config['default_entity_manager'])) { + $tmp = array_keys($this->entityManagers); + $config['default_entity_manager'] = reset($tmp); + } + $container->setParameter('doctrine.default_entity_manager', $config['default_entity_manager']); + + $options = array('auto_generate_proxy_classes', 'proxy_dir', 'proxy_namespace'); + foreach ($options as $key) { + $container->setParameter('doctrine.orm.'.$key, $config[$key]); + } + + $container->setAlias('doctrine.orm.entity_manager', sprintf('doctrine.orm.%s_entity_manager', $config['default_entity_manager'])); + + foreach ($config['entity_managers'] as $name => $entityManager) { + $entityManager['name'] = $name; + $this->loadOrmEntityManager($entityManager, $container); + } + + if ($config['resolve_target_entities']) { + $def = $container->findDefinition('doctrine.orm.listeners.resolve_target_entity'); + foreach ($config['resolve_target_entities'] as $name => $implementation) { + $def->addMethodCall('addResolveTargetEntity', array( + $name, $implementation, array() + )); + } + + $def->addTag('doctrine.event_listener', array('event' => 'loadClassMetadata')); + } + } + + /** + * Loads a configured ORM entity manager. + * + * @param array $entityManager A configured ORM entity manager. + * @param ContainerBuilder $container A ContainerBuilder instance + */ + protected function loadOrmEntityManager(array $entityManager, ContainerBuilder $container) + { + if ($entityManager['auto_mapping'] && count($this->entityManagers) > 1) { + throw new \LogicException('You cannot enable "auto_mapping" when several entity managers are defined.'); + } + + $ormConfigDef = $container->setDefinition(sprintf('doctrine.orm.%s_configuration', $entityManager['name']), new DefinitionDecorator('doctrine.orm.configuration')); + + $this->loadOrmEntityManagerMappingInformation($entityManager, $ormConfigDef, $container); + $this->loadOrmCacheDrivers($entityManager, $container); + + $methods = array( + 'setMetadataCacheImpl' => new Reference(sprintf('doctrine.orm.%s_metadata_cache', $entityManager['name'])), + 'setQueryCacheImpl' => new Reference(sprintf('doctrine.orm.%s_query_cache', $entityManager['name'])), + 'setResultCacheImpl' => new Reference(sprintf('doctrine.orm.%s_result_cache', $entityManager['name'])), + 'setMetadataDriverImpl' => new Reference('doctrine.orm.'.$entityManager['name'].'_metadata_driver'), + 'setProxyDir' => '%doctrine.orm.proxy_dir%', + 'setProxyNamespace' => '%doctrine.orm.proxy_namespace%', + 'setAutoGenerateProxyClasses' => '%doctrine.orm.auto_generate_proxy_classes%', + 'setClassMetadataFactoryName' => $entityManager['class_metadata_factory_name'], + 'setDefaultRepositoryClassName' => $entityManager['default_repository_class'], + ); + foreach ($methods as $method => $arg) { + $ormConfigDef->addMethodCall($method, array($arg)); + } + + foreach ($entityManager['hydrators'] as $name => $class) { + $ormConfigDef->addMethodCall('addCustomHydrationMode', array($name, $class)); + } + + if (!empty($entityManager['dql'])) { + foreach ($entityManager['dql']['string_functions'] as $name => $function) { + $ormConfigDef->addMethodCall('addCustomStringFunction', array($name, $function)); + } + foreach ($entityManager['dql']['numeric_functions'] as $name => $function) { + $ormConfigDef->addMethodCall('addCustomNumericFunction', array($name, $function)); + } + foreach ($entityManager['dql']['datetime_functions'] as $name => $function) { + $ormConfigDef->addMethodCall('addCustomDatetimeFunction', array($name, $function)); + } + } + + $enabledFilters = array(); + foreach ($entityManager['filters'] as $name => $filter) { + $ormConfigDef->addMethodCall('addFilter', array($name, $filter['class'])); + if ($filter['enabled']) { + $enabledFilters[] = $name; + } + } + + $managerConfiguratorName = sprintf('doctrine.orm.%s_manager_configurator', $entityManager['name']); + $managerConfiguratorDef = $container + ->setDefinition($managerConfiguratorName, new DefinitionDecorator('doctrine.orm.manager_configurator.abstract')) + ->replaceArgument(0, $enabledFilters) + ; + + if (!isset($entityManager['connection'])) { + $entityManager['connection'] = $this->defaultConnection; + } + + $container + ->setDefinition(sprintf('doctrine.orm.%s_entity_manager', $entityManager['name']), new DefinitionDecorator('doctrine.orm.entity_manager.abstract')) + ->setArguments(array( + new Reference(sprintf('doctrine.dbal.%s_connection', $entityManager['connection'])), + new Reference(sprintf('doctrine.orm.%s_configuration', $entityManager['name'])) + )) + ->setConfigurator(array(new Reference($managerConfiguratorName), 'configure')) + ; + + $container->setAlias( + sprintf('doctrine.orm.%s_entity_manager.event_manager', $entityManager['name']), + new Alias(sprintf('doctrine.dbal.%s_connection.event_manager', $entityManager['connection']), false) + ); + } + + /** + * Loads an ORM entity managers bundle mapping information. + * + * There are two distinct configuration possibilities for mapping information: + * + * 1. Specify a bundle and optionally details where the entity and mapping information reside. + * 2. Specify an arbitrary mapping location. + * + * @example + * + * doctrine.orm: + * mappings: + * MyBundle1: ~ + * MyBundle2: yml + * MyBundle3: { type: annotation, dir: Entities/ } + * MyBundle4: { type: xml, dir: Resources/config/doctrine/mapping } + * MyBundle5: + * type: yml + * dir: [bundle-mappings1/, bundle-mappings2/] + * alias: BundleAlias + * arbitrary_key: + * type: xml + * dir: %kernel.dir%/../src/vendor/DoctrineExtensions/lib/DoctrineExtensions/Entities + * prefix: DoctrineExtensions\Entities\ + * alias: DExt + * + * In the case of bundles everything is really optional (which leads to autodetection for this bundle) but + * in the mappings key everything except alias is a required argument. + * + * @param array $entityManager A configured ORM entity manager + * @param Definition $ormConfigDef A Definition instance + * @param ContainerBuilder $container A ContainerBuilder instance + */ + protected function loadOrmEntityManagerMappingInformation(array $entityManager, Definition $ormConfigDef, ContainerBuilder $container) + { + // reset state of drivers and alias map. They are only used by this methods and children. + $this->drivers = array(); + $this->aliasMap = array(); + + $this->loadMappingInformation($entityManager, $container); + $this->registerMappingDrivers($entityManager, $container); + + $ormConfigDef->addMethodCall('setEntityNamespaces', array($this->aliasMap)); + } + + protected function getObjectManagerElementName($name) + { + return 'doctrine.orm.'.$name; + } + + protected function getMappingObjectDefaultName() + { + return 'Entity'; + } + + protected function getMappingResourceConfigDirectory() + { + return 'Resources/config/doctrine'; + } + + protected function getMappingResourceExtension() + { + return 'orm'; + } + + /** + * Loads a configured entity managers cache drivers. + * + * @param array $entityManager A configured ORM entity manager. + * @param ContainerBuilder $container A ContainerBuilder instance + */ + protected function loadOrmCacheDrivers(array $entityManager, ContainerBuilder $container) + { + $this->loadObjectManagerCacheDriver($entityManager, $container, 'metadata_cache'); + $this->loadObjectManagerCacheDriver($entityManager, $container, 'result_cache'); + $this->loadObjectManagerCacheDriver($entityManager, $container, 'query_cache'); + } + + /** + * Returns the base path for the XSD files. + * + * @return string The XSD base path + */ + public function getXsdValidationBasePath() + { + return __DIR__.'/../Resources/config/schema'; + } + + /** + * Returns the namespace to be used for this extension (XML namespace). + * + * @return string The XML namespace + */ + public function getNamespace() + { + return 'http://symfony.com/schema/dic/doctrine'; + } + + public function getConfiguration(array $config, ContainerBuilder $container) + { + return new Configuration($container->getParameter('kernel.debug')); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/DoctrineBundle.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/DoctrineBundle.php new file mode 100644 index 0000000..d611572 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/DoctrineBundle.php @@ -0,0 +1,120 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle; + +use Doctrine\Common\Util\ClassUtils; +use Doctrine\Bundle\DoctrineBundle\Command\CreateDatabaseDoctrineCommand; +use Doctrine\Bundle\DoctrineBundle\Command\DropDatabaseDoctrineCommand; +use Doctrine\Bundle\DoctrineBundle\Command\Proxy\RunSqlDoctrineCommand; +use Symfony\Component\Console\Application; +use Symfony\Component\DependencyInjection\Compiler\PassConfig; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\HttpKernel\Bundle\Bundle; +use Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass\DoctrineValidationPass; +use Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass\RegisterEventListenersAndSubscribersPass; +use Symfony\Bridge\Doctrine\DependencyInjection\Security\UserProvider\EntityFactory; + +/** + * Bundle. + * + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class DoctrineBundle extends Bundle +{ + private $autoloader; + + public function build(ContainerBuilder $container) + { + parent::build($container); + + $container->addCompilerPass(new RegisterEventListenersAndSubscribersPass('doctrine.connections', 'doctrine.dbal.%s_connection.event_manager', 'doctrine'), PassConfig::TYPE_BEFORE_OPTIMIZATION); + + if ($container->hasExtension('security')) { + $container->getExtension('security')->addUserProviderFactory(new EntityFactory('entity', 'doctrine.orm.security.user.provider')); + } + $container->addCompilerPass(new DoctrineValidationPass('orm')); + } + + public function boot() + { + // Register an autoloader for proxies to avoid issues when unserializing them + // when the ORM is used. + if ($this->container->hasParameter('doctrine.orm.proxy_namespace')) { + $namespace = $this->container->getParameter('doctrine.orm.proxy_namespace'); + $dir = $this->container->getParameter('doctrine.orm.proxy_dir'); + // See https://github.com/symfony/symfony/pull/3419 for usage of + // references + $container =& $this->container; + + $this->autoloader = function($class) use ($namespace, $dir, &$container) { + if (0 === strpos($class, $namespace)) { + $fileName = str_replace('\\', '', substr($class, strlen($namespace) +1)); + $file = $dir.DIRECTORY_SEPARATOR.$fileName.'.php'; + + if (!is_file($file) && $container->getParameter('kernel.debug')) { + $originalClassName = ClassUtils::getRealClass($class); + $registry = $container->get('doctrine'); + + // Tries to auto-generate the proxy file + foreach ($registry->getManagers() as $em) { + + if ($em->getConfiguration()->getAutoGenerateProxyClasses()) { + $classes = $em->getMetadataFactory()->getAllMetadata(); + + foreach ($classes as $classMetadata) { + if ($classMetadata->name == $originalClassName) { + $em->getProxyFactory()->generateProxyClasses(array($classMetadata)); + } + } + } + } + + clearstatcache($file); + } + + if (file_exists($file)) { + require $file; + } + } + }; + spl_autoload_register($this->autoloader); + } + } + + public function shutdown() + { + if (null !== $this->autoloader) { + spl_autoload_unregister($this->autoloader); + $this->autoloader = null; + } + } + + public function registerCommands(Application $application) + { + // Use the default logic when the ORM is available. + // This avoids listing all ORM commands by hand. + if (class_exists('Doctrine\\ORM\\Version')) { + parent::registerCommands($application); + + return; + } + + // Register only the DBAL commands if the ORM is not available. + $application->add(new CreateDatabaseDoctrineCommand()); + $application->add(new DropDatabaseDoctrineCommand()); + $application->add(new RunSqlDoctrineCommand()); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/LICENSE b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/LICENSE new file mode 100644 index 0000000..655a5ce --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2011 Fabien Potencier, Doctrine Project + +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/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/ManagerConfigurator.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/ManagerConfigurator.php new file mode 100644 index 0000000..fa4b563 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/ManagerConfigurator.php @@ -0,0 +1,59 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle; + +use Doctrine\ORM\EntityManager; + +/** + * Configurator for an EntityManager + * + * @author Christophe Coevoet + */ +class ManagerConfigurator +{ + private $enabledFilters = array(); + + /** + * Construct. + * + * @param array $enabledFilters + */ + public function __construct(array $enabledFilters) + { + $this->enabledFilters = $enabledFilters; + } + + /** + * Create a connection by name. + * + * @param EntityManager $entityManager + */ + public function configure(EntityManager $entityManager) + { + $this->enableFilters($entityManager); + } + + private function enableFilters(EntityManager $entityManager) + { + if (empty($this->enabledFilters)) { + return; + } + + $filterCollection = $entityManager->getFilters(); + foreach ($this->enabledFilters as $filter) { + $filterCollection->enable($filter); + } + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Mapping/ClassMetadataCollection.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Mapping/ClassMetadataCollection.php new file mode 100644 index 0000000..e441151 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Mapping/ClassMetadataCollection.php @@ -0,0 +1,55 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Mapping; + +/** + * @author Fabien Potencier + */ +class ClassMetadataCollection +{ + private $path; + private $namespace; + private $metadata; + + public function __construct(array $metadata) + { + $this->metadata = $metadata; + } + + public function getMetadata() + { + return $this->metadata; + } + + public function setPath($path) + { + $this->path = $path; + } + + public function getPath() + { + return $this->path; + } + + public function setNamespace($namespace) + { + $this->namespace = $namespace; + } + + public function getNamespace() + { + return $this->namespace; + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Mapping/DisconnectedMetadataFactory.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Mapping/DisconnectedMetadataFactory.php new file mode 100644 index 0000000..ffcb7de --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Mapping/DisconnectedMetadataFactory.php @@ -0,0 +1,26 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Mapping; + +/** + * @author Fabien Potencier + */ +class DisconnectedMetadataFactory extends MetadataFactory +{ + protected function getClassMetadataFactoryClass() + { + return 'Doctrine\\ORM\\Tools\\DisconnectedClassMetadataFactory'; + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Mapping/MetadataFactory.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Mapping/MetadataFactory.php new file mode 100644 index 0000000..e6e5199 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Mapping/MetadataFactory.php @@ -0,0 +1,180 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Mapping; + +use Doctrine\Common\Persistence\ManagerRegistry; +use Symfony\Component\HttpKernel\Bundle\BundleInterface; +use Doctrine\ORM\Mapping\MappingException; + +/** + * This class provides methods to access Doctrine entity class metadata for a + * given bundle, namespace or entity class. + * + * @author Fabien Potencier + */ +class MetadataFactory +{ + private $registry; + + /** + * Constructor. + * + * @param ManagerRegistry $registry A ManagerRegistry instance + */ + public function __construct(ManagerRegistry $registry) + { + $this->registry = $registry; + } + + /** + * Gets the metadata of all classes of a bundle. + * + * @param BundleInterface $bundle A BundleInterface instance + * + * @return ClassMetadataCollection A ClassMetadataCollection instance + */ + public function getBundleMetadata(BundleInterface $bundle) + { + $namespace = $bundle->getNamespace(); + $metadata = $this->getMetadataForNamespace($namespace); + if (!$metadata->getMetadata()) { + throw new \RuntimeException(sprintf('Bundle "%s" does not contain any mapped entities.', $bundle->getName())); + } + + $path = $this->getBasePathForClass($bundle->getName(), $bundle->getNamespace(), $bundle->getPath()); + + $metadata->setPath($path); + $metadata->setNamespace($bundle->getNamespace()); + + return $metadata; + } + + /** + * Gets the metadata of a class. + * + * @param string $class A class name + * @param string $path The path where the class is stored (if known) + * + * @return ClassMetadataCollection A ClassMetadataCollection instance + */ + public function getClassMetadata($class, $path = null) + { + $metadata = $this->getMetadataForClass($class); + if (!$metadata->getMetadata()) { + throw MappingException::classIsNotAValidEntityOrMappedSuperClass($class); + } + + $this->findNamespaceAndPathForMetadata($metadata); + + return $metadata; + } + + /** + * Gets the metadata of all classes of a namespace. + * + * @param string $namespace A namespace name + * @param string $path The path where the class is stored (if known) + * + * @return ClassMetadataCollection A ClassMetadataCollection instance + */ + public function getNamespaceMetadata($namespace, $path = null) + { + $metadata = $this->getMetadataForNamespace($namespace); + if (!$metadata->getMetadata()) { + throw new \RuntimeException(sprintf('Namespace "%s" does not contain any mapped entities.', $namespace)); + } + + $this->findNamespaceAndPathForMetadata($metadata, $path); + + return $metadata; + } + + /** + * Find and configure path and namespace for the metadata collection. + * + * @param ClassMetadataCollection $metadata + * @param string|null $path + * @return void + */ + public function findNamespaceAndPathForMetadata(ClassMetadataCollection $metadata, $path = null) + { + $all = $metadata->getMetadata(); + if (class_exists($all[0]->name)) { + $r = new \ReflectionClass($all[0]->name); + $path = $this->getBasePathForClass($r->getName(), $r->getNamespaceName(), dirname($r->getFilename())); + } elseif (!$path) { + throw new \RuntimeException(sprintf('Unable to determine where to save the "%s" class (use the --path option).', $all[0]->name)); + } + + $metadata->setPath($path); + $metadata->setNamespace(isset($r) ? $r->getNamespaceName() : $all[0]->name); + } + + private function getBasePathForClass($name, $namespace, $path) + { + $namespace = str_replace('\\', '/', $namespace); + $search = str_replace('\\', '/', $path); + $destination = str_replace('/'.$namespace, '', $search, $c); + + if ($c != 1) { + throw new \RuntimeException(sprintf('Can\'t find base path for "%s" (path: "%s", destination: "%s").', $name, $path, $destination)); + } + + return $destination; + } + + private function getMetadataForNamespace($namespace) + { + $metadata = array(); + foreach ($this->getAllMetadata() as $m) { + if (strpos($m->name, $namespace) === 0) { + $metadata[] = $m; + } + } + + return new ClassMetadataCollection($metadata); + } + + private function getMetadataForClass($entity) + { + foreach ($this->getAllMetadata() as $metadata) { + if ($metadata->name === $entity) { + return new ClassMetadataCollection(array($metadata)); + } + } + + return new ClassMetadataCollection(array()); + } + + private function getAllMetadata() + { + $metadata = array(); + foreach ($this->registry->getManagers() as $em) { + $class = $this->getClassMetadataFactoryClass(); + $cmf = new $class(); + $cmf->setEntityManager($em); + foreach ($cmf->getAllMetadata() as $m) { + $metadata[] = $m; + } + } + + return $metadata; + } + + protected function getClassMetadataFactoryClass() + { + return 'Doctrine\\ORM\\Mapping\\ClassMetadataFactory'; + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/README.md b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/README.md new file mode 100644 index 0000000..31391c5 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/README.md @@ -0,0 +1,56 @@ +# Doctrine Bundle + +Doctrine DBAL & ORM Bundle for the Symfony Framework. + +Because Symfony 2 does not want to force or suggest a specific persistence solutions on the users +this bundle was removed from the core of the Symfony 2 framework. Doctrine2 will still be a major player +in the Symfony world and the bundle is maintained by developers in the Doctrine and Symfony communities. + + IMPORTANT: This bundle is developed for Symfony 2.1 and up. For Symfony 2.0 applications the DoctrineBundle + is still shipped with the core Symfony repository. + +Build Status: [![Build Status](https://secure.travis-ci.org/doctrine/DoctrineBundle.png?branch=master)](http://travis-ci.org/doctrine/DoctrineBundle) + +## What is Doctrine? + +The Doctrine Project is the home of a selected set of PHP libraries primarily focused on providing persistence +services and related functionality. Its prize projects are a Object Relational Mapper and the Database Abstraction +Layer it is built on top of. You can read more about the projects below or view a list of all projects. + +Object relational mapper (ORM) for PHP that sits on top of a powerful database abstraction layer (DBAL). +One of its key features is the option to write database queries in a proprietary object oriented SQL dialect +called Doctrine Query Language (DQL), inspired by Hibernates HQL. This provides developers with a powerful +alternative to SQL that maintains flexibility without requiring unnecessary code duplication. + +DBAL is a powerful database abstraction layer with many features for database schema introspection, +schema management and PDO abstraction. + +## Installation + +### 1. Old deps and bin/vendors way + +Add the following snippets to "deps" files: + + [doctrine-dbal] + git=http://github.com/doctrine/dbal.git + + [doctrine-orm] + git=http://github.com/doctrine/doctrine2.git + + [DoctrineBundle] + git=http://github.com/doctrine/DoctrineBundle.git + target=/bundles/Doctrine/Bundle/DoctrineBundle + +### 2. Composer + +Add the following dependencies to your projects composer.json file: + + "require": { + # .. + "doctrine/doctrine-bundle": ">=2.1" + # .. + } + +## Documentation + +See the Resources/docs folder more a full documentation. diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Registry.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Registry.php new file mode 100644 index 0000000..1b10b7f --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Registry.php @@ -0,0 +1,155 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Bridge\Doctrine\RegistryInterface; +use Symfony\Bridge\Doctrine\ManagerRegistry; +use Doctrine\ORM\ORMException; +use Doctrine\ORM\EntityManager; + +/** + * References all Doctrine connections and entity managers in a given Container. + * + * @author Fabien Potencier + */ +class Registry extends ManagerRegistry implements RegistryInterface +{ + public function __construct(ContainerInterface $container, array $connections, array $entityManagers, $defaultConnection, $defaultEntityManager) + { + $this->setContainer($container); + + parent::__construct('ORM', $connections, $entityManagers, $defaultConnection, $defaultEntityManager, 'Doctrine\ORM\Proxy\Proxy'); + } + + /** + * Gets the default entity manager name. + * + * @return string The default entity manager name + * + * @deprecated + */ + public function getDefaultEntityManagerName() + { + return $this->getDefaultManagerName(); + } + + /** + * Gets a named entity manager. + * + * @param string $name The entity manager name (null for the default one) + * + * @return EntityManager + * + * @deprecated + */ + public function getEntityManager($name = null) + { + return $this->getManager($name); + } + + /** + * Gets an array of all registered entity managers + * + * @return EntityManager[] an array of all EntityManager instances + * + * @deprecated + */ + public function getEntityManagers() + { + return $this->getManagers(); + } + + /** + * Resets a named entity manager. + * + * This method is useful when an entity manager has been closed + * because of a rollbacked transaction AND when you think that + * it makes sense to get a new one to replace the closed one. + * + * Be warned that you will get a brand new entity manager as + * the existing one is not useable anymore. This means that any + * other object with a dependency on this entity manager will + * hold an obsolete reference. You can inject the registry instead + * to avoid this problem. + * + * @param string $name The entity manager name (null for the default one) + * + * @return EntityManager + */ + public function resetEntityManager($name = null) + { + $this->resetManager($name); + } + + /** + * Resolves a registered namespace alias to the full namespace. + * + * This method looks for the alias in all registered entity managers. + * + * @param string $alias The alias + * + * @return string The full namespace + */ + public function getEntityNamespace($alias) + { + return $this->getAliasNamespace($alias); + } + + /** + * Resolves a registered namespace alias to the full namespace. + * + * This method looks for the alias in all registered entity managers. + * + * @param string $alias The alias + * + * @return string The full namespace + * + * @see Configuration::getEntityNamespace + */ + public function getAliasNamespace($alias) + { + foreach (array_keys($this->getManagers()) as $name) { + try { + return $this->getManager($name)->getConfiguration()->getEntityNamespace($alias); + } catch (ORMException $e) { + } + } + + throw ORMException::unknownEntityNamespace($alias); + } + + /** + * Gets all connection names. + * + * @return array An array of connection names + */ + public function getEntityManagerNames() + { + return $this->getManagerNames(); + } + + /** + * Gets the entity manager associated with a given class. + * + * @param string $class A Doctrine Entity class name + * + * @return EntityManager|null + */ + public function getEntityManagerForClass($class) + { + return $this->getManagerForClass($class); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/config/dbal.xml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/config/dbal.xml new file mode 100644 index 0000000..ff85087 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/config/dbal.xml @@ -0,0 +1,62 @@ + + + + + + Doctrine\DBAL\Logging\LoggerChain + Doctrine\DBAL\Logging\DebugStack + Symfony\Bridge\Doctrine\Logger\DbalLogger + Doctrine\DBAL\Configuration + Symfony\Bridge\Doctrine\DataCollector\DoctrineDataCollector + Symfony\Bridge\Doctrine\ContainerAwareEventManager + Doctrine\Bundle\DoctrineBundle\ConnectionFactory + Doctrine\DBAL\Event\Listeners\MysqlSessionInit + Doctrine\DBAL\Event\Listeners\OracleSessionInit + Doctrine\Bundle\DoctrineBundle\Registry + + + + + + + + + + + + + + + + + + + + + + + + + + %doctrine.dbal.connection_factory.types% + + + + + + + + + + + + + %doctrine.connections% + %doctrine.entity_managers% + %doctrine.default_connection% + %doctrine.default_entity_manager% + + + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/config/orm.xml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/config/orm.xml new file mode 100644 index 0000000..211fe7a --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/config/orm.xml @@ -0,0 +1,97 @@ + + + + + + Doctrine\ORM\Configuration + Doctrine\ORM\EntityManager + Doctrine\Bundle\DoctrineBundle\ManagerConfigurator + + + Doctrine\Common\Cache\ArrayCache + Doctrine\Common\Cache\ApcCache + Doctrine\Common\Cache\MemcacheCache + localhost + 11211 + Memcache + Doctrine\Common\Cache\MemcachedCache + localhost + 11211 + Memcached + Doctrine\Common\Cache\XcacheCache + + + Doctrine\ORM\Mapping\Driver\DriverChain + Doctrine\ORM\Mapping\Driver\AnnotationDriver + Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver + Doctrine\ORM\Mapping\Driver\SimplifiedYamlDriver + Doctrine\ORM\Mapping\Driver\PHPDriver + Doctrine\ORM\Mapping\Driver\StaticPHPDriver + + + Symfony\Bridge\Doctrine\CacheWarmer\ProxyCacheWarmer + + + Symfony\Bridge\Doctrine\Form\DoctrineOrmTypeGuesser + + + Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator + Symfony\Bridge\Doctrine\Validator\DoctrineInitializer + + + Symfony\Bridge\Doctrine\Security\User\EntityUserProvider + + + Doctrine\ORM\Tools\ResolveTargetEntityListener + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/config/schema/doctrine-1.0.xsd b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/config/schema/doctrine-1.0.xsd new file mode 100644 index 0000000..76170b9 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/config/schema/doctrine-1.0.xsd @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/doc/configuration.rst b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/doc/configuration.rst new file mode 100644 index 0000000..088eb49 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/doc/configuration.rst @@ -0,0 +1,305 @@ +.. index:: + single: Doctrine; ORM Configuration Reference + single: Configuration Reference; Doctrine ORM + +Configuration Reference +======================= + +.. configuration-block:: + + .. code-block:: yaml + + doctrine: + dbal: + default_connection: default + connections: + default: + dbname: database + host: localhost + port: 1234 + user: user + password: secret + driver: pdo_mysql + driver_class: MyNamespace\MyDriverImpl + options: + foo: bar + path: %kernel.data_dir%/data.sqlite + memory: true + unix_socket: /tmp/mysql.sock + wrapper_class: MyDoctrineDbalConnectionWrapper + charset: UTF8 + logging: %kernel.debug% + platform_service: MyOwnDatabasePlatformService + mapping_types: + enum: string + conn1: + # ... + types: + custom: Acme\HelloBundle\MyCustomType + orm: + auto_generate_proxy_classes: false + proxy_namespace: Proxies + proxy_dir: %kernel.cache_dir%/doctrine/orm/Proxies + default_entity_manager: default # The first defined is used if not set + entity_managers: + default: + # The name of a DBAL connection (the one marked as default is used if not set) + connection: conn1 + mappings: # Required + AcmeHelloBundle: ~ + class_metadata_factory_name: Doctrine\ORM\Mapping\ClassMetadataFactory + # All cache drivers have to be array, apc, xcache or memcache + metadata_cache_driver: array + query_cache_driver: array + result_cache_driver: + type: memcache + host: localhost + port: 11211 + instance_class: Memcache + class: Doctrine\Common\Cache\MemcacheCache + dql: + string_functions: + test_string: Acme\HelloBundle\DQL\StringFunction + numeric_functions: + test_numeric: Acme\HelloBundle\DQL\NumericFunction + datetime_functions: + test_datetime: Acme\HelloBundle\DQL\DatetimeFunction + em2: + # ... + + .. code-block:: xml + + + + + + + bar + string + + + Acme\HelloBundle\MyCustomType + + + + + + + + Acme\HelloBundle\DQL\NumericFunction + + + + + + + +Configuration Overview +---------------------- + +This following configuration example shows all the configuration defaults that +the ORM resolves to: + +.. code-block:: yaml + + doctrine: + orm: + auto_mapping: true + # the standard distribution overrides this to be true in debug, false otherwise + auto_generate_proxy_classes: false + proxy_namespace: Proxies + proxy_dir: %kernel.cache_dir%/doctrine/orm/Proxies + default_entity_manager: default + metadata_cache_driver: array + query_cache_driver: array + result_cache_driver: array + +There are lots of other configuration options that you can use to overwrite +certain classes, but those are for very advanced use-cases only. + +Caching Drivers +~~~~~~~~~~~~~~~ + +For the caching drivers you can specify the values "array", "apc", "memcache" +or "xcache". + +The following example shows an overview of the caching configurations: + +.. code-block:: yaml + + doctrine: + orm: + auto_mapping: true + metadata_cache_driver: apc + query_cache_driver: xcache + result_cache_driver: + type: memcache + host: localhost + port: 11211 + instance_class: Memcache + +Mapping Configuration +~~~~~~~~~~~~~~~~~~~~~ + +Explicit definition of all the mapped entities is the only necessary +configuration for the ORM and there are several configuration options that you +can control. The following configuration options exist for a mapping: + +* ``type`` One of ``annotation``, ``xml``, ``yml``, ``php`` or ``staticphp``. + This specifies which type of metadata type your mapping uses. + +* ``dir`` Path to the mapping or entity files (depending on the driver). If + this path is relative it is assumed to be relative to the bundle root. This + only works if the name of your mapping is a bundle name. If you want to use + this option to specify absolute paths you should prefix the path with the + kernel parameters that exist in the DIC (for example %kernel.root_dir%). + +* ``prefix`` A common namespace prefix that all entities of this mapping + share. This prefix should never conflict with prefixes of other defined + mappings otherwise some of your entities cannot be found by Doctrine. This + option defaults to the bundle namespace + ``Entity``, for example for an + application bundle called ``AcmeHelloBundle`` prefix would be + ``Acme\HelloBundle\Entity``. + +* ``alias`` Doctrine offers a way to alias entity namespaces to simpler, + shorter names to be used in DQL queries or for Repository access. When using + a bundle the alias defaults to the bundle name. + +* ``is_bundle`` This option is a derived value from ``dir`` and by default is + set to true if dir is relative proved by a ``file_exists()`` check that + returns false. It is false if the existence check returns true. In this case + an absolute path was specified and the metadata files are most likely in a + directory outside of a bundle. + +.. index:: + single: Configuration; Doctrine DBAL + single: Doctrine; DBAL configuration + +.. _`reference-dbal-configuration`: + +Doctrine DBAL Configuration +--------------------------- + +.. note:: + + DoctrineBundle supports all parameters that default Doctrine drivers + accept, converted to the XML or YAML naming standards that Symfony + enforces. See the Doctrine `DBAL documentation`_ for more information. + +Besides default Doctrine options, there are some Symfony-related ones that you +can configure. The following block shows all possible configuration keys: + +.. configuration-block:: + + .. code-block:: yaml + + doctrine: + dbal: + dbname: database + host: localhost + port: 1234 + user: user + password: secret + driver: pdo_mysql + driver_class: MyNamespace\MyDriverImpl + options: + foo: bar + path: %kernel.data_dir%/data.sqlite + memory: true + unix_socket: /tmp/mysql.sock + wrapper_class: MyDoctrineDbalConnectionWrapper + charset: UTF8 + logging: %kernel.debug% + platform_service: MyOwnDatabasePlatformService + mapping_types: + enum: string + types: + custom: Acme\HelloBundle\MyCustomType + + .. code-block:: xml + + + + + + + bar + string + Acme\HelloBundle\MyCustomType + + + +If you want to configure multiple connections in YAML, put them under the +``connections`` key and give them a unique name: + +.. code-block:: yaml + + doctrine: + dbal: + default_connection: default + connections: + default: + dbname: Symfony2 + user: root + password: null + host: localhost + customer: + dbname: customer + user: root + password: null + host: localhost + +The ``database_connection`` service always refers to the *default* connection, +which is the first one defined or the one configured via the +``default_connection`` parameter. + +Each connection is also accessible via the ``doctrine.dbal.[name]_connection`` +service where ``[name]`` if the name of the connection. + +.. _DBAL documentation: http://www.doctrine-project.org/docs/dbal/2.0/en diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/doc/installation.rst b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/doc/installation.rst new file mode 100644 index 0000000..1ee5a31 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/doc/installation.rst @@ -0,0 +1,43 @@ +Doctrine Bundle +=============== + +Doctrine DBAL & ORM Bundle for the Symfony Framework. + +Because Symfony 2 does not want to force or suggest a specific persistence solutions on the users +this bundle was removed from the core of the Symfony 2 framework. Doctrine2 will still be a major player +in the Symfony world and the bundle is maintained by developers in the Doctrine and Symfony communities. + +IMPORTANT: This bundle is developed for Symfony 2.1 and up. For Symfony 2.0 applications the DoctrineBundle +is still shipped with the core Symfony repository. + +Installation +------------ + +1. Old deps and bin/vendors way + +Add the following snippets to "deps" files: + +.. code-block:: + + [doctrine-mongodb] + git=http://github.com/doctrine/dbal.git + + [doctrine-mongodb-odm] + git=http://github.com/doctrine/doctrine2.git + + [DoctrineBundle] + git=http://github.com/doctrine/DoctrineBundle.git + target=/bundles/Doctrine/Bundle/DoctrineBundle + +2. Composer + +Add the following dependencies to your projects composer.json file: + +.. code-block:: + + "require": { + # .. + "doctrine/doctrine-bundle": ">=2.1" + # .. + } + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/views/Collector/db.html.twig b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/views/Collector/db.html.twig new file mode 100644 index 0000000..fa2aed3 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/views/Collector/db.html.twig @@ -0,0 +1,122 @@ +{% extends app.request.isXmlHttpRequest ? 'WebProfilerBundle:Profiler:ajax_layout.html.twig' : 'WebProfilerBundle:Profiler:layout.html.twig' %} + +{% block toolbar %} + {% set icon %} + Database + {{ collector.querycount }} + in {{ '%0.2f'|format(collector.time * 1000) }} ms + {% endset %} + {% set text %} +
    + DB Queries + {{ collector.querycount }} +
    +
    + Query time + {{ '%0.2f'|format(collector.time * 1000) }} ms +
    + {% endset %} + {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %} +{% endblock %} + +{% block menu %} + + + Doctrine + + {{ collector.querycount }} + {{ '%0.0f'|format(collector.time * 1000) }} ms + + +{% endblock %} + +{% block panel %} + {% if 'explain' == page %} + {% render 'DoctrineBundle:Profiler:explain' with { + 'token': token, + 'panel': 'db', + 'connectionName': app.request.query.get('connection'), + 'query': app.request.query.get('query') + } %} + {% else %} + {{ block('queries') }} + {% endif %} +{% endblock %} + +{% block queries %} +

    Queries

    + + {% for connection, queries in collector.queries %} +

    Connection {{ connection }}

    + {% if queries is empty %} +

    + No queries. +

    + {% else %} +
      + {% for i, query in queries %} +
    • +
      + {% if query.explainable %} + + + + - + + {% endif %} + {{ query.sql }} +
      + + Parameters: {{ query.params|yaml_encode }}
      + Time: {{ '%0.2f'|format(query.executionMS * 1000) }} ms +
      + {% if query.explainable %} +
      + {% endif %} +
    • + {% endfor %} +
    + {% endif %} + {% endfor %} + +

    Database Connections

    + + {% if collector.connections %} + {% include 'WebProfilerBundle:Profiler:table.html.twig' with {data: collector.connections} only %} + {% else %} +

    + No connections. +

    + {% endif %} + +

    Entity Managers

    + + {% if collector.managers %} + {% include 'WebProfilerBundle:Profiler:table.html.twig' with {data: collector.managers} only %} + {% else %} +

    + No entity managers. +

    + {% endif %} + + +{% endblock %} \ No newline at end of file diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/views/Collector/explain.html.twig b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/views/Collector/explain.html.twig new file mode 100644 index 0000000..22af37f --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Resources/views/Collector/explain.html.twig @@ -0,0 +1,20 @@ +Explanation: + + + + + {% for label in data[0]|keys %} + + {% endfor %} + + + + {% for row in data %} + + {% for item in row %} + + {% endfor %} + + {% endfor %} + +
    {{ label }}
    {{ item }}
    \ No newline at end of file diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/BundleTest.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/BundleTest.php new file mode 100644 index 0000000..94eaccd --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/BundleTest.php @@ -0,0 +1,47 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Tests; + +use Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass\DoctrineValidationPass; +use Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass\RegisterEventListenersAndSubscribersPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Doctrine\Bundle\DoctrineBundle\DoctrineBundle; + +class BundleTest extends \PHPUnit_Framework_TestCase +{ + public function testBuildCompilerPasses() + { + $container = new ContainerBuilder(); + $bundle = new DoctrineBundle(); + $bundle->build($container); + + $config = $container->getCompilerPassConfig(); + $passes = $config->getBeforeOptimizationPasses(); + + $foundEventListener = false; + $foundValidation = false; + + foreach ($passes as $pass) { + if ($pass instanceof RegisterEventListenersAndSubscribersPass) { + $foundEventListener = true; + } elseif ($pass instanceof DoctrineValidationPass) { + $foundValidation = true; + } + } + + $this->assertTrue($foundEventListener, 'RegisterEventListenersAndSubcribersPass was not found'); + $this->assertTrue($foundValidation, 'DoctrineValidationPass was not found'); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/ContainerTest.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/ContainerTest.php new file mode 100644 index 0000000..83de54c --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/ContainerTest.php @@ -0,0 +1,59 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Tests; + +use Doctrine\DBAL\Types\Type; + +class ContainerTest extends TestCase +{ + protected function setUp() + { + parent::setUp(); + + if (!class_exists('Doctrine\\ORM\\Version')) { + $this->markTestSkipped('Doctrine ORM is not available.'); + } + } + + public function testContainer() + { + $container = $this->createYamlBundleTestContainer(); + + $this->assertInstanceOf('Symfony\Bridge\Doctrine\Logger\DbalLogger', $container->get('doctrine.dbal.logger')); + $this->assertInstanceOf('Symfony\Bridge\Doctrine\DataCollector\DoctrineDataCollector', $container->get('data_collector.doctrine')); + $this->assertInstanceOf('Doctrine\DBAL\Configuration', $container->get('doctrine.dbal.default_connection.configuration')); + $this->assertInstanceOf('Doctrine\Common\EventManager', $container->get('doctrine.dbal.default_connection.event_manager')); + $this->assertInstanceOf('Doctrine\DBAL\Connection', $container->get('doctrine.dbal.default_connection')); + $this->assertInstanceOf('Doctrine\Common\Annotations\Reader', $container->get('doctrine.orm.metadata.annotation_reader')); + $this->assertInstanceOf('Doctrine\ORM\Configuration', $container->get('doctrine.orm.default_configuration')); + $this->assertInstanceOf('Doctrine\ORM\Mapping\Driver\DriverChain', $container->get('doctrine.orm.default_metadata_driver')); + $this->assertInstanceOf('Doctrine\Common\Cache\ArrayCache', $container->get('doctrine.orm.default_metadata_cache')); + $this->assertInstanceOf('Doctrine\Common\Cache\ArrayCache', $container->get('doctrine.orm.default_query_cache')); + $this->assertInstanceOf('Doctrine\Common\Cache\ArrayCache', $container->get('doctrine.orm.default_result_cache')); + $this->assertInstanceOf('Doctrine\ORM\EntityManager', $container->get('doctrine.orm.default_entity_manager')); + $this->assertInstanceOf('Doctrine\DBAL\Connection', $container->get('database_connection')); + $this->assertInstanceOf('Doctrine\ORM\EntityManager', $container->get('doctrine.orm.entity_manager')); + $this->assertInstanceOf('Doctrine\Common\EventManager', $container->get('doctrine.orm.default_entity_manager.event_manager')); + $this->assertInstanceOf('Doctrine\Common\EventManager', $container->get('doctrine.dbal.event_manager')); + $this->assertInstanceOf('Doctrine\DBAL\Event\Listeners\MysqlSessionInit', $container->get('doctrine.dbal.default_connection.events.mysqlsessioninit')); + $this->assertInstanceOf('Symfony\Bridge\Doctrine\CacheWarmer\ProxyCacheWarmer', $container->get('doctrine.orm.proxy_cache_warmer')); + $this->assertInstanceOf('Doctrine\Common\Persistence\ManagerRegistry', $container->get('doctrine')); + $this->assertInstanceOf('Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator', $container->get('doctrine.orm.validator.unique')); + + $this->assertSame($container->get('my.platform'), $container->get('doctrine.dbal.default_connection')->getDatabasePlatform()); + + $this->assertTrue(Type::hasType('test')); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php new file mode 100644 index 0000000..b200fc3 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php @@ -0,0 +1,854 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection; + +use Doctrine\Bundle\DoctrineBundle\Tests\TestCase; +use Doctrine\Bundle\DoctrineBundle\DependencyInjection\DoctrineExtension; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Compiler\ResolveDefinitionTemplatesPass; +use Symfony\Component\Config\FileLocator; + +abstract class AbstractDoctrineExtensionTest extends \PHPUnit_Framework_TestCase +{ + abstract protected function loadFromFile(ContainerBuilder $container, $file); + + public function testDbalOverrideDefaultConnection() + { + $container = $this->getContainer(); + $loader = new DoctrineExtension(); + + $loader->load(array(array(), array('dbal' => array('default_connection' => 'foo')), array()), $container); + + // doctrine.dbal.default_connection + $this->assertEquals('%doctrine.default_connection%', $container->getDefinition('doctrine')->getArgument(3), '->load() overrides existing configuration options'); + $this->assertEquals('foo', $container->getParameter('doctrine.default_connection'), '->load() overrides existing configuration options'); + + } + + public function testDbalLoad() + { + $container = $this->getContainer(); + $loader = new DoctrineExtension(); + + $loader->load(array(array('dbal' => array('connections' => array('default' => array('password' => 'foo')))), array(), array('dbal' => array('default_connection' => 'foo')), array()), $container); + + $config = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0); + + $this->assertEquals('foo', $config['password']); + $this->assertEquals('root', $config['user']); + } + + public function testDbalLoadFromXmlMultipleConnections() + { + $container = $this->getContainer(); + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + + $this->loadFromFile($container, 'dbal_service_multiple_connections'); + + $this->compileContainer($container); + + // doctrine.dbal.mysql_connection + $config = $container->getDefinition('doctrine.dbal.mysql_connection')->getArgument(0); + + $this->assertEquals('mysql_s3cr3t', $config['password']); + $this->assertEquals('mysql_user', $config['user']); + $this->assertEquals('mysql_db', $config['dbname']); + $this->assertEquals('/path/to/mysqld.sock', $config['unix_socket']); + + // doctrine.dbal.sqlite_connection + $config = $container->getDefinition('doctrine.dbal.sqlite_connection')->getArgument(0); + $this->assertArrayHasKey('memory', $config); + + // doctrine.dbal.oci8_connection + $config = $container->getDefinition('doctrine.dbal.oci_connection')->getArgument(0); + $this->assertArrayHasKey('charset', $config); + } + + public function testDbalLoadFromXmlSingleConnections() + { + $container = $this->getContainer(); + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + + $this->loadFromFile($container, 'dbal_service_single_connection'); + + $this->compileContainer($container); + + // doctrine.dbal.mysql_connection + $config = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0); + + $this->assertEquals('mysql_s3cr3t', $config['password']); + $this->assertEquals('mysql_user', $config['user']); + $this->assertEquals('mysql_db', $config['dbname']); + $this->assertEquals('/path/to/mysqld.sock', $config['unix_socket']); + } + + public function testDbalLoadSingleMasterSlaveConnection() + { + $container = $this->getContainer(); + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + + $this->loadFromFile($container, 'dbal_service_single_master_slave_connection'); + + $this->compileContainer($container); + + // doctrine.dbal.mysql_connection + $param = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0); + + $this->assertEquals('Doctrine\\DBAL\\Connections\\MasterSlaveConnection', $param['wrapperClass']); + $this->assertEquals( + array('user' => 'mysql_user', 'password' => 'mysql_s3cr3t', 'port' => null, 'dbname' => 'mysql_db', 'host' => 'localhost', 'unix_socket' => '/path/to/mysqld.sock'), + $param['master'] + ); + $this->assertEquals( + array( + 'user' => 'slave_user', 'password' => 'slave_s3cr3t', 'port' => null, 'dbname' => 'slave_db', + 'host' => 'localhost', 'unix_socket' => '/path/to/mysqld_slave.sock' + ), + $param['slaves']['slave1'] + ); + } + + public function testDependencyInjectionConfigurationDefaults() + { + $container = $this->getContainer(); + $loader = new DoctrineExtension(); + + $loader->load(array(array('dbal' => array('connections' => array('default' => array('password' => 'foo'))), 'orm' => array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('YamlBundle' => array())))))), $container); + + $this->assertFalse($container->getParameter('doctrine.orm.auto_generate_proxy_classes')); + $this->assertEquals('Doctrine\ORM\Configuration', $container->getParameter('doctrine.orm.configuration.class')); + $this->assertEquals('Doctrine\ORM\EntityManager', $container->getParameter('doctrine.orm.entity_manager.class')); + $this->assertEquals('Proxies', $container->getParameter('doctrine.orm.proxy_namespace')); + $this->assertEquals('Doctrine\Common\Cache\ArrayCache', $container->getParameter('doctrine.orm.cache.array.class')); + $this->assertEquals('Doctrine\Common\Cache\ApcCache', $container->getParameter('doctrine.orm.cache.apc.class')); + $this->assertEquals('Doctrine\Common\Cache\MemcacheCache', $container->getParameter('doctrine.orm.cache.memcache.class')); + $this->assertEquals('localhost', $container->getParameter('doctrine.orm.cache.memcache_host')); + $this->assertEquals('11211', $container->getParameter('doctrine.orm.cache.memcache_port')); + $this->assertEquals('Memcache', $container->getParameter('doctrine.orm.cache.memcache_instance.class')); + $this->assertEquals('Doctrine\Common\Cache\XcacheCache', $container->getParameter('doctrine.orm.cache.xcache.class')); + $this->assertEquals('Doctrine\ORM\Mapping\Driver\DriverChain', $container->getParameter('doctrine.orm.metadata.driver_chain.class')); + $this->assertEquals('Doctrine\ORM\Mapping\Driver\AnnotationDriver', $container->getParameter('doctrine.orm.metadata.annotation.class')); + $this->assertEquals('Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver', $container->getParameter('doctrine.orm.metadata.xml.class')); + $this->assertEquals('Doctrine\ORM\Mapping\Driver\SimplifiedYamlDriver', $container->getParameter('doctrine.orm.metadata.yml.class')); + + $config = array( + 'proxy_namespace' => 'MyProxies', + 'auto_generate_proxy_classes' => true, + 'default_entity_manager' => 'default', + 'entity_managers' => array( + 'default' => array( + 'mappings' => array('YamlBundle' => array()), + ) + ) + ); + + $container = $this->getContainer(); + $loader->load(array(array('dbal' => array('connections' => array('default' => array('password' => 'foo'))), 'orm' => $config)), $container); + $this->compileContainer($container); + + $definition = $container->getDefinition('doctrine.dbal.default_connection'); + + $args = $definition->getArguments(); + $this->assertEquals('pdo_mysql', $args[0]['driver']); + $this->assertEquals('localhost', $args[0]['host']); + $this->assertEquals('root', $args[0]['user']); + $this->assertEquals('doctrine.dbal.default_connection.configuration', (string) $args[1]); + $this->assertEquals('doctrine.dbal.default_connection.event_manager', (string) $args[2]); + + $definition = $container->getDefinition('doctrine.orm.default_entity_manager'); + $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass()); + $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getFactoryClass()); + $this->assertEquals('create', $definition->getFactoryMethod()); + + $this->assertEquals(array('default' => 'doctrine.orm.default_entity_manager'), $container->getParameter('doctrine.entity_managers'), "Set of the existing EntityManagers names is incorrect."); + $this->assertEquals('%doctrine.entity_managers%', $container->getDefinition('doctrine')->getArgument(2), "Set of the existing EntityManagers names is incorrect."); + + $arguments = $definition->getArguments(); + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]); + $this->assertEquals('doctrine.dbal.default_connection', (string) $arguments[0]); + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[1]); + $this->assertEquals('doctrine.orm.default_configuration', (string) $arguments[1]); + + $definition = $container->getDefinition('doctrine.orm.default_configuration'); + $calls = array_values($definition->getMethodCalls()); + $this->assertEquals(array('YamlBundle' => 'Fixtures\Bundles\YamlBundle\Entity'), $calls[0][1][0]); + $this->assertEquals('doctrine.orm.default_metadata_cache', (string) $calls[1][1][0]); + $this->assertEquals('doctrine.orm.default_query_cache', (string) $calls[2][1][0]); + $this->assertEquals('doctrine.orm.default_result_cache', (string) $calls[3][1][0]); + + $definition = $container->getDefinition('doctrine.orm.default_metadata_cache'); + $this->assertEquals('%doctrine.orm.cache.array.class%', $definition->getClass()); + + $definition = $container->getDefinition('doctrine.orm.default_query_cache'); + $this->assertEquals('%doctrine.orm.cache.array.class%', $definition->getClass()); + + $definition = $container->getDefinition('doctrine.orm.default_result_cache'); + $this->assertEquals('%doctrine.orm.cache.array.class%', $definition->getClass()); + } + + public function testSingleEntityManagerConfiguration() + { + $container = $this->getContainer(); + $loader = new DoctrineExtension(); + + $loader->load(array(array('dbal' => array('connections' => array('default' => array('password' => 'foo'))), 'orm' => array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('YamlBundle' => array())))))), $container); + $this->compileContainer($container); + + $definition = $container->getDefinition('doctrine.dbal.default_connection'); + + $definition = $container->getDefinition('doctrine.orm.default_entity_manager'); + $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass()); + $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getFactoryClass()); + $this->assertEquals('create', $definition->getFactoryMethod()); + + $this->assertDICConstructorArguments($definition, array( + new Reference('doctrine.dbal.default_connection'), new Reference('doctrine.orm.default_configuration') + )); + } + + public function testLoadSimpleSingleConnection() + { + $container = $this->getContainer(); + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + + $this->loadFromFile($container, 'orm_service_simple_single_entity_manager'); + + $this->compileContainer($container); + + $definition = $container->getDefinition('doctrine.dbal.default_connection'); + + $this->assertDICConstructorArguments($definition, array( + array( + 'dbname' => 'db', + 'host' => 'localhost', + 'port' => null, + 'user' => 'root', + 'password' => null, + 'driver' => 'pdo_mysql', + 'driverOptions' => array(), + ), + new Reference('doctrine.dbal.default_connection.configuration'), + new Reference('doctrine.dbal.default_connection.event_manager'), + array(), + )); + + $definition = $container->getDefinition('doctrine.orm.default_entity_manager'); + $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass()); + $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getFactoryClass()); + $this->assertEquals('create', $definition->getFactoryMethod()); + + $this->assertDICConstructorArguments($definition, array( + new Reference('doctrine.dbal.default_connection'), new Reference('doctrine.orm.default_configuration') + )); + } + + public function testLoadSingleConnection() + { + $container = $this->getContainer(); + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + + $this->loadFromFile($container, 'orm_service_single_entity_manager'); + + $this->compileContainer($container); + + $definition = $container->getDefinition('doctrine.dbal.default_connection'); + + $this->assertDICConstructorArguments($definition, array( + array( + 'host' => 'localhost', + 'driver' => 'pdo_sqlite', + 'driverOptions' => array(), + 'user' => 'sqlite_user', + 'port' => null, + 'password' => 'sqlite_s3cr3t', + 'dbname' => 'sqlite_db', + 'memory' => true, + ), + new Reference('doctrine.dbal.default_connection.configuration'), + new Reference('doctrine.dbal.default_connection.event_manager'), + array(), + )); + + $definition = $container->getDefinition('doctrine.orm.default_entity_manager'); + $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass()); + $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getFactoryClass()); + $this->assertEquals('create', $definition->getFactoryMethod()); + + $this->assertDICConstructorArguments($definition, array( + new Reference('doctrine.dbal.default_connection'), new Reference('doctrine.orm.default_configuration') + )); + + $configDef = $container->getDefinition('doctrine.orm.default_configuration'); + $this->assertDICDefinitionMethodCallOnce($configDef, 'setDefaultRepositoryClassName', array('Acme\Doctrine\Repository')); + } + + public function testLoadMultipleConnections() + { + $container = $this->getContainer(); + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + + $this->loadFromFile($container, 'orm_service_multiple_entity_managers'); + + $this->compileContainer($container); + + $definition = $container->getDefinition('doctrine.dbal.conn1_connection'); + + $args = $definition->getArguments(); + $this->assertEquals('pdo_sqlite', $args[0]['driver']); + $this->assertEquals('localhost', $args[0]['host']); + $this->assertEquals('sqlite_user', $args[0]['user']); + $this->assertEquals('doctrine.dbal.conn1_connection.configuration', (string) $args[1]); + $this->assertEquals('doctrine.dbal.conn1_connection.event_manager', (string) $args[2]); + + $this->assertEquals('doctrine.orm.em2_entity_manager', (string) $container->getAlias('doctrine.orm.entity_manager')); + + $definition = $container->getDefinition('doctrine.orm.em1_entity_manager'); + $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass()); + $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getFactoryClass()); + $this->assertEquals('create', $definition->getFactoryMethod()); + + $arguments = $definition->getArguments(); + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]); + $this->assertEquals('doctrine.dbal.conn1_connection', (string) $arguments[0]); + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[1]); + $this->assertEquals('doctrine.orm.em1_configuration', (string) $arguments[1]); + + $definition = $container->getDefinition('doctrine.dbal.conn2_connection'); + + $args = $definition->getArguments(); + $this->assertEquals('pdo_sqlite', $args[0]['driver']); + $this->assertEquals('localhost', $args[0]['host']); + $this->assertEquals('sqlite_user', $args[0]['user']); + $this->assertEquals('doctrine.dbal.conn2_connection.configuration', (string) $args[1]); + $this->assertEquals('doctrine.dbal.conn2_connection.event_manager', (string) $args[2]); + + $definition = $container->getDefinition('doctrine.orm.em2_entity_manager'); + $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass()); + $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getFactoryClass()); + $this->assertEquals('create', $definition->getFactoryMethod()); + + $arguments = $definition->getArguments(); + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]); + $this->assertEquals('doctrine.dbal.conn2_connection', (string) $arguments[0]); + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[1]); + $this->assertEquals('doctrine.orm.em2_configuration', (string) $arguments[1]); + + $definition = $container->getDefinition('doctrine.orm.em1_metadata_cache'); + $this->assertEquals('%doctrine.orm.cache.xcache.class%', $definition->getClass()); + + $definition = $container->getDefinition('doctrine.orm.em1_query_cache'); + $this->assertEquals('%doctrine.orm.cache.array.class%', $definition->getClass()); + + $definition = $container->getDefinition('doctrine.orm.em1_result_cache'); + $this->assertEquals('%doctrine.orm.cache.array.class%', $definition->getClass()); + } + + public function testLoadLogging() + { + $container = $this->getContainer(); + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + + $this->loadFromFile($container, 'dbal_logging'); + + $this->compileContainer($container); + + $definition = $container->getDefinition('doctrine.dbal.log_connection.configuration'); + $this->assertDICDefinitionMethodCallOnce($definition, 'setSQLLogger', array(new Reference('doctrine.dbal.logger'))); + + $definition = $container->getDefinition('doctrine.dbal.profile_connection.configuration'); + $this->assertDICDefinitionMethodCallOnce($definition, 'setSQLLogger', array(new Reference('doctrine.dbal.logger.chain.profile'))); + + $definition = $container->getDefinition('doctrine.dbal.both_connection.configuration'); + $this->assertDICDefinitionMethodCallOnce($definition, 'setSQLLogger', array(new Reference('doctrine.dbal.logger.chain.both'))); + } + + public function testBundleEntityAliases() + { + $container = $this->getContainer(); + $loader = new DoctrineExtension(); + + $config = $this->getConnectionConfig(); + $config['orm'] = array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('YamlBundle' => array())))); + $loader->load(array($config), $container); + + $definition = $container->getDefinition('doctrine.orm.default_configuration'); + $this->assertDICDefinitionMethodCallOnce($definition, 'setEntityNamespaces', + array(array('YamlBundle' => 'Fixtures\Bundles\YamlBundle\Entity')) + ); + } + + public function testOverwriteEntityAliases() + { + $container = $this->getContainer(); + $loader = new DoctrineExtension(); + + $config = $this->getConnectionConfig(); + $config['orm'] = array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('YamlBundle' => array('alias' => 'yml'))))); + $loader->load(array($config), $container); + + $definition = $container->getDefinition('doctrine.orm.default_configuration'); + $this->assertDICDefinitionMethodCallOnce($definition, 'setEntityNamespaces', + array(array('yml' => 'Fixtures\Bundles\YamlBundle\Entity')) + ); + } + + public function testYamlBundleMappingDetection() + { + $container = $this->getContainer('YamlBundle'); + $loader = new DoctrineExtension(); + + $config = $this->getConnectionConfig(); + $config['orm'] = array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('YamlBundle' => array())))); + $loader->load(array($config), $container); + + $definition = $container->getDefinition('doctrine.orm.default_metadata_driver'); + $this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', array( + new Reference('doctrine.orm.default_yml_metadata_driver'), + 'Fixtures\Bundles\YamlBundle\Entity' + )); + } + + public function testXmlBundleMappingDetection() + { + $container = $this->getContainer('XmlBundle'); + $loader = new DoctrineExtension(); + + $config = $this->getConnectionConfig(); + $config['orm'] = array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('XmlBundle' => array())))); + $loader->load(array($config), $container); + + $definition = $container->getDefinition('doctrine.orm.default_metadata_driver'); + $this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', array( + new Reference('doctrine.orm.default_xml_metadata_driver'), + 'Fixtures\Bundles\XmlBundle\Entity' + )); + } + + public function testAnnotationsBundleMappingDetection() + { + $container = $this->getContainer('AnnotationsBundle'); + $loader = new DoctrineExtension(); + + $config = $this->getConnectionConfig(); + $config['orm'] = array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('AnnotationsBundle' => array())))); + $loader->load(array($config), $container); + + $definition = $container->getDefinition('doctrine.orm.default_metadata_driver'); + $this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', array( + new Reference('doctrine.orm.default_annotation_metadata_driver'), + 'Fixtures\Bundles\AnnotationsBundle\Entity' + )); + } + + public function testOrmMergeConfigs() + { + $container = $this->getContainer(array('XmlBundle', 'AnnotationsBundle')); + $loader = new DoctrineExtension(); + + $config1 = $this->getConnectionConfig(); + $config1['orm'] = array( + 'auto_generate_proxy_classes' => true, + 'default_entity_manager' => 'default', + 'entity_managers' => array( + 'default' => array('mappings' => array('AnnotationsBundle' => array())) + )); + $config2 = $this->getConnectionConfig(); + $config2['orm'] = array( + 'auto_generate_proxy_classes' => false, + 'default_entity_manager' => 'default', + 'entity_managers' => array( + 'default' => array('mappings' => array('XmlBundle' => array())) + )); + $loader->load(array($config1, $config2), $container); + + $definition = $container->getDefinition('doctrine.orm.default_metadata_driver'); + $this->assertDICDefinitionMethodCallAt(0, $definition, 'addDriver', array( + new Reference('doctrine.orm.default_annotation_metadata_driver'), + 'Fixtures\Bundles\AnnotationsBundle\Entity' + )); + $this->assertDICDefinitionMethodCallAt(1, $definition, 'addDriver', array( + new Reference('doctrine.orm.default_xml_metadata_driver'), + 'Fixtures\Bundles\XmlBundle\Entity' + )); + + $configDef = $container->getDefinition('doctrine.orm.default_configuration'); + $this->assertDICDefinitionMethodCallOnce($configDef, 'setAutoGenerateProxyClasses'); + + $calls = $configDef->getMethodCalls(); + foreach ($calls as $call) { + if ($call[0] == 'setAutoGenerateProxyClasses') { + $this->assertFalse($container->getParameterBag()->resolveValue($call[1][0])); + break; + } + } + } + + public function testEntityManagerMetadataCacheDriverConfiguration() + { + $container = $this->getContainer(); + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + + $this->loadFromFile($container, 'orm_service_multiple_entity_managers'); + + $this->compileContainer($container); + + $definition = $container->getDefinition('doctrine.orm.em1_metadata_cache'); + $this->assertDICDefinitionClass($definition, '%doctrine.orm.cache.xcache.class%'); + + $definition = $container->getDefinition('doctrine.orm.em2_metadata_cache'); + $this->assertDICDefinitionClass($definition, '%doctrine.orm.cache.apc.class%'); + } + + public function testEntityManagerMemcacheMetadataCacheDriverConfiguration() + { + $container = $this->getContainer(); + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + + $this->loadFromFile($container, 'orm_service_simple_single_entity_manager'); + + $this->compileContainer($container); + + $definition = $container->getDefinition('doctrine.orm.default_metadata_cache'); + $this->assertDICDefinitionClass($definition, 'Doctrine\Common\Cache\MemcacheCache'); + $this->assertDICDefinitionMethodCallOnce($definition, 'setMemcache', + array(new Reference('doctrine.orm.default_memcache_instance')) + ); + + $definition = $container->getDefinition('doctrine.orm.default_memcache_instance'); + $this->assertDICDefinitionClass($definition, 'Memcache'); + $this->assertDICDefinitionMethodCallOnce($definition, 'connect', array( + 'localhost', '11211' + )); + } + + public function testDependencyInjectionImportsOverrideDefaults() + { + $container = $this->getContainer(); + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + + $this->loadFromFile($container, 'orm_imports'); + + $this->compileContainer($container); + + $cacheDefinition = $container->getDefinition('doctrine.orm.default_metadata_cache'); + $this->assertEquals('%doctrine.orm.cache.apc.class%', $cacheDefinition->getClass()); + + $configDefinition = $container->getDefinition('doctrine.orm.default_configuration'); + $this->assertDICDefinitionMethodCallOnce($configDefinition, 'setAutoGenerateProxyClasses', array('%doctrine.orm.auto_generate_proxy_classes%')); + } + + public function testSingleEntityManagerMultipleMappingBundleDefinitions() + { + $container = $this->getContainer(array('YamlBundle', 'AnnotationsBundle', 'XmlBundle')); + + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + + $this->loadFromFile($container, 'orm_single_em_bundle_mappings'); + + $this->compileContainer($container); + + $definition = $container->getDefinition('doctrine.orm.default_metadata_driver'); + + $this->assertDICDefinitionMethodCallAt(0, $definition, 'addDriver', array( + new Reference('doctrine.orm.default_annotation_metadata_driver'), + 'Fixtures\Bundles\AnnotationsBundle\Entity' + )); + + $this->assertDICDefinitionMethodCallAt(1, $definition, 'addDriver', array( + new Reference('doctrine.orm.default_yml_metadata_driver'), + 'Fixtures\Bundles\YamlBundle\Entity' + )); + + $this->assertDICDefinitionMethodCallAt(2, $definition, 'addDriver', array( + new Reference('doctrine.orm.default_xml_metadata_driver'), + 'Fixtures\Bundles\XmlBundle' + )); + + $annDef = $container->getDefinition('doctrine.orm.default_annotation_metadata_driver'); + $this->assertDICConstructorArguments($annDef, array( + new Reference('doctrine.orm.metadata.annotation_reader'), + array(__DIR__ .DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'Bundles'.DIRECTORY_SEPARATOR.'AnnotationsBundle'.DIRECTORY_SEPARATOR.'Entity') + )); + + $ymlDef = $container->getDefinition('doctrine.orm.default_yml_metadata_driver'); + $this->assertDICConstructorArguments($ymlDef, array( + array(__DIR__ .DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'Bundles'.DIRECTORY_SEPARATOR.'YamlBundle'.DIRECTORY_SEPARATOR.'Resources'.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'doctrine' => 'Fixtures\Bundles\YamlBundle\Entity') + )); + + $xmlDef = $container->getDefinition('doctrine.orm.default_xml_metadata_driver'); + $this->assertDICConstructorArguments($xmlDef, array( + array(__DIR__ .DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'Bundles'.DIRECTORY_SEPARATOR.'XmlBundle'.DIRECTORY_SEPARATOR.'Resources'.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'doctrine' => 'Fixtures\Bundles\XmlBundle') + )); + } + + public function testMultipleEntityManagersMappingBundleDefinitions() + { + $container = $this->getContainer(array('YamlBundle', 'AnnotationsBundle', 'XmlBundle')); + + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + + $this->loadFromFile($container, 'orm_multiple_em_bundle_mappings'); + + $this->compileContainer($container); + + $this->assertEquals(array('em1' => 'doctrine.orm.em1_entity_manager', 'em2' => 'doctrine.orm.em2_entity_manager'), $container->getParameter('doctrine.entity_managers'), "Set of the existing EntityManagers names is incorrect."); + $this->assertEquals('%doctrine.entity_managers%', $container->getDefinition('doctrine')->getArgument(2), "Set of the existing EntityManagers names is incorrect."); + + $def1 = $container->getDefinition('doctrine.orm.em1_metadata_driver'); + $def2 = $container->getDefinition('doctrine.orm.em2_metadata_driver'); + + $this->assertDICDefinitionMethodCallAt(0, $def1, 'addDriver', array( + new Reference('doctrine.orm.em1_annotation_metadata_driver'), + 'Fixtures\Bundles\AnnotationsBundle\Entity' + )); + + $this->assertDICDefinitionMethodCallAt(0, $def2, 'addDriver', array( + new Reference('doctrine.orm.em2_yml_metadata_driver'), + 'Fixtures\Bundles\YamlBundle\Entity' + )); + + $this->assertDICDefinitionMethodCallAt(1, $def2, 'addDriver', array( + new Reference('doctrine.orm.em2_xml_metadata_driver'), + 'Fixtures\Bundles\XmlBundle' + )); + + $annDef = $container->getDefinition('doctrine.orm.em1_annotation_metadata_driver'); + $this->assertDICConstructorArguments($annDef, array( + new Reference('doctrine.orm.metadata.annotation_reader'), + array(__DIR__ .DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'Bundles'.DIRECTORY_SEPARATOR.'AnnotationsBundle'.DIRECTORY_SEPARATOR.'Entity') + )); + + $ymlDef = $container->getDefinition('doctrine.orm.em2_yml_metadata_driver'); + $this->assertDICConstructorArguments($ymlDef, array( + array(__DIR__ .DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'Bundles'.DIRECTORY_SEPARATOR.'YamlBundle'.DIRECTORY_SEPARATOR.'Resources'.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'doctrine' => 'Fixtures\Bundles\YamlBundle\Entity') + )); + + $xmlDef = $container->getDefinition('doctrine.orm.em2_xml_metadata_driver'); + $this->assertDICConstructorArguments($xmlDef, array( + array(__DIR__ .DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'Bundles'.DIRECTORY_SEPARATOR.'XmlBundle'.DIRECTORY_SEPARATOR.'Resources'.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'doctrine' => 'Fixtures\Bundles\XmlBundle') + )); + } + + public function testAnnotationsBundleMappingDetectionWithVendorNamespace() + { + $container = $this->getContainer('AnnotationsBundle', 'Vendor'); + $loader = new DoctrineExtension(); + + $config = $this->getConnectionConfig(); + $config['orm'] = array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('AnnotationsBundle' => array())))); + $loader->load(array($config), $container); + + $calls = $container->getDefinition('doctrine.orm.default_metadata_driver')->getMethodCalls(); + $this->assertEquals('doctrine.orm.default_annotation_metadata_driver', (string) $calls[0][1][0]); + $this->assertEquals('Fixtures\Bundles\Vendor\AnnotationsBundle\Entity', $calls[0][1][1]); + } + + public function testSetTypes() + { + $container = $this->getContainer(array('YamlBundle')); + + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + $this->loadFromFile($container, 'dbal_types'); + $this->compileContainer($container); + + $this->assertEquals( + array('test' => array('class' => 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestType', 'commented' => true)), + $container->getParameter('doctrine.dbal.connection_factory.types') + ); + $this->assertEquals('%doctrine.dbal.connection_factory.types%', $container->getDefinition('doctrine.dbal.connection_factory')->getArgument(0)); + } + + public function testSetCustomFunctions() + { + $container = $this->getContainer(array('YamlBundle')); + + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + $this->loadFromFile($container, 'orm_functions'); + $this->compileContainer($container); + + $definition = $container->getDefinition('doctrine.orm.default_configuration'); + $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomStringFunction', array('test_string', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction')); + $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomNumericFunction', array('test_numeric', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestNumericFunction')); + $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomDatetimeFunction', array('test_datetime', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestDatetimeFunction')); + } + + public function testSingleEMSetCustomFunctions() + { + $container = $this->getContainer(array('YamlBundle')); + + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + $this->loadFromFile($container, 'orm_single_em_dql_functions'); + $this->compileContainer($container); + + $definition = $container->getDefinition('doctrine.orm.default_configuration'); + $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomStringFunction', array('test_string', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction')); + } + + public function testAddCustomHydrationMode() + { + $container = $this->getContainer(array('YamlBundle')); + + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + $this->loadFromFile($container, 'orm_hydration_mode'); + $this->compileContainer($container); + + $definition = $container->getDefinition('doctrine.orm.default_configuration'); + $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomHydrationMode', array('test_hydrator', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestHydrator')); + } + + public function testAddFilter() + { + $container = $this->getContainer(array('YamlBundle')); + + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + + $this->loadFromFile($container, 'orm_filters'); + $this->compileContainer($container); + + $definition = $container->getDefinition('doctrine.orm.default_configuration'); + $this->assertDICDefinitionMethodCallOnce($definition, 'addFilter', array('soft_delete', 'Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\TestFilter')); + + $definition = $container->getDefinition('doctrine.orm.default_manager_configurator'); + $this->assertDICConstructorArguments($definition, array(array('soft_delete'))); + + // Let's create the instance to check the configurator work. + /** @var $entityManager \Doctrine\ORM\EntityManager */ + $entityManager = $container->get('doctrine.orm.entity_manager'); + $this->assertCount(1, $entityManager->getFilters()->getEnabledFilters()); + } + + public function testResolveTargetEntity() + { + $container = $this->getContainer(array('YamlBundle')); + + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + + $this->loadFromFile($container, 'orm_resolve_target_entity'); + $this->compileContainer($container); + + $definition = $container->getDefinition('doctrine.orm.listeners.resolve_target_entity'); + $this->assertDICDefinitionMethodCallOnce($definition, 'addResolveTargetEntity', array('Symfony\Component\Security\Core\User\UserInterface', 'MyUserClass', array())); + $this->assertEquals(array('doctrine.event_listener' => array( array('event' => 'loadClassMetadata') ) ), $definition->getTags()); + } + + protected function getContainer($bundles = 'YamlBundle', $vendor = null) + { + $bundles = (array) $bundles; + + $map = array(); + foreach ($bundles as $bundle) { + require_once __DIR__.'/Fixtures/Bundles/'.($vendor ? $vendor.'/' : '').$bundle.'/'.$bundle.'.php'; + + $map[$bundle] = 'Fixtures\\Bundles\\'.($vendor ? $vendor.'\\' : '').$bundle.'\\'.$bundle; + } + + return new ContainerBuilder(new ParameterBag(array( + 'kernel.debug' => false, + 'kernel.bundles' => $map, + 'kernel.cache_dir' => sys_get_temp_dir(), + 'kernel.environment' => 'test', + 'kernel.root_dir' => __DIR__.'/../../' // src dir + ))); + } + + /** + * Assertion on the Class of a DIC Service Definition. + * + * @param \Symfony\Component\DependencyInjection\Definition $definition + * @param string $expectedClass + */ + protected function assertDICDefinitionClass($definition, $expectedClass) + { + $this->assertEquals($expectedClass, $definition->getClass(), 'Expected Class of the DIC Container Service Definition is wrong.'); + } + + protected function assertDICConstructorArguments($definition, $args) + { + $this->assertEquals($args, $definition->getArguments(), "Expected and actual DIC Service constructor arguments of definition '".$definition->getClass()."' don't match."); + } + + protected function assertDICDefinitionMethodCallAt($pos, $definition, $methodName, array $params = null) + { + $calls = $definition->getMethodCalls(); + if (isset($calls[$pos][0])) { + $this->assertEquals($methodName, $calls[$pos][0], "Method '".$methodName."' is expected to be called at position $pos."); + + if ($params !== null) { + $this->assertEquals($params, $calls[$pos][1], "Expected parameters to methods '".$methodName."' do not match the actual parameters."); + } + } + } + + /** + * Assertion for the DI Container, check if the given definition contains a method call with the given parameters. + * + * @param \Symfony\Component\DependencyInjection\Definition $definition + * @param string $methodName + * @param array $params + */ + protected function assertDICDefinitionMethodCallOnce($definition, $methodName, array $params = null) + { + $calls = $definition->getMethodCalls(); + $called = false; + foreach ($calls as $call) { + if ($call[0] == $methodName) { + if ($called) { + $this->fail("Method '".$methodName."' is expected to be called only once, a second call was registered though."); + } else { + $called = true; + if ($params !== null) { + $this->assertEquals($params, $call[1], "Expected parameters to methods '".$methodName."' do not match the actual parameters."); + } + } + } + } + if (!$called) { + $this->fail("Method '".$methodName."' is expected to be called once, definition does not contain a call though."); + } + } + + protected function compileContainer(ContainerBuilder $container) + { + $container->getCompilerPassConfig()->setOptimizationPasses(array(new ResolveDefinitionTemplatesPass())); + $container->getCompilerPassConfig()->setRemovingPasses(array()); + $container->compile(); + } + + protected function getConnectionConfig() + { + return array('dbal' => array('connections' => array('default' => array('password' => 'foo')))); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/AnnotationsBundle/AnnotationsBundle.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/AnnotationsBundle/AnnotationsBundle.php new file mode 100644 index 0000000..c99a0bb --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/AnnotationsBundle/AnnotationsBundle.php @@ -0,0 +1,21 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\AnnotationsBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class AnnotationsBundle extends Bundle +{ +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/AnnotationsBundle/Entity/Test.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/AnnotationsBundle/Entity/Test.php new file mode 100644 index 0000000..9c2932c --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/AnnotationsBundle/Entity/Test.php @@ -0,0 +1,19 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\AnnotationsBundle\Entity; + +class Test +{ +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/Vendor/AnnotationsBundle/AnnotationsBundle.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/Vendor/AnnotationsBundle/AnnotationsBundle.php new file mode 100644 index 0000000..fe940e3 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/Vendor/AnnotationsBundle/AnnotationsBundle.php @@ -0,0 +1,21 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\Vendor\AnnotationsBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class AnnotationsBundle extends Bundle +{ +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/Vendor/AnnotationsBundle/Entity/Test.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/Vendor/AnnotationsBundle/Entity/Test.php new file mode 100644 index 0000000..0dfe0f6 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/Vendor/AnnotationsBundle/Entity/Test.php @@ -0,0 +1,19 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\Vendor\AnnotationsBundle\Entity; + +class Test +{ +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/XmlBundle/Entity/Test.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/XmlBundle/Entity/Test.php new file mode 100644 index 0000000..770ab31 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/XmlBundle/Entity/Test.php @@ -0,0 +1,19 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\XmlBundle\Entity; + +class Test +{ +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/XmlBundle/Resources/config/doctrine/Test.orm.xml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/XmlBundle/Resources/config/doctrine/Test.orm.xml new file mode 100644 index 0000000..e69de29 diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/XmlBundle/XmlBundle.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/XmlBundle/XmlBundle.php new file mode 100644 index 0000000..f14e909 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/XmlBundle/XmlBundle.php @@ -0,0 +1,21 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\XmlBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class XmlBundle extends Bundle +{ +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/YamlBundle/Entity/Test.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/YamlBundle/Entity/Test.php new file mode 100644 index 0000000..9eb004c --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/YamlBundle/Entity/Test.php @@ -0,0 +1,20 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\YamlBundle\Entity; + +class Test +{ + private $id; +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/YamlBundle/Resources/config/doctrine/Test.orm.yml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/YamlBundle/Resources/config/doctrine/Test.orm.yml new file mode 100644 index 0000000..6ac8c14 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/YamlBundle/Resources/config/doctrine/Test.orm.yml @@ -0,0 +1,5 @@ +Fixtures\Bundles\YamlBundle\Entity\Test: + type: entity + id: + id: + type: integer diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/YamlBundle/YamlBundle.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/YamlBundle/YamlBundle.php new file mode 100644 index 0000000..8b9fea0 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/YamlBundle/YamlBundle.php @@ -0,0 +1,21 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\YamlBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class YamlBundle extends Bundle +{ +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_logging.xml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_logging.xml new file mode 100644 index 0000000..b7b17b4 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_logging.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_service_multiple_connections.xml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_service_multiple_connections.xml new file mode 100644 index 0000000..acfa896 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_service_multiple_connections.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_service_single_connection.xml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_service_single_connection.xml new file mode 100644 index 0000000..fada4ad --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_service_single_connection.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_service_single_master_slave_connection.xml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_service_single_master_slave_connection.xml new file mode 100644 index 0000000..1b31a4c --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_service_single_master_slave_connection.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_types.xml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_types.xml new file mode 100644 index 0000000..368cc89 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_types.xml @@ -0,0 +1,15 @@ + + + + + + + Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestType + + + + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_filters.xml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_filters.xml new file mode 100644 index 0000000..913a10e --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_filters.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\TestFilter + + + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_functions.xml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_functions.xml new file mode 100644 index 0000000..7bbdf7a --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_functions.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction + Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestNumericFunction + Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestDatetimeFunction + + + + + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_hydration_mode.xml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_hydration_mode.xml new file mode 100644 index 0000000..b6ceb83 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_hydration_mode.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestHydrator + + + + + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_imports.xml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_imports.xml new file mode 100644 index 0000000..20e9b25 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_imports.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_imports_import.xml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_imports_import.xml new file mode 100644 index 0000000..de649bf --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_imports_import.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_multiple_em_bundle_mappings.xml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_multiple_em_bundle_mappings.xml new file mode 100644 index 0000000..65312da --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_multiple_em_bundle_mappings.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_proxy.xml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_proxy.xml new file mode 100644 index 0000000..96208dd --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_proxy.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_resolve_target_entity.xml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_resolve_target_entity.xml new file mode 100644 index 0000000..6890cd0 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_resolve_target_entity.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + MyUserClass + + + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_multiple_entity_managers.xml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_multiple_entity_managers.xml new file mode 100644 index 0000000..9c3b840 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_multiple_entity_managers.xml @@ -0,0 +1,40 @@ + + + + + + Proxies + + + + + + + + + + + + + + + + + + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_simple_single_entity_manager.xml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_simple_single_entity_manager.xml new file mode 100644 index 0000000..0870542 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_simple_single_entity_manager.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + Doctrine\Common\Cache\MemcacheCache + localhost + 11211 + Memcache + + + + + + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_single_entity_manager.xml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_single_entity_manager.xml new file mode 100644 index 0000000..bd64743 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_single_entity_manager.xml @@ -0,0 +1,39 @@ + + + + + + Proxies + + + + + + + + + + + Doctrine\Common\Cache\MemcacheCache + localhost + 11211 + Memcache + + + + + + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_single_em_bundle_mappings.xml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_single_em_bundle_mappings.xml new file mode 100644 index 0000000..5ea5b2f --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_single_em_bundle_mappings.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_single_em_dql_functions.xml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_single_em_dql_functions.xml new file mode 100644 index 0000000..0ed15d1 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_single_em_dql_functions.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction + + + + diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/dbal_logging.yml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/dbal_logging.yml new file mode 100644 index 0000000..ee8ef26 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/dbal_logging.yml @@ -0,0 +1,13 @@ +doctrine: + dbal: + default_connection: mysql + connections: + log: + logging: true + profiling: false + profile: + logging: false + profiling: true + both: + logging: true + profiling: true diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/dbal_service_multiple_connections.yml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/dbal_service_multiple_connections.yml new file mode 100644 index 0000000..a01101d --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/dbal_service_multiple_connections.yml @@ -0,0 +1,18 @@ +doctrine: + dbal: + default_connection: mysql + connections: + mysql: + dbname: mysql_db + user: mysql_user + password: mysql_s3cr3t + unix_socket: /path/to/mysqld.sock + sqlite: + driver: pdo_sqlite + memory: true + oci: + driver: oci8 + dbname: oracle_db + user: oracle_user + password: oracle_s3cr3t + charset: utf8 diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/dbal_service_single_connection.yml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/dbal_service_single_connection.yml new file mode 100644 index 0000000..9db7c37 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/dbal_service_single_connection.yml @@ -0,0 +1,6 @@ +doctrine: + dbal: + dbname: mysql_db + user: mysql_user + password: mysql_s3cr3t + unix_socket: /path/to/mysqld.sock diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/dbal_service_single_master_slave_connection.yml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/dbal_service_single_master_slave_connection.yml new file mode 100644 index 0000000..c7f05f6 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/dbal_service_single_master_slave_connection.yml @@ -0,0 +1,12 @@ +doctrine: + dbal: + dbname: mysql_db + user: mysql_user + password: mysql_s3cr3t + unix_socket: /path/to/mysqld.sock + slaves: + slave1: + user: slave_user + dbname: slave_db + password: slave_s3cr3t + unix_socket: /path/to/mysqld_slave.sock diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/dbal_types.yml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/dbal_types.yml new file mode 100644 index 0000000..1e86dc4 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/dbal_types.yml @@ -0,0 +1,7 @@ +doctrine: + dbal: + default_connection: default + types: + test: Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestType + connections: + default: ~ diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_filters.yml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_filters.yml new file mode 100644 index 0000000..aa85341 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_filters.yml @@ -0,0 +1,12 @@ +doctrine: + dbal: + default_connection: default + connections: + default: + dbname: db + + orm: + filters: + soft_delete: + class: Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\TestFilter + enabled: true diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_functions.yml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_functions.yml new file mode 100644 index 0000000..2185305 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_functions.yml @@ -0,0 +1,19 @@ +doctrine: + dbal: + default_connection: default + connections: + default: + dbname: db + + orm: + entity_managers: + default: + mappings: + YamlBundle: ~ + dql: + string_functions: + test_string: Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction + numeric_functions: + test_numeric: Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestNumericFunction + datetime_functions: + test_datetime: Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestDatetimeFunction diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_hydration_mode.yml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_hydration_mode.yml new file mode 100644 index 0000000..6d81a5b --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_hydration_mode.yml @@ -0,0 +1,14 @@ +doctrine: + dbal: + default_connection: default + connections: + default: + dbname: db + + orm: + entity_managers: + default: + hydrators: + test_hydrator: Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestHydrator + mappings: + YamlBundle: ~ diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_imports.yml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_imports.yml new file mode 100644 index 0000000..df87945 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_imports.yml @@ -0,0 +1,6 @@ +imports: + - { resource: orm_imports_import.yml } + +doctrine: + orm: + auto_generate_proxy_classes: true diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_imports_import.yml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_imports_import.yml new file mode 100644 index 0000000..c533c1e --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_imports_import.yml @@ -0,0 +1,15 @@ +doctrine: + dbal: + default_connection: default + connections: + default: + dbname: db + + orm: + auto_generate_proxy_classes: false + default_entity_manager: default + entity_managers: + default: + metadata_cache_driver: apc + mappings: + YamlBundle: ~ diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_multiple_em_bundle_mappings.yml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_multiple_em_bundle_mappings.yml new file mode 100644 index 0000000..320df94 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_multiple_em_bundle_mappings.yml @@ -0,0 +1,23 @@ +doctrine: + dbal: + default_connection: default + connections: + default: + dbname: db + + orm: + default_entity_manager: em2 + entity_managers: + em1: + mappings: + AnnotationsBundle: ~ + em2: + mappings: + YamlBundle: + dir: Resources/config/doctrine + alias: yml + manual: + type: xml + prefix: Fixtures\Bundles\XmlBundle + dir: %kernel.root_dir%/Tests/DependencyInjection/Fixtures/Bundles/XmlBundle/Resources/config/doctrine + alias: TestAlias diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_resolve_target_entity.yml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_resolve_target_entity.yml new file mode 100644 index 0000000..4bdbedd --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_resolve_target_entity.yml @@ -0,0 +1,10 @@ +doctrine: + dbal: + default_connection: default + connections: + default: + dbname: db + + orm: + resolve_target_entities: + Symfony\Component\Security\Core\User\UserInterface: MyUserClass diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_service_multiple_entity_managers.yml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_service_multiple_entity_managers.yml new file mode 100644 index 0000000..31b9cc1 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_service_multiple_entity_managers.yml @@ -0,0 +1,34 @@ +parameters: + doctrine.orm.proxy_namespace: Proxies + +doctrine: + dbal: + default_connection: conn1 + connections: + conn1: + driver: pdo_sqlite + dbname: sqlite_db + user: sqlite_user + password: sqlite_s3cr3t + memory: true + conn2: + driver: pdo_sqlite + dbname: sqlite_db + user: sqlite_user + password: sqlite_s3cr3t + memory: true + + orm: + default_entity_manager: em2 + auto_generate_proxy_classes: true + entity_managers: + em1: + metadata_cache_driver: xcache + connection: conn1 + mappings: + YamlBundle: ~ + em2: + metadata_cache_driver: apc + connection: conn2 + mappings: + YamlBundle: ~ diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_service_simple_single_entity_manager.yml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_service_simple_single_entity_manager.yml new file mode 100644 index 0000000..b2082a5 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_service_simple_single_entity_manager.yml @@ -0,0 +1,19 @@ +doctrine: + dbal: + default_connection: default + connections: + default: + dbname: db + + orm: + default_entity_manager: default + entity_managers: + default: + mappings: + YamlBundle: ~ + metadata_cache_driver: + type: memcache + class: Doctrine\Common\Cache\MemcacheCache + host: localhost + port: 11211 + instance_class: Memcache diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_service_single_entity_manager.yml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_service_single_entity_manager.yml new file mode 100644 index 0000000..9f81981 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_service_single_entity_manager.yml @@ -0,0 +1,27 @@ +doctrine: + dbal: + default_connection: default + connections: + default: + driver: pdo_sqlite + dbname: sqlite_db + user: sqlite_user + password: sqlite_s3cr3t + memory: true + + orm: + default_entity_manager: dm2 + proxy_namespace: Proxies + auto_generate_proxy_classes: true + entity_managers: + default: + connection: default + default_repository_class: Acme\Doctrine\Repository + mappings: + YamlBundle: ~ + metadata_cache_driver: + type: memcache + class: Doctrine\Common\Cache\MemcacheCache + host: localhost + port: 11211 + instance_class: Memcache diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_single_em_bundle_mappings.yml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_single_em_bundle_mappings.yml new file mode 100644 index 0000000..bf4a199 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_single_em_bundle_mappings.yml @@ -0,0 +1,18 @@ +doctrine: + dbal: + default_connection: default + connections: + default: + dbname: db + + orm: + mappings: + AnnotationsBundle: ~ + YamlBundle: + dir: Resources/config/doctrine + alias: yml + manual: + type: xml + prefix: Fixtures\Bundles\XmlBundle + dir: %kernel.root_dir%/Tests/DependencyInjection/Fixtures/Bundles/XmlBundle/Resources/config/doctrine + alias: TestAlias diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_single_em_dql_functions.yml b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_single_em_dql_functions.yml new file mode 100644 index 0000000..9bcec3c --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_single_em_dql_functions.yml @@ -0,0 +1,11 @@ +doctrine: + dbal: + default_connection: default + connections: + default: + dbname: db + + orm: + dql: + string_functions: + test_string: Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/TestDatetimeFunction.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/TestDatetimeFunction.php new file mode 100644 index 0000000..02ed7e0 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/TestDatetimeFunction.php @@ -0,0 +1,32 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection; + +use Doctrine\ORM\Query\AST\Functions\FunctionNode; +use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\Parser; + +class TestDatetimeFunction extends FunctionNode +{ + public function getSql(SqlWalker $sqlWalker) + { + return ''; + } + + public function parse(Parser $parser) + { + return ''; + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/TestFilter.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/TestFilter.php new file mode 100644 index 0000000..63b5bee --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/TestFilter.php @@ -0,0 +1,30 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection; + +use Doctrine\ORM\Query\Filter\SQLFilter; +use Doctrine\ORM\Mapping\ClassMetadata; + +class TestFilter extends SQLFilter +{ + /** + * Gets the SQL query part to add to a query. + * + * @return string The constraint SQL if there is available, empty string otherwise + */ + public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias) + { + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/TestNumericFunction.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/TestNumericFunction.php new file mode 100644 index 0000000..dd5d865 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/TestNumericFunction.php @@ -0,0 +1,32 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection; + +use Doctrine\ORM\Query\AST\Functions\FunctionNode; +use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\Parser; + +class TestNumericFunction extends FunctionNode +{ + public function getSql(SqlWalker $sqlWalker) + { + return ''; + } + + public function parse(Parser $parser) + { + return ''; + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/TestStringFunction.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/TestStringFunction.php new file mode 100644 index 0000000..8831482 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/TestStringFunction.php @@ -0,0 +1,32 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection; + +use Doctrine\ORM\Query\AST\Functions\FunctionNode; +use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\Parser; + +class TestStringFunction extends FunctionNode +{ + public function getSql(SqlWalker $sqlWalker) + { + return ''; + } + + public function parse(Parser $parser) + { + return ''; + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/TestType.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/TestType.php new file mode 100644 index 0000000..18f6b0f --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/TestType.php @@ -0,0 +1,30 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection; + +use Doctrine\DBAL\Platforms\AbstractPlatform; + +class TestType extends \Doctrine\DBAL\Types\Type +{ + public function getName() + { + return 'test'; + } + + public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + { + return ''; + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/XMLSchemaTest.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/XMLSchemaTest.php new file mode 100644 index 0000000..c48a68b --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/XMLSchemaTest.php @@ -0,0 +1,66 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection; + +class XMLSchemaTest extends \PHPUnit_Framework_TestCase +{ + static public function dataValidateSchemaFiles() + { + $schemaFiles = array(); + $di = new \DirectoryIterator(__DIR__."/Fixtures/config/xml"); + foreach ($di as $element) { + if ($element->isFile() && substr($element->getFilename(), -4) === ".xml") { + $schemaFiles[] = array($element->getPathname()); + } + } + + return $schemaFiles; + } + + /** + * @dataProvider dataValidateSchemaFiles + */ + public function testValidateSchema($file) + { + $found = false; + $dom = new \DOMDocument('1.0', 'UTF-8'); + $dom->load($file); + + + $dbalElements = $dom->getElementsByTagNameNS("http://symfony.com/schema/dic/doctrine", "config"); + if ($dbalElements->length) { + $dbalDom = new \DOMDocument('1.0', 'UTF-8'); + $dbalNode = $dbalDom->importNode($dbalElements->item(0)); + $dbalDom->appendChild($dbalNode); + + $ret = $dbalDom->schemaValidate(__DIR__."/../../Resources/config/schema/doctrine-1.0.xsd"); + $this->assertTrue($ret, "DoctrineBundle Dependency Injection XMLSchema did not validate this XML instance."); + $found = true; + } + + $ormElements = $dom->getElementsByTagNameNS("http://symfony.com/schema/dic/doctrine", "config"); + if ($ormElements->length) { + $ormDom = new \DOMDocument('1.0', 'UTF-8'); + $ormNode = $ormDom->importNode($ormElements->item(0)); + $ormDom->appendChild($ormNode); + + $ret = $ormDom->schemaValidate(__DIR__."/../../Resources/config/schema/doctrine-1.0.xsd"); + $this->assertTrue($ret, "DoctrineBundle Dependency Injection XMLSchema did not validate this XML instance."); + $found = true; + } + + $this->assertTrue($found, "Neither nor elements found in given XML. Are namespaces configured correctly?"); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/XmlDoctrineExtensionTest.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/XmlDoctrineExtensionTest.php new file mode 100644 index 0000000..4b787fb --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/XmlDoctrineExtensionTest.php @@ -0,0 +1,28 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\Config\FileLocator; + +class XmlDoctrineExtensionTest extends AbstractDoctrineExtensionTest +{ + protected function loadFromFile(ContainerBuilder $container, $file) + { + $loadXml = new XmlFileLoader($container, new FileLocator(__DIR__.'/Fixtures/config/xml')); + $loadXml->load($file.'.xml'); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/YamlDoctrineExtensionTest.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/YamlDoctrineExtensionTest.php new file mode 100644 index 0000000..2a96bd5 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/DependencyInjection/YamlDoctrineExtensionTest.php @@ -0,0 +1,28 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\Config\FileLocator; + +class YamlDoctrineExtensionTest extends AbstractDoctrineExtensionTest +{ + protected function loadFromFile(ContainerBuilder $container, $file) + { + $loadYaml = new YamlFileLoader($container, new FileLocator(__DIR__.'/Fixtures/config/yml')); + $loadYaml->load($file.'.yml'); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/Mapping/MetadataFactoryTest.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/Mapping/MetadataFactoryTest.php new file mode 100644 index 0000000..b226336 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/Mapping/MetadataFactoryTest.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 Doctrine\Bundle\DoctrineBundle\Tests; + +use Doctrine\Bundle\DoctrineBundle\Tests\TestCase; +use Doctrine\Bundle\DoctrineBundle\Mapping\MetadataFactory; +use Doctrine\Bundle\DoctrineBundle\Mapping\ClassMetadataCollection; +use Doctrine\ORM\Mapping\ClassMetadataInfo; + +class MetadataFactoryTest extends TestCase +{ + protected function setUp() + { + parent::setUp(); + + if (!class_exists('Doctrine\\ORM\\Version')) { + $this->markTestSkipped('Doctrine ORM is not available.'); + } + } + + public function testFindNamespaceAndPathForMetadata() + { + $class = new ClassMetadataInfo(__CLASS__); + $collection = new ClassMetadataCollection(array($class)); + + $registry = $this->getMock('Doctrine\Common\Persistence\ManagerRegistry'); + $factory = new MetadataFactory($registry); + + $this->setExpectedException("RuntimeException", "Can't find base path for \"Doctrine\Bundle\DoctrineBundle\Tests\MetadataFactoryTest"); + $factory->findNamespaceAndPathForMetadata($collection); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/RegistryTest.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/RegistryTest.php new file mode 100644 index 0000000..9d1003d --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/RegistryTest.php @@ -0,0 +1,149 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Tests; + +use Doctrine\Bundle\DoctrineBundle\Registry; + +class RegistryTest extends TestCase +{ + public function testGetDefaultConnectionName() + { + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $registry = new Registry($container, array(), array(), 'default', 'default'); + + $this->assertEquals('default', $registry->getDefaultConnectionName()); + } + + public function testGetDefaultEntityManagerName() + { + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $registry = new Registry($container, array(), array(), 'default', 'default'); + + $this->assertEquals('default', $registry->getDefaultEntityManagerName()); + } + + public function testGetDefaultConnection() + { + $conn = $this->getMock('Doctrine\DBAL\Connection', array(), array(), '', false); + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $container->expects($this->once()) + ->method('get') + ->with($this->equalTo('doctrine.dbal.default_connection')) + ->will($this->returnValue($conn)); + + $registry = new Registry($container, array('default' => 'doctrine.dbal.default_connection'), array(), 'default', 'default'); + + $this->assertSame($conn, $registry->getConnection()); + } + + public function testGetConnection() + { + $conn = $this->getMock('Doctrine\DBAL\Connection', array(), array(), '', false); + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $container->expects($this->once()) + ->method('get') + ->with($this->equalTo('doctrine.dbal.default_connection')) + ->will($this->returnValue($conn)); + + $registry = new Registry($container, array('default' => 'doctrine.dbal.default_connection'), array(), 'default', 'default'); + + $this->assertSame($conn, $registry->getConnection('default')); + } + + public function testGetUnknownConnection() + { + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $registry = new Registry($container, array(), array(), 'default', 'default'); + + $this->setExpectedException('InvalidArgumentException', 'Doctrine ORM Connection named "default" does not exist.'); + $registry->getConnection('default'); + } + + public function testGetConnectionNames() + { + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $registry = new Registry($container, array('default' => 'doctrine.dbal.default_connection'), array(), 'default', 'default'); + + $this->assertEquals(array('default' => 'doctrine.dbal.default_connection'), $registry->getConnectionNames()); + } + + public function testGetDefaultEntityManager() + { + $em = new \stdClass(); + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $container->expects($this->once()) + ->method('get') + ->with($this->equalTo('doctrine.orm.default_entity_manager')) + ->will($this->returnValue($em)); + + $registry = new Registry($container, array(), array('default' => 'doctrine.orm.default_entity_manager'), 'default', 'default'); + + $this->assertSame($em, $registry->getEntityManager()); + } + + public function testGetEntityManager() + { + $em = new \stdClass(); + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $container->expects($this->once()) + ->method('get') + ->with($this->equalTo('doctrine.orm.default_entity_manager')) + ->will($this->returnValue($em)); + + $registry = new Registry($container, array(), array('default' => 'doctrine.orm.default_entity_manager'), 'default', 'default'); + + $this->assertSame($em, $registry->getEntityManager('default')); + } + + public function testGetUnknownEntityManager() + { + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $registry = new Registry($container, array(), array(), 'default', 'default'); + + $this->setExpectedException('InvalidArgumentException', 'Doctrine ORM Manager named "default" does not exist.'); + $registry->getEntityManager('default'); + } + + public function testResetDefaultEntityManager() + { + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $container->expects($this->once()) + ->method('set') + ->with($this->equalTo('doctrine.orm.default_entity_manager'), $this->equalTo(null)); + + $registry = new Registry($container, array(), array('default' => 'doctrine.orm.default_entity_manager'), 'default', 'default'); + $registry->resetEntityManager(); + } + + public function testResetEntityManager() + { + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $container->expects($this->once()) + ->method('set') + ->with($this->equalTo('doctrine.orm.default_entity_manager'), $this->equalTo(null)); + + $registry = new Registry($container, array(), array('default' => 'doctrine.orm.default_entity_manager'), 'default', 'default'); + $registry->resetEntityManager('default'); + } + + public function testResetUnknownEntityManager() + { + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $registry = new Registry($container, array(), array(), 'default', 'default'); + + $this->setExpectedException('InvalidArgumentException', 'Doctrine ORM Manager named "default" does not exist.'); + $registry->resetEntityManager('default'); + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/TestCase.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/TestCase.php new file mode 100644 index 0000000..b8857d8 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/TestCase.php @@ -0,0 +1,83 @@ + + * (c) Doctrine Project, Benjamin Eberlei + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Bundle\DoctrineBundle\Tests; + +use Doctrine\Common\Annotations\AnnotationReader; +use Doctrine\Bundle\DoctrineBundle\DependencyInjection\DoctrineExtension; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\Compiler\ResolveDefinitionTemplatesPass; +use Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass\RegisterEventListenersAndSubscribersPass; + +class TestCase extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Doctrine\\Common\\Version')) { + $this->markTestSkipped('Doctrine is not available.'); + } + } + + public function createYamlBundleTestContainer() + { + $container = new ContainerBuilder(new ParameterBag(array( + 'kernel.debug' => false, + 'kernel.bundles' => array('YamlBundle' => 'Fixtures\Bundles\YamlBundle\YamlBundle'), + 'kernel.cache_dir' => sys_get_temp_dir(), + 'kernel.environment' => 'test', + 'kernel.root_dir' => __DIR__.'/../../../../' // src dir + ))); + $container->set('annotation_reader', new AnnotationReader()); + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + $loader->load(array(array( + 'dbal' => array( + 'connections' => array( + 'default' => array( + 'driver' => 'pdo_mysql', + 'charset' => 'UTF8', + 'platform-service' => 'my.platform', + ) + ), + 'default_connection' => 'default', + 'types' => array( + 'test' => 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestType', + ), + ), 'orm' => array( + 'default_entity_manager' => 'default', + 'entity_managers' => array ( + 'default' => array( + 'mappings' => array('YamlBundle' => array( + 'type' => 'yml', + 'dir' => __DIR__.'/DependencyInjection/Fixtures/Bundles/YamlBundle/Resources/config/doctrine', + 'prefix' => 'Fixtures\Bundles\YamlBundle\Entity', + ) + ))), + 'resolve_target_entities' => array( + 'Symfony\Component\Security\Core\User\UserInterface' => 'stdClass', + ), + ) + )), $container); + + $container->setDefinition('my.platform', new \Symfony\Component\DependencyInjection\Definition('Doctrine\DBAL\Platforms\MySqlPlatform')); + + $container->getCompilerPassConfig()->setOptimizationPasses(array(new ResolveDefinitionTemplatesPass())); + $container->getCompilerPassConfig()->setRemovingPasses(array()); + $container->compile(); + + return $container; + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/bootstrap.php b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/bootstrap.php new file mode 100644 index 0000000..2598748 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Tests/bootstrap.php @@ -0,0 +1,8 @@ +=5.3.2", + "symfony/framework-bundle": "2.1.*", + "symfony/doctrine-bridge": "2.1.*", + "doctrine/dbal": ">=2.2,<2.4-dev" + }, + "require-dev": { + "doctrine/orm": ">=2.2,<2.4-dev", + "symfony/yaml": "2.1.*", + "symfony/validator": "2.1.*" + }, + "suggest": { + "doctrine/orm": "The Doctrine ORM integration is optional in the bundle." + }, + "autoload": { + "psr-0": { "Doctrine\\Bundle\\DoctrineBundle": "" } + }, + "target-dir": "Doctrine/Bundle/DoctrineBundle", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/phpunit.xml.dist b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/phpunit.xml.dist new file mode 100644 index 0000000..d401031 --- /dev/null +++ b/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/phpunit.xml.dist @@ -0,0 +1,35 @@ + + + + + + ./Tests + + + + + + benchmark + + + + + + . + + ./Resources + ./Tests + + + + diff --git a/vendor/doctrine/orm/.travis.yml b/vendor/doctrine/orm/.travis.yml new file mode 100644 index 0000000..716b9b6 --- /dev/null +++ b/vendor/doctrine/orm/.travis.yml @@ -0,0 +1,19 @@ +language: php + +php: + - 5.3 + - 5.4 +env: + - DB=mysql + - DB=pgsql + - DB=sqlite + +before_script: + - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'DROP DATABASE IF EXISTS doctrine_tests;' -U postgres; fi" + - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'DROP DATABASE IF EXISTS doctrine_tests_tmp;' -U postgres; fi" + - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database doctrine_tests;' -U postgres; fi" + - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database doctrine_tests_tmp;' -U postgres; fi" + - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS doctrine_tests_tmp;create database IF NOT EXISTS doctrine_tests;'; fi" + - git submodule update --init + +script: phpunit --configuration tests/travis/$DB.travis.xml \ No newline at end of file diff --git a/vendor/doctrine/orm/LICENSE b/vendor/doctrine/orm/LICENSE new file mode 100644 index 0000000..1c03f74 --- /dev/null +++ b/vendor/doctrine/orm/LICENSE @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/vendor/doctrine/orm/README.markdown b/vendor/doctrine/orm/README.markdown new file mode 100644 index 0000000..00458ca --- /dev/null +++ b/vendor/doctrine/orm/README.markdown @@ -0,0 +1,18 @@ +# Doctrine 2 ORM + +Master: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?branch=master)](http://travis-ci.org/doctrine/doctrine2) +2.1.x: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?branch=2.1.x)](http://travis-ci.org/doctrine/doctrine2) + +Doctrine 2 is an object-relational mapper (ORM) for PHP 5.3.2+ that provides transparent persistence +for PHP objects. It sits on top of a powerful database abstraction layer (DBAL). One of its key features +is the option to write database queries in a proprietary object oriented SQL dialect called Doctrine Query Language (DQL), +inspired by Hibernates HQL. This provides developers with a powerful alternative to SQL that maintains flexibility +without requiring unnecessary code duplication. + +## More resources: + +* [Website](http://www.doctrine-project.org) +* [Documentation](http://www.doctrine-project.org/projects/orm/2.0/docs/reference/introduction/en) +* [Issue Tracker](http://www.doctrine-project.org/jira/browse/DDC) +* [Downloads](http://github.com/doctrine/doctrine2/downloads) + diff --git a/vendor/doctrine/orm/composer.json b/vendor/doctrine/orm/composer.json new file mode 100644 index 0000000..4f3f7b3 --- /dev/null +++ b/vendor/doctrine/orm/composer.json @@ -0,0 +1,23 @@ +{ + "name": "doctrine/orm", + "type": "library", + "description": "Object-Relational-Mapper for PHP", + "keywords": ["orm", "database"], + "homepage": "http://www.doctrine-project.org", + "license": "LGPL", + "authors": [ + {"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"}, + {"name": "Roman Borschel", "email": "roman@code-factory.org"}, + {"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"}, + {"name": "Jonathan Wage", "email": "jonwage@gmail.com"} + ], + "require": { + "php": ">=5.3.2", + "ext-pdo": "*", + "doctrine/common": "2.2.*", + "doctrine/dbal": "2.2.*" + }, + "autoload": { + "psr-0": { "Doctrine\\ORM": "lib/" } + } +} diff --git a/vendor/doctrine/orm/doctrine-mapping.xsd b/vendor/doctrine/orm/doctrine-mapping.xsd new file mode 100644 index 0000000..8db612e --- /dev/null +++ b/vendor/doctrine/orm/doctrine-mapping.xsd @@ -0,0 +1,409 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php b/vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php new file mode 100644 index 0000000..0dba9dc --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php @@ -0,0 +1,820 @@ +. + */ + +namespace Doctrine\ORM; + +use Doctrine\DBAL\Types\Type, + Doctrine\DBAL\Cache\QueryCacheProfile, + Doctrine\ORM\Query\QueryException, + Doctrine\ORM\Internal\Hydration\CacheHydrator; + +/** + * Base contract for ORM queries. Base class for Query and NativeQuery. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Konsta Vesterinen + */ +abstract class AbstractQuery +{ + /* Hydration mode constants */ + /** + * Hydrates an object graph. This is the default behavior. + */ + const HYDRATE_OBJECT = 1; + /** + * Hydrates an array graph. + */ + const HYDRATE_ARRAY = 2; + /** + * Hydrates a flat, rectangular result set with scalar values. + */ + const HYDRATE_SCALAR = 3; + /** + * Hydrates a single scalar value. + */ + const HYDRATE_SINGLE_SCALAR = 4; + + /** + * Very simple object hydrator (optimized for performance). + */ + const HYDRATE_SIMPLEOBJECT = 5; + + /** + * @var array The parameter map of this query. + */ + protected $_params = array(); + + /** + * @var array The parameter type map of this query. + */ + protected $_paramTypes = array(); + + /** + * @var ResultSetMapping The user-specified ResultSetMapping to use. + */ + protected $_resultSetMapping; + + /** + * @var \Doctrine\ORM\EntityManager The entity manager used by this query object. + */ + protected $_em; + + /** + * @var array The map of query hints. + */ + protected $_hints = array(); + + /** + * @var integer The hydration mode. + */ + protected $_hydrationMode = self::HYDRATE_OBJECT; + + /** + * @param \Doctrine\DBAL\Cache\QueryCacheProfile + */ + protected $_queryCacheProfile; + + /** + * @var boolean Boolean value that indicates whether or not expire the result cache. + */ + protected $_expireResultCache = false; + + /** + * @param \Doctrine\DBAL\Cache\QueryCacheProfile + */ + protected $_hydrationCacheProfile; + + /** + * Initializes a new instance of a class derived from AbstractQuery. + * + * @param \Doctrine\ORM\EntityManager $entityManager + */ + public function __construct(EntityManager $em) + { + $this->_em = $em; + } + + /** + * Retrieves the associated EntityManager of this Query instance. + * + * @return \Doctrine\ORM\EntityManager + */ + public function getEntityManager() + { + return $this->_em; + } + + /** + * Frees the resources used by the query object. + * + * Resets Parameters, Parameter Types and Query Hints. + * + * @return void + */ + public function free() + { + $this->_params = array(); + $this->_paramTypes = array(); + $this->_hints = array(); + } + + /** + * Get all defined parameters. + * + * @return array The defined query parameters. + */ + public function getParameters() + { + return $this->_params; + } + + /** + * Get all defined parameter types. + * + * @return array The defined query parameter types. + */ + public function getParameterTypes() + { + return $this->_paramTypes; + } + + /** + * Gets a query parameter. + * + * @param mixed $key The key (index or name) of the bound parameter. + * @return mixed The value of the bound parameter. + */ + public function getParameter($key) + { + if (isset($this->_params[$key])) { + return $this->_params[$key]; + } + + return null; + } + + /** + * Gets a query parameter type. + * + * @param mixed $key The key (index or name) of the bound parameter. + * @return mixed The parameter type of the bound parameter. + */ + public function getParameterType($key) + { + if (isset($this->_paramTypes[$key])) { + return $this->_paramTypes[$key]; + } + + return null; + } + + /** + * Gets the SQL query that corresponds to this query object. + * The returned SQL syntax depends on the connection driver that is used + * by this query object at the time of this method call. + * + * @return string SQL query + */ + abstract public function getSQL(); + + /** + * Sets a query parameter. + * + * @param string|integer $key The parameter position or name. + * @param mixed $value The parameter value. + * @param string $type The parameter type. If specified, the given value will be run through + * the type conversion of this type. This is usually not needed for + * strings and numeric types. + * @return \Doctrine\ORM\AbstractQuery This query instance. + */ + public function setParameter($key, $value, $type = null) + { + $key = trim($key, ':'); + + $value = $this->processParameterValue($value); + if ($type === null) { + $type = Query\ParameterTypeInferer::inferType($value); + } + + $this->_paramTypes[$key] = $type; + $this->_params[$key] = $value; + + return $this; + } + + /** + * Process an individual parameter value + * + * @param mixed $value + * @return array + */ + private function processParameterValue($value) + { + switch (true) { + case is_array($value): + for ($i = 0, $l = count($value); $i < $l; $i++) { + $paramValue = $this->processParameterValue($value[$i]); + $value[$i] = is_array($paramValue) ? $paramValue[key($paramValue)] : $paramValue; + } + + return $value; + + case is_object($value) && $this->_em->getMetadataFactory()->hasMetadataFor(get_class($value)): + return $this->convertObjectParameterToScalarValue($value); + + default: + return $value; + } + } + + protected function convertObjectParameterToScalarValue($value) + { + $class = $this->_em->getClassMetadata(get_class($value)); + + if ($class->isIdentifierComposite) { + throw new \InvalidArgumentException("Binding an entity with a composite primary key to a query is not supported. You should split the parameter into the explicit fields and bind them seperately."); + } + + if ($this->_em->getUnitOfWork()->getEntityState($value) === UnitOfWork::STATE_MANAGED) { + $values = $this->_em->getUnitOfWork()->getEntityIdentifier($value); + } else { + $values = $class->getIdentifierValues($value); + } + + $value = $values[$class->getSingleIdentifierFieldName()]; + if (!$value) { + throw new \InvalidArgumentException("Binding entities to query parameters only allowed for entities that have an identifier."); + } + + return $value; + } + + /** + * Sets a collection of query parameters. + * + * @param array $params + * @param array $types + * @return \Doctrine\ORM\AbstractQuery This query instance. + */ + public function setParameters(array $params, array $types = array()) + { + foreach ($params as $key => $value) { + $this->setParameter($key, $value, isset($types[$key]) ? $types[$key] : null); + } + + return $this; + } + + /** + * Sets the ResultSetMapping that should be used for hydration. + * + * @param ResultSetMapping $rsm + * @return \Doctrine\ORM\AbstractQuery + */ + public function setResultSetMapping(Query\ResultSetMapping $rsm) + { + $this->_resultSetMapping = $rsm; + + return $this; + } + + /** + * Set a cache profile for hydration caching. + * + * If no result cache driver is set in the QueryCacheProfile, the default + * result cache driver is used from the configuration. + * + * Important: Hydration caching does NOT register entities in the + * UnitOfWork when retrieved from the cache. Never use result cached + * entities for requests that also flush the EntityManager. If you want + * some form of caching with UnitOfWork registration you should use + * {@see AbstractQuery::setResultCacheProfile()}. + * + * @example + * $lifetime = 100; + * $resultKey = "abc"; + * $query->setHydrationCacheProfile(new QueryCacheProfile()); + * $query->setHydrationCacheProfile(new QueryCacheProfile($lifetime, $resultKey)); + * + * @param \Doctrine\DBAL\Cache\QueryCacheProfile $profile + * @return \Doctrine\ORM\AbstractQuery + */ + public function setHydrationCacheProfile(QueryCacheProfile $profile = null) + { + if ( ! $profile->getResultCacheDriver()) { + $resultCacheDriver = $this->_em->getConfiguration()->getHydrationCacheImpl(); + $profile = $profile->setResultCacheDriver($resultCacheDriver); + } + + $this->_hydrationCacheProfile = $profile; + + return $this; + } + + /** + * @return \Doctrine\DBAL\Cache\QueryCacheProfile + */ + public function getHydrationCacheProfile() + { + return $this->_hydrationCacheProfile; + } + + /** + * Set a cache profile for the result cache. + * + * If no result cache driver is set in the QueryCacheProfile, the default + * result cache driver is used from the configuration. + * + * @param \Doctrine\DBAL\Cache\QueryCacheProfile $profile + * @return \Doctrine\ORM\AbstractQuery + */ + public function setResultCacheProfile(QueryCacheProfile $profile = null) + { + if ( ! $profile->getResultCacheDriver()) { + $resultCacheDriver = $this->_em->getConfiguration()->getResultCacheImpl(); + $profile = $profile->setResultCacheDriver($resultCacheDriver); + } + + $this->_queryCacheProfile = $profile; + + return $this; + } + + /** + * Defines a cache driver to be used for caching result sets and implictly enables caching. + * + * @param \Doctrine\Common\Cache\Cache $driver Cache driver + * @return \Doctrine\ORM\AbstractQuery + */ + public function setResultCacheDriver($resultCacheDriver = null) + { + if ($resultCacheDriver !== null && ! ($resultCacheDriver instanceof \Doctrine\Common\Cache\Cache)) { + throw ORMException::invalidResultCacheDriver(); + } + + $this->_queryCacheProfile = $this->_queryCacheProfile + ? $this->_queryCacheProfile->setResultCacheDriver($resultCacheDriver) + : new QueryCacheProfile(0, null, $resultCacheDriver); + + return $this; + } + + /** + * Returns the cache driver used for caching result sets. + * + * @deprecated + * @return \Doctrine\Common\Cache\Cache Cache driver + */ + public function getResultCacheDriver() + { + if ($this->_queryCacheProfile && $this->_queryCacheProfile->getResultCacheDriver()) { + return $this->_queryCacheProfile->getResultCacheDriver(); + } + + return $this->_em->getConfiguration()->getResultCacheImpl(); + } + + /** + * Set whether or not to cache the results of this query and if so, for + * how long and which ID to use for the cache entry. + * + * @param boolean $bool + * @param integer $lifetime + * @param string $resultCacheId + * @return \Doctrine\ORM\AbstractQuery This query instance. + */ + public function useResultCache($bool, $lifetime = null, $resultCacheId = null) + { + if ($bool) { + $this->setResultCacheLifetime($lifetime); + $this->setResultCacheId($resultCacheId); + + return $this; + } + + $this->_queryCacheProfile = null; + + return $this; + } + + /** + * Defines how long the result cache will be active before expire. + * + * @param integer $lifetime How long the cache entry is valid. + * @return \Doctrine\ORM\AbstractQuery This query instance. + */ + public function setResultCacheLifetime($lifetime) + { + $lifetime = ($lifetime !== null) ? (int) $lifetime : 0; + + $this->_queryCacheProfile = $this->_queryCacheProfile + ? $this->_queryCacheProfile->setLifetime($lifetime) + : new QueryCacheProfile($lifetime, null, $this->_em->getConfiguration()->getResultCacheImpl()); + + return $this; + } + + /** + * Retrieves the lifetime of resultset cache. + * + * @deprecated + * @return integer + */ + public function getResultCacheLifetime() + { + return $this->_queryCacheProfile ? $this->_queryCacheProfile->getLifetime() : 0; + } + + /** + * Defines if the result cache is active or not. + * + * @param boolean $expire Whether or not to force resultset cache expiration. + * @return \Doctrine\ORM\AbstractQuery This query instance. + */ + public function expireResultCache($expire = true) + { + $this->_expireResultCache = $expire; + + return $this; + } + + /** + * Retrieves if the resultset cache is active or not. + * + * @return boolean + */ + public function getExpireResultCache() + { + return $this->_expireResultCache; + } + + /** + * @return QueryCacheProfile + */ + public function getQueryCacheProfile() + { + return $this->_queryCacheProfile; + } + + /** + * Change the default fetch mode of an association for this query. + * + * $fetchMode can be one of ClassMetadata::FETCH_EAGER or ClassMetadata::FETCH_LAZY + * + * @param string $class + * @param string $assocName + * @param int $fetchMode + * @return AbstractQuery + */ + public function setFetchMode($class, $assocName, $fetchMode) + { + if ($fetchMode !== Mapping\ClassMetadata::FETCH_EAGER) { + $fetchMode = Mapping\ClassMetadata::FETCH_LAZY; + } + + $this->_hints['fetchMode'][$class][$assocName] = $fetchMode; + + return $this; + } + + /** + * Defines the processing mode to be used during hydration / result set transformation. + * + * @param integer $hydrationMode Doctrine processing mode to be used during hydration process. + * One of the Query::HYDRATE_* constants. + * @return \Doctrine\ORM\AbstractQuery This query instance. + */ + public function setHydrationMode($hydrationMode) + { + $this->_hydrationMode = $hydrationMode; + + return $this; + } + + /** + * Gets the hydration mode currently used by the query. + * + * @return integer + */ + public function getHydrationMode() + { + return $this->_hydrationMode; + } + + /** + * Gets the list of results for the query. + * + * Alias for execute(array(), $hydrationMode = HYDRATE_OBJECT). + * + * @return array + */ + public function getResult($hydrationMode = self::HYDRATE_OBJECT) + { + return $this->execute(array(), $hydrationMode); + } + + /** + * Gets the array of results for the query. + * + * Alias for execute(array(), HYDRATE_ARRAY). + * + * @return array + */ + public function getArrayResult() + { + return $this->execute(array(), self::HYDRATE_ARRAY); + } + + /** + * Gets the scalar results for the query. + * + * Alias for execute(array(), HYDRATE_SCALAR). + * + * @return array + */ + public function getScalarResult() + { + return $this->execute(array(), self::HYDRATE_SCALAR); + } + + /** + * Get exactly one result or null. + * + * @throws NonUniqueResultException + * @param int $hydrationMode + * @return mixed + */ + public function getOneOrNullResult($hydrationMode = null) + { + $result = $this->execute(array(), $hydrationMode); + + if ($this->_hydrationMode !== self::HYDRATE_SINGLE_SCALAR && ! $result) { + return null; + } + + if ( ! is_array($result)) { + return $result; + } + + if (count($result) > 1) { + throw new NonUniqueResultException; + } + + return array_shift($result); + } + + /** + * Gets the single result of the query. + * + * Enforces the presence as well as the uniqueness of the result. + * + * If the result is not unique, a NonUniqueResultException is thrown. + * If there is no result, a NoResultException is thrown. + * + * @param integer $hydrationMode + * @return mixed + * @throws NonUniqueResultException If the query result is not unique. + * @throws NoResultException If the query returned no result. + */ + public function getSingleResult($hydrationMode = null) + { + $result = $this->execute(array(), $hydrationMode); + + if ($this->_hydrationMode !== self::HYDRATE_SINGLE_SCALAR && ! $result) { + throw new NoResultException; + } + + if ( ! is_array($result)) { + return $result; + } + + if (count($result) > 1) { + throw new NonUniqueResultException; + } + + return array_shift($result); + } + + /** + * Gets the single scalar result of the query. + * + * Alias for getSingleResult(HYDRATE_SINGLE_SCALAR). + * + * @return mixed + * @throws QueryException If the query result is not unique. + */ + public function getSingleScalarResult() + { + return $this->getSingleResult(self::HYDRATE_SINGLE_SCALAR); + } + + /** + * Sets a query hint. If the hint name is not recognized, it is silently ignored. + * + * @param string $name The name of the hint. + * @param mixed $value The value of the hint. + * @return \Doctrine\ORM\AbstractQuery + */ + public function setHint($name, $value) + { + $this->_hints[$name] = $value; + + return $this; + } + + /** + * Gets the value of a query hint. If the hint name is not recognized, FALSE is returned. + * + * @param string $name The name of the hint. + * @return mixed The value of the hint or FALSE, if the hint name is not recognized. + */ + public function getHint($name) + { + return isset($this->_hints[$name]) ? $this->_hints[$name] : false; + } + + /** + * Return the key value map of query hints that are currently set. + * + * @return array + */ + public function getHints() + { + return $this->_hints; + } + + /** + * Executes the query and returns an IterableResult that can be used to incrementally + * iterate over the result. + * + * @param array $params The query parameters. + * @param integer $hydrationMode The hydration mode to use. + * @return \Doctrine\ORM\Internal\Hydration\IterableResult + */ + public function iterate(array $params = array(), $hydrationMode = null) + { + if ($hydrationMode !== null) { + $this->setHydrationMode($hydrationMode); + } + + if ($params) { + $this->setParameters($params); + } + + $stmt = $this->_doExecute(); + + return $this->_em->newHydrator($this->_hydrationMode)->iterate( + $stmt, $this->_resultSetMapping, $this->_hints + ); + } + + /** + * Executes the query. + * + * @param array $params Any additional query parameters. + * @param integer $hydrationMode Processing mode to be used during the hydration process. + * @return mixed + */ + public function execute($params = array(), $hydrationMode = null) + { + if ($hydrationMode !== null) { + $this->setHydrationMode($hydrationMode); + } + + if ($params) { + $this->setParameters($params); + } + + $setCacheEntry = function() {}; + + if ($this->_hydrationCacheProfile !== null) { + list($cacheKey, $realCacheKey) = $this->getHydrationCacheId(); + + $queryCacheProfile = $this->getHydrationCacheProfile(); + $cache = $queryCacheProfile->getResultCacheDriver(); + $result = $cache->fetch($cacheKey); + + if (isset($result[$realCacheKey])) { + return $result[$realCacheKey]; + } + + if ( ! $result) { + $result = array(); + } + + $setCacheEntry = function($data) use ($cache, $result, $cacheKey, $realCacheKey, $queryCacheProfile) { + $result[$realCacheKey] = $data; + $cache->save($cacheKey, $result, $queryCacheProfile->getLifetime()); + }; + } + + $stmt = $this->_doExecute(); + + if (is_numeric($stmt)) { + $setCacheEntry($stmt); + + return $stmt; + } + + $data = $this->_em->getHydrator($this->_hydrationMode)->hydrateAll( + $stmt, $this->_resultSetMapping, $this->_hints + ); + + $setCacheEntry($data); + + return $data; + } + + /** + * Get the result cache id to use to store the result set cache entry. + * Will return the configured id if it exists otherwise a hash will be + * automatically generated for you. + * + * @return array ($key, $hash) + */ + protected function getHydrationCacheId() + { + $params = $this->getParameters(); + + foreach ($params AS $key => $value) { + $params[$key] = $this->processParameterValue($value); + } + + $sql = $this->getSQL(); + $queryCacheProfile = $this->getHydrationCacheProfile(); + $hints = $this->getHints(); + $hints['hydrationMode'] = $this->getHydrationMode(); + ksort($hints); + + return $queryCacheProfile->generateCacheKeys($sql, $params, $hints); + } + + /** + * Set the result cache id to use to store the result set cache entry. + * If this is not explicitely set by the developer then a hash is automatically + * generated for you. + * + * @param string $id + * @return \Doctrine\ORM\AbstractQuery This query instance. + */ + public function setResultCacheId($id) + { + $this->_queryCacheProfile = $this->_queryCacheProfile + ? $this->_queryCacheProfile->setCacheKey($id) + : new QueryCacheProfile(0, $id, $this->_em->getConfiguration()->getResultCacheImpl()); + + return $this; + } + + /** + * Get the result cache id to use to store the result set cache entry if set. + * + * @deprecated + * @return string + */ + public function getResultCacheId() + { + return $this->_queryCacheProfile ? $this->_queryCacheProfile->getCacheKey() : null; + } + + /** + * Executes the query and returns a the resulting Statement object. + * + * @return \Doctrine\DBAL\Driver\Statement The executed database statement that holds the results. + */ + abstract protected function _doExecute(); + + /** + * Cleanup Query resource when clone is called. + * + * @return void + */ + public function __clone() + { + $this->_params = array(); + $this->_paramTypes = array(); + $this->_hints = array(); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Configuration.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Configuration.php new file mode 100644 index 0000000..4189f91 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Configuration.php @@ -0,0 +1,573 @@ +. + */ + +namespace Doctrine\ORM; + +use Doctrine\Common\Cache\Cache, + Doctrine\Common\Cache\ArrayCache, + Doctrine\Common\Annotations\AnnotationRegistry, + Doctrine\Common\Annotations\AnnotationReader, + Doctrine\ORM\Mapping\Driver\Driver, + Doctrine\ORM\Mapping\Driver\AnnotationDriver; + +/** + * Configuration container for all configuration options of Doctrine. + * It combines all configuration options from DBAL & ORM. + * + * @since 2.0 + * @internal When adding a new configuration option just write a getter/setter pair. + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class Configuration extends \Doctrine\DBAL\Configuration +{ + /** + * Sets the directory where Doctrine generates any necessary proxy class files. + * + * @param string $dir + */ + public function setProxyDir($dir) + { + $this->_attributes['proxyDir'] = $dir; + } + + /** + * Gets the directory where Doctrine generates any necessary proxy class files. + * + * @return string + */ + public function getProxyDir() + { + return isset($this->_attributes['proxyDir']) ? + $this->_attributes['proxyDir'] : null; + } + + /** + * Gets a boolean flag that indicates whether proxy classes should always be regenerated + * during each script execution. + * + * @return boolean + */ + public function getAutoGenerateProxyClasses() + { + return isset($this->_attributes['autoGenerateProxyClasses']) ? + $this->_attributes['autoGenerateProxyClasses'] : true; + } + + /** + * Sets a boolean flag that indicates whether proxy classes should always be regenerated + * during each script execution. + * + * @param boolean $bool + */ + public function setAutoGenerateProxyClasses($bool) + { + $this->_attributes['autoGenerateProxyClasses'] = $bool; + } + + /** + * Gets the namespace where proxy classes reside. + * + * @return string + */ + public function getProxyNamespace() + { + return isset($this->_attributes['proxyNamespace']) ? + $this->_attributes['proxyNamespace'] : null; + } + + /** + * Sets the namespace where proxy classes reside. + * + * @param string $ns + */ + public function setProxyNamespace($ns) + { + $this->_attributes['proxyNamespace'] = $ns; + } + + /** + * Sets the cache driver implementation that is used for metadata caching. + * + * @param Driver $driverImpl + * @todo Force parameter to be a Closure to ensure lazy evaluation + * (as soon as a metadata cache is in effect, the driver never needs to initialize). + */ + public function setMetadataDriverImpl(Driver $driverImpl) + { + $this->_attributes['metadataDriverImpl'] = $driverImpl; + } + + /** + * Add a new default annotation driver with a correctly configured annotation reader. + * + * @param array $paths + * @return Mapping\Driver\AnnotationDriver + */ + public function newDefaultAnnotationDriver($paths = array()) + { + if (version_compare(\Doctrine\Common\Version::VERSION, '2.2.0-DEV', '>=')) { + // Register the ORM Annotations in the AnnotationRegistry + AnnotationRegistry::registerFile(__DIR__ . '/Mapping/Driver/DoctrineAnnotations.php'); + + $reader = new \Doctrine\Common\Annotations\SimpleAnnotationReader(); + $reader->addNamespace('Doctrine\ORM\Mapping'); + $reader = new \Doctrine\Common\Annotations\CachedReader($reader, new ArrayCache()); + } else if (version_compare(\Doctrine\Common\Version::VERSION, '2.1.0-DEV', '>=')) { + // Register the ORM Annotations in the AnnotationRegistry + AnnotationRegistry::registerFile(__DIR__ . '/Mapping/Driver/DoctrineAnnotations.php'); + + $reader = new AnnotationReader(); + $reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\'); + $reader->setIgnoreNotImportedAnnotations(true); + $reader->setEnableParsePhpImports(false); + $reader = new \Doctrine\Common\Annotations\CachedReader( + new \Doctrine\Common\Annotations\IndexedReader($reader), new ArrayCache() + ); + } else { + $reader = new AnnotationReader(); + $reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\'); + } + return new AnnotationDriver($reader, (array)$paths); + } + + /** + * Adds a namespace under a certain alias. + * + * @param string $alias + * @param string $namespace + */ + public function addEntityNamespace($alias, $namespace) + { + $this->_attributes['entityNamespaces'][$alias] = $namespace; + } + + /** + * Resolves a registered namespace alias to the full namespace. + * + * @param string $entityNamespaceAlias + * @return string + * @throws MappingException + */ + public function getEntityNamespace($entityNamespaceAlias) + { + if ( ! isset($this->_attributes['entityNamespaces'][$entityNamespaceAlias])) { + throw ORMException::unknownEntityNamespace($entityNamespaceAlias); + } + + return trim($this->_attributes['entityNamespaces'][$entityNamespaceAlias], '\\'); + } + + /** + * Set the entity alias map + * + * @param array $entityAliasMap + * @return void + */ + public function setEntityNamespaces(array $entityNamespaces) + { + $this->_attributes['entityNamespaces'] = $entityNamespaces; + } + + /** + * Retrieves the list of registered entity namespace aliases. + * + * @return array + */ + public function getEntityNamespaces() + { + return $this->_attributes['entityNamespaces']; + } + + /** + * Gets the cache driver implementation that is used for the mapping metadata. + * + * @throws ORMException + * @return Mapping\Driver\Driver + */ + public function getMetadataDriverImpl() + { + return isset($this->_attributes['metadataDriverImpl']) ? + $this->_attributes['metadataDriverImpl'] : null; + } + + /** + * Gets the cache driver implementation that is used for the query cache (SQL cache). + * + * @return \Doctrine\Common\Cache\Cache + */ + public function getQueryCacheImpl() + { + return isset($this->_attributes['queryCacheImpl']) ? + $this->_attributes['queryCacheImpl'] : null; + } + + /** + * Sets the cache driver implementation that is used for the query cache (SQL cache). + * + * @param \Doctrine\Common\Cache\Cache $cacheImpl + */ + public function setQueryCacheImpl(Cache $cacheImpl) + { + $this->_attributes['queryCacheImpl'] = $cacheImpl; + } + + /** + * Gets the cache driver implementation that is used for the hydration cache (SQL cache). + * + * @return \Doctrine\Common\Cache\Cache + */ + public function getHydrationCacheImpl() + { + return isset($this->_attributes['hydrationCacheImpl']) + ? $this->_attributes['hydrationCacheImpl'] + : null; + } + + /** + * Sets the cache driver implementation that is used for the hydration cache (SQL cache). + * + * @param \Doctrine\Common\Cache\Cache $cacheImpl + */ + public function setHydrationCacheImpl(Cache $cacheImpl) + { + $this->_attributes['hydrationCacheImpl'] = $cacheImpl; + } + + /** + * Gets the cache driver implementation that is used for metadata caching. + * + * @return \Doctrine\Common\Cache\Cache + */ + public function getMetadataCacheImpl() + { + return isset($this->_attributes['metadataCacheImpl']) ? + $this->_attributes['metadataCacheImpl'] : null; + } + + /** + * Sets the cache driver implementation that is used for metadata caching. + * + * @param \Doctrine\Common\Cache\Cache $cacheImpl + */ + public function setMetadataCacheImpl(Cache $cacheImpl) + { + $this->_attributes['metadataCacheImpl'] = $cacheImpl; + } + + /** + * Adds a named DQL query to the configuration. + * + * @param string $name The name of the query. + * @param string $dql The DQL query string. + */ + public function addNamedQuery($name, $dql) + { + $this->_attributes['namedQueries'][$name] = $dql; + } + + /** + * Gets a previously registered named DQL query. + * + * @param string $name The name of the query. + * @return string The DQL query. + */ + public function getNamedQuery($name) + { + if ( ! isset($this->_attributes['namedQueries'][$name])) { + throw ORMException::namedQueryNotFound($name); + } + return $this->_attributes['namedQueries'][$name]; + } + + /** + * Adds a named native query to the configuration. + * + * @param string $name The name of the query. + * @param string $sql The native SQL query string. + * @param ResultSetMapping $rsm The ResultSetMapping used for the results of the SQL query. + */ + public function addNamedNativeQuery($name, $sql, Query\ResultSetMapping $rsm) + { + $this->_attributes['namedNativeQueries'][$name] = array($sql, $rsm); + } + + /** + * Gets the components of a previously registered named native query. + * + * @param string $name The name of the query. + * @return array A tuple with the first element being the SQL string and the second + * element being the ResultSetMapping. + */ + public function getNamedNativeQuery($name) + { + if ( ! isset($this->_attributes['namedNativeQueries'][$name])) { + throw ORMException::namedNativeQueryNotFound($name); + } + return $this->_attributes['namedNativeQueries'][$name]; + } + + /** + * Ensures that this Configuration instance contains settings that are + * suitable for a production environment. + * + * @throws ORMException If a configuration setting has a value that is not + * suitable for a production environment. + */ + public function ensureProductionSettings() + { + if ( !$this->getQueryCacheImpl()) { + throw ORMException::queryCacheNotConfigured(); + } + if ( !$this->getMetadataCacheImpl()) { + throw ORMException::metadataCacheNotConfigured(); + } + if ($this->getAutoGenerateProxyClasses()) { + throw ORMException::proxyClassesAlwaysRegenerating(); + } + } + + /** + * Registers a custom DQL function that produces a string value. + * Such a function can then be used in any DQL statement in any place where string + * functions are allowed. + * + * DQL function names are case-insensitive. + * + * @param string $name + * @param string $className + */ + public function addCustomStringFunction($name, $className) + { + $this->_attributes['customStringFunctions'][strtolower($name)] = $className; + } + + /** + * Gets the implementation class name of a registered custom string DQL function. + * + * @param string $name + * @return string + */ + public function getCustomStringFunction($name) + { + $name = strtolower($name); + return isset($this->_attributes['customStringFunctions'][$name]) ? + $this->_attributes['customStringFunctions'][$name] : null; + } + + /** + * Sets a map of custom DQL string functions. + * + * Keys must be function names and values the FQCN of the implementing class. + * The function names will be case-insensitive in DQL. + * + * Any previously added string functions are discarded. + * + * @param array $functions The map of custom DQL string functions. + */ + public function setCustomStringFunctions(array $functions) + { + $this->_attributes['customStringFunctions'] = array_change_key_case($functions); + } + + /** + * Registers a custom DQL function that produces a numeric value. + * Such a function can then be used in any DQL statement in any place where numeric + * functions are allowed. + * + * DQL function names are case-insensitive. + * + * @param string $name + * @param string $className + */ + public function addCustomNumericFunction($name, $className) + { + $this->_attributes['customNumericFunctions'][strtolower($name)] = $className; + } + + /** + * Gets the implementation class name of a registered custom numeric DQL function. + * + * @param string $name + * @return string + */ + public function getCustomNumericFunction($name) + { + $name = strtolower($name); + return isset($this->_attributes['customNumericFunctions'][$name]) ? + $this->_attributes['customNumericFunctions'][$name] : null; + } + + /** + * Sets a map of custom DQL numeric functions. + * + * Keys must be function names and values the FQCN of the implementing class. + * The function names will be case-insensitive in DQL. + * + * Any previously added numeric functions are discarded. + * + * @param array $functions The map of custom DQL numeric functions. + */ + public function setCustomNumericFunctions(array $functions) + { + $this->_attributes['customNumericFunctions'] = array_change_key_case($functions); + } + + /** + * Registers a custom DQL function that produces a date/time value. + * Such a function can then be used in any DQL statement in any place where date/time + * functions are allowed. + * + * DQL function names are case-insensitive. + * + * @param string $name + * @param string $className + */ + public function addCustomDatetimeFunction($name, $className) + { + $this->_attributes['customDatetimeFunctions'][strtolower($name)] = $className; + } + + /** + * Gets the implementation class name of a registered custom date/time DQL function. + * + * @param string $name + * @return string + */ + public function getCustomDatetimeFunction($name) + { + $name = strtolower($name); + return isset($this->_attributes['customDatetimeFunctions'][$name]) ? + $this->_attributes['customDatetimeFunctions'][$name] : null; + } + + /** + * Sets a map of custom DQL date/time functions. + * + * Keys must be function names and values the FQCN of the implementing class. + * The function names will be case-insensitive in DQL. + * + * Any previously added date/time functions are discarded. + * + * @param array $functions The map of custom DQL date/time functions. + */ + public function setCustomDatetimeFunctions(array $functions) + { + $this->_attributes['customDatetimeFunctions'] = array_change_key_case($functions); + } + + /** + * Get the hydrator class for the given hydration mode name. + * + * @param string $modeName The hydration mode name. + * @return string $hydrator The hydrator class name. + */ + public function getCustomHydrationMode($modeName) + { + return isset($this->_attributes['customHydrationModes'][$modeName]) ? + $this->_attributes['customHydrationModes'][$modeName] : null; + } + + /** + * Add a custom hydration mode. + * + * @param string $modeName The hydration mode name. + * @param string $hydrator The hydrator class name. + */ + public function addCustomHydrationMode($modeName, $hydrator) + { + $this->_attributes['customHydrationModes'][$modeName] = $hydrator; + } + + /** + * Set a class metadata factory. + * + * @param string $cmf + */ + public function setClassMetadataFactoryName($cmfName) + { + $this->_attributes['classMetadataFactoryName'] = $cmfName; + } + + /** + * @return string + */ + public function getClassMetadataFactoryName() + { + if (!isset($this->_attributes['classMetadataFactoryName'])) { + $this->_attributes['classMetadataFactoryName'] = 'Doctrine\ORM\Mapping\ClassMetadataFactory'; + } + return $this->_attributes['classMetadataFactoryName']; + } + + /** + * Add a filter to the list of possible filters. + * + * @param string $name The name of the filter. + * @param string $className The class name of the filter. + */ + public function addFilter($name, $className) + { + $this->_attributes['filters'][$name] = $className; + } + + /** + * Gets the class name for a given filter name. + * + * @param string $name The name of the filter. + * + * @return string The class name of the filter, or null of it is not + * defined. + */ + public function getFilterClassName($name) + { + return isset($this->_attributes['filters'][$name]) ? + $this->_attributes['filters'][$name] : null; + } + + /** + * Set default repository class. + * + * @since 2.2 + * @param string $className + * @throws ORMException If not is a \Doctrine\ORM\EntityRepository + */ + public function setDefaultRepositoryClassName($className) + { + if ($className != "Doctrine\ORM\EntityRepository" && + !is_subclass_of($className, 'Doctrine\ORM\EntityRepository')){ + throw ORMException::invalidEntityRepository($className); + } + $this->_attributes['defaultRepositoryClassName'] = $className; + } + + /** + * Get default repository class. + * + * @since 2.2 + * @return string + */ + public function getDefaultRepositoryClassName() + { + return isset($this->_attributes['defaultRepositoryClassName']) ? + $this->_attributes['defaultRepositoryClassName'] : 'Doctrine\ORM\EntityRepository'; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php b/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php new file mode 100644 index 0000000..ab3e4c7 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php @@ -0,0 +1,834 @@ +. + */ + +namespace Doctrine\ORM; + +use Closure, Exception, + Doctrine\Common\EventManager, + Doctrine\Common\Persistence\ObjectManager, + Doctrine\DBAL\Connection, + Doctrine\DBAL\LockMode, + Doctrine\ORM\Mapping\ClassMetadata, + Doctrine\ORM\Mapping\ClassMetadataFactory, + Doctrine\ORM\Query\ResultSetMapping, + Doctrine\ORM\Proxy\ProxyFactory, + Doctrine\ORM\Query\FilterCollection; + +/** + * The EntityManager is the central access point to ORM functionality. + * + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class EntityManager implements ObjectManager +{ + /** + * The used Configuration. + * + * @var \Doctrine\ORM\Configuration + */ + private $config; + + /** + * The database connection used by the EntityManager. + * + * @var \Doctrine\DBAL\Connection + */ + private $conn; + + /** + * The metadata factory, used to retrieve the ORM metadata of entity classes. + * + * @var \Doctrine\ORM\Mapping\ClassMetadataFactory + */ + private $metadataFactory; + + /** + * The EntityRepository instances. + * + * @var array + */ + private $repositories = array(); + + /** + * The UnitOfWork used to coordinate object-level transactions. + * + * @var \Doctrine\ORM\UnitOfWork + */ + private $unitOfWork; + + /** + * The event manager that is the central point of the event system. + * + * @var \Doctrine\Common\EventManager + */ + private $eventManager; + + /** + * The maintained (cached) hydrators. One instance per type. + * + * @var array + */ + private $hydrators = array(); + + /** + * The proxy factory used to create dynamic proxies. + * + * @var \Doctrine\ORM\Proxy\ProxyFactory + */ + private $proxyFactory; + + /** + * The expression builder instance used to generate query expressions. + * + * @var \Doctrine\ORM\Query\Expr + */ + private $expressionBuilder; + + /** + * Whether the EntityManager is closed or not. + * + * @var bool + */ + private $closed = false; + + /** + * Collection of query filters. + * + * @var Doctrine\ORM\Query\FilterCollection + */ + private $filterCollection; + + /** + * Creates a new EntityManager that operates on the given database connection + * and uses the given Configuration and EventManager implementations. + * + * @param \Doctrine\DBAL\Connection $conn + * @param \Doctrine\ORM\Configuration $config + * @param \Doctrine\Common\EventManager $eventManager + */ + protected function __construct(Connection $conn, Configuration $config, EventManager $eventManager) + { + $this->conn = $conn; + $this->config = $config; + $this->eventManager = $eventManager; + + $metadataFactoryClassName = $config->getClassMetadataFactoryName(); + $this->metadataFactory = new $metadataFactoryClassName; + $this->metadataFactory->setEntityManager($this); + $this->metadataFactory->setCacheDriver($this->config->getMetadataCacheImpl()); + + $this->unitOfWork = new UnitOfWork($this); + $this->proxyFactory = new ProxyFactory( + $this, + $config->getProxyDir(), + $config->getProxyNamespace(), + $config->getAutoGenerateProxyClasses() + ); + } + + /** + * Gets the database connection object used by the EntityManager. + * + * @return \Doctrine\DBAL\Connection + */ + public function getConnection() + { + return $this->conn; + } + + /** + * Gets the metadata factory used to gather the metadata of classes. + * + * @return \Doctrine\ORM\Mapping\ClassMetadataFactory + */ + public function getMetadataFactory() + { + return $this->metadataFactory; + } + + /** + * Gets an ExpressionBuilder used for object-oriented construction of query expressions. + * + * Example: + * + * + * $qb = $em->createQueryBuilder(); + * $expr = $em->getExpressionBuilder(); + * $qb->select('u')->from('User', 'u') + * ->where($expr->orX($expr->eq('u.id', 1), $expr->eq('u.id', 2))); + * + * + * @return \Doctrine\ORM\Query\Expr + */ + public function getExpressionBuilder() + { + if ($this->expressionBuilder === null) { + $this->expressionBuilder = new Query\Expr; + } + + return $this->expressionBuilder; + } + + /** + * Starts a transaction on the underlying database connection. + * + * @deprecated Use {@link getConnection}.beginTransaction(). + */ + public function beginTransaction() + { + $this->conn->beginTransaction(); + } + + /** + * Executes a function in a transaction. + * + * The function gets passed this EntityManager instance as an (optional) parameter. + * + * {@link flush} is invoked prior to transaction commit. + * + * If an exception occurs during execution of the function or flushing or transaction commit, + * the transaction is rolled back, the EntityManager closed and the exception re-thrown. + * + * @param Closure $func The function to execute transactionally. + * @return mixed Returns the non-empty value returned from the closure or true instead + */ + public function transactional(Closure $func) + { + $this->conn->beginTransaction(); + + try { + $return = $func($this); + + $this->flush(); + $this->conn->commit(); + + return $return ?: true; + } catch (Exception $e) { + $this->close(); + $this->conn->rollback(); + + throw $e; + } + } + + /** + * Commits a transaction on the underlying database connection. + * + * @deprecated Use {@link getConnection}.commit(). + */ + public function commit() + { + $this->conn->commit(); + } + + /** + * Performs a rollback on the underlying database connection. + * + * @deprecated Use {@link getConnection}.rollback(). + */ + public function rollback() + { + $this->conn->rollback(); + } + + /** + * Returns the ORM metadata descriptor for a class. + * + * The class name must be the fully-qualified class name without a leading backslash + * (as it is returned by get_class($obj)) or an aliased class name. + * + * Examples: + * MyProject\Domain\User + * sales:PriceRequest + * + * @return \Doctrine\ORM\Mapping\ClassMetadata + * @internal Performance-sensitive method. + */ + public function getClassMetadata($className) + { + return $this->metadataFactory->getMetadataFor($className); + } + + /** + * Creates a new Query object. + * + * @param string The DQL string. + * @return \Doctrine\ORM\Query + */ + public function createQuery($dql = "") + { + $query = new Query($this); + + if ( ! empty($dql)) { + $query->setDql($dql); + } + + return $query; + } + + /** + * Creates a Query from a named query. + * + * @param string $name + * @return \Doctrine\ORM\Query + */ + public function createNamedQuery($name) + { + return $this->createQuery($this->config->getNamedQuery($name)); + } + + /** + * Creates a native SQL query. + * + * @param string $sql + * @param ResultSetMapping $rsm The ResultSetMapping to use. + * @return NativeQuery + */ + public function createNativeQuery($sql, ResultSetMapping $rsm) + { + $query = new NativeQuery($this); + $query->setSql($sql); + $query->setResultSetMapping($rsm); + + return $query; + } + + /** + * Creates a NativeQuery from a named native query. + * + * @param string $name + * @return \Doctrine\ORM\NativeQuery + */ + public function createNamedNativeQuery($name) + { + list($sql, $rsm) = $this->config->getNamedNativeQuery($name); + + return $this->createNativeQuery($sql, $rsm); + } + + /** + * Create a QueryBuilder instance + * + * @return QueryBuilder $qb + */ + public function createQueryBuilder() + { + return new QueryBuilder($this); + } + + /** + * Flushes all changes to objects that have been queued up to now to the database. + * This effectively synchronizes the in-memory state of managed objects with the + * database. + * + * If an entity is explicitly passed to this method only this entity and + * the cascade-persist semantics + scheduled inserts/removals are synchronized. + * + * @param object $entity + * @throws \Doctrine\ORM\OptimisticLockException If a version check on an entity that + * makes use of optimistic locking fails. + */ + public function flush($entity = null) + { + $this->errorIfClosed(); + + $this->unitOfWork->commit($entity); + } + + /** + * Finds an Entity by its identifier. + * + * This is just a convenient shortcut for getRepository($entityName)->find($id). + * + * @param string $entityName + * @param mixed $identifier + * @param int $lockMode + * @param int $lockVersion + * @return object + */ + public function find($entityName, $identifier, $lockMode = LockMode::NONE, $lockVersion = null) + { + return $this->getRepository($entityName)->find($identifier, $lockMode, $lockVersion); + } + + /** + * Gets a reference to the entity identified by the given type and identifier + * without actually loading it, if the entity is not yet loaded. + * + * @param string $entityName The name of the entity type. + * @param mixed $id The entity identifier. + * @return object The entity reference. + */ + public function getReference($entityName, $id) + { + $class = $this->metadataFactory->getMetadataFor(ltrim($entityName, '\\')); + if ( ! is_array($id)) { + $id = array($class->identifier[0] => $id); + } + $sortedId = array(); + foreach ($class->identifier as $identifier) { + if (!isset($id[$identifier])) { + throw ORMException::missingIdentifierField($class->name, $identifier); + } + $sortedId[$identifier] = $id[$identifier]; + } + + // Check identity map first, if its already in there just return it. + if ($entity = $this->unitOfWork->tryGetById($sortedId, $class->rootEntityName)) { + return ($entity instanceof $class->name) ? $entity : null; + } + + if ($class->subClasses) { + return $this->find($entityName, $sortedId); + } + + if ( ! is_array($sortedId)) { + $sortedId = array($class->identifier[0] => $sortedId); + } + + $entity = $this->proxyFactory->getProxy($class->name, $sortedId); + $this->unitOfWork->registerManaged($entity, $sortedId, array()); + + return $entity; + } + + /** + * Gets a partial reference to the entity identified by the given type and identifier + * without actually loading it, if the entity is not yet loaded. + * + * The returned reference may be a partial object if the entity is not yet loaded/managed. + * If it is a partial object it will not initialize the rest of the entity state on access. + * Thus you can only ever safely access the identifier of an entity obtained through + * this method. + * + * The use-cases for partial references involve maintaining bidirectional associations + * without loading one side of the association or to update an entity without loading it. + * Note, however, that in the latter case the original (persistent) entity data will + * never be visible to the application (especially not event listeners) as it will + * never be loaded in the first place. + * + * @param string $entityName The name of the entity type. + * @param mixed $identifier The entity identifier. + * @return object The (partial) entity reference. + */ + public function getPartialReference($entityName, $identifier) + { + $class = $this->metadataFactory->getMetadataFor(ltrim($entityName, '\\')); + + // Check identity map first, if its already in there just return it. + if ($entity = $this->unitOfWork->tryGetById($identifier, $class->rootEntityName)) { + return ($entity instanceof $class->name) ? $entity : null; + } + + if ( ! is_array($identifier)) { + $identifier = array($class->identifier[0] => $identifier); + } + + $entity = $class->newInstance(); + $class->setIdentifierValues($entity, $identifier); + $this->unitOfWork->registerManaged($entity, $identifier, array()); + $this->unitOfWork->markReadOnly($entity); + + return $entity; + } + + /** + * Clears the EntityManager. All entities that are currently managed + * by this EntityManager become detached. + * + * @param string $entityName if given, only entities of this type will get detached + */ + public function clear($entityName = null) + { + $this->unitOfWork->clear($entityName); + } + + /** + * Closes the EntityManager. All entities that are currently managed + * by this EntityManager become detached. The EntityManager may no longer + * be used after it is closed. + */ + public function close() + { + $this->clear(); + $this->closed = true; + } + + /** + * Tells the EntityManager to make an instance managed and persistent. + * + * The entity will be entered into the database at or before transaction + * commit or as a result of the flush operation. + * + * NOTE: The persist operation always considers entities that are not yet known to + * this EntityManager as NEW. Do not pass detached entities to the persist operation. + * + * @param object $object The instance to make managed and persistent. + */ + public function persist($entity) + { + if ( ! is_object($entity)) { + throw new \InvalidArgumentException(gettype($entity)); + } + + $this->errorIfClosed(); + + $this->unitOfWork->persist($entity); + } + + /** + * Removes an entity instance. + * + * A removed entity will be removed from the database at or before transaction commit + * or as a result of the flush operation. + * + * @param object $entity The entity instance to remove. + */ + public function remove($entity) + { + if ( ! is_object($entity)) { + throw new \InvalidArgumentException(gettype($entity)); + } + + $this->errorIfClosed(); + + $this->unitOfWork->remove($entity); + } + + /** + * Refreshes the persistent state of an entity from the database, + * overriding any local changes that have not yet been persisted. + * + * @param object $entity The entity to refresh. + */ + public function refresh($entity) + { + if ( ! is_object($entity)) { + throw new \InvalidArgumentException(gettype($entity)); + } + + $this->errorIfClosed(); + + $this->unitOfWork->refresh($entity); + } + + /** + * Detaches an entity from the EntityManager, causing a managed entity to + * become detached. Unflushed changes made to the entity if any + * (including removal of the entity), will not be synchronized to the database. + * Entities which previously referenced the detached entity will continue to + * reference it. + * + * @param object $entity The entity to detach. + */ + public function detach($entity) + { + if ( ! is_object($entity)) { + throw new \InvalidArgumentException(gettype($entity)); + } + + $this->unitOfWork->detach($entity); + } + + /** + * Merges the state of a detached entity into the persistence context + * of this EntityManager and returns the managed copy of the entity. + * The entity passed to merge will not become associated/managed with this EntityManager. + * + * @param object $entity The detached entity to merge into the persistence context. + * @return object The managed copy of the entity. + */ + public function merge($entity) + { + if ( ! is_object($entity)) { + throw new \InvalidArgumentException(gettype($entity)); + } + + $this->errorIfClosed(); + + return $this->unitOfWork->merge($entity); + } + + /** + * Creates a copy of the given entity. Can create a shallow or a deep copy. + * + * @param object $entity The entity to copy. + * @return object The new entity. + * @todo Implementation need. This is necessary since $e2 = clone $e1; throws an E_FATAL when access anything on $e: + * Fatal error: Maximum function nesting level of '100' reached, aborting! + */ + public function copy($entity, $deep = false) + { + throw new \BadMethodCallException("Not implemented."); + } + + /** + * Acquire a lock on the given entity. + * + * @param object $entity + * @param int $lockMode + * @param int $lockVersion + * @throws OptimisticLockException + * @throws PessimisticLockException + */ + public function lock($entity, $lockMode, $lockVersion = null) + { + $this->unitOfWork->lock($entity, $lockMode, $lockVersion); + } + + /** + * Gets the repository for an entity class. + * + * @param string $entityName The name of the entity. + * @return EntityRepository The repository class. + */ + public function getRepository($entityName) + { + $entityName = ltrim($entityName, '\\'); + + if (isset($this->repositories[$entityName])) { + return $this->repositories[$entityName]; + } + + $metadata = $this->getClassMetadata($entityName); + $repositoryClassName = $metadata->customRepositoryClassName; + + if ($repositoryClassName === null) { + $repositoryClassName = $this->config->getDefaultRepositoryClassName(); + } + + $repository = new $repositoryClassName($this, $metadata); + + $this->repositories[$entityName] = $repository; + + return $repository; + } + + /** + * Determines whether an entity instance is managed in this EntityManager. + * + * @param object $entity + * @return boolean TRUE if this EntityManager currently manages the given entity, FALSE otherwise. + */ + public function contains($entity) + { + return $this->unitOfWork->isScheduledForInsert($entity) + || $this->unitOfWork->isInIdentityMap($entity) + && ! $this->unitOfWork->isScheduledForDelete($entity); + } + + /** + * Gets the EventManager used by the EntityManager. + * + * @return \Doctrine\Common\EventManager + */ + public function getEventManager() + { + return $this->eventManager; + } + + /** + * Gets the Configuration used by the EntityManager. + * + * @return \Doctrine\ORM\Configuration + */ + public function getConfiguration() + { + return $this->config; + } + + /** + * Throws an exception if the EntityManager is closed or currently not active. + * + * @throws ORMException If the EntityManager is closed. + */ + private function errorIfClosed() + { + if ($this->closed) { + throw ORMException::entityManagerClosed(); + } + } + + /** + * Check if the Entity manager is open or closed. + * + * @return bool + */ + public function isOpen() + { + return (!$this->closed); + } + + /** + * Gets the UnitOfWork used by the EntityManager to coordinate operations. + * + * @return \Doctrine\ORM\UnitOfWork + */ + public function getUnitOfWork() + { + return $this->unitOfWork; + } + + /** + * Gets a hydrator for the given hydration mode. + * + * This method caches the hydrator instances which is used for all queries that don't + * selectively iterate over the result. + * + * @param int $hydrationMode + * @return \Doctrine\ORM\Internal\Hydration\AbstractHydrator + */ + public function getHydrator($hydrationMode) + { + if ( ! isset($this->hydrators[$hydrationMode])) { + $this->hydrators[$hydrationMode] = $this->newHydrator($hydrationMode); + } + + return $this->hydrators[$hydrationMode]; + } + + /** + * Create a new instance for the given hydration mode. + * + * @param int $hydrationMode + * @return \Doctrine\ORM\Internal\Hydration\AbstractHydrator + */ + public function newHydrator($hydrationMode) + { + switch ($hydrationMode) { + case Query::HYDRATE_OBJECT: + return new Internal\Hydration\ObjectHydrator($this); + + case Query::HYDRATE_ARRAY: + return new Internal\Hydration\ArrayHydrator($this); + + case Query::HYDRATE_SCALAR: + return new Internal\Hydration\ScalarHydrator($this); + + case Query::HYDRATE_SINGLE_SCALAR: + return new Internal\Hydration\SingleScalarHydrator($this); + + case Query::HYDRATE_SIMPLEOBJECT: + return new Internal\Hydration\SimpleObjectHydrator($this); + + default: + if ($class = $this->config->getCustomHydrationMode($hydrationMode)) { + return new $class($this); + } + } + + throw ORMException::invalidHydrationMode($hydrationMode); + } + + /** + * Gets the proxy factory used by the EntityManager to create entity proxies. + * + * @return ProxyFactory + */ + public function getProxyFactory() + { + return $this->proxyFactory; + } + + /** + * Helper method to initialize a lazy loading proxy or persistent collection. + * + * This method is a no-op for other objects + * + * @param object $obj + */ + public function initializeObject($obj) + { + $this->unitOfWork->initializeObject($obj); + } + + /** + * Factory method to create EntityManager instances. + * + * @param mixed $conn An array with the connection parameters or an existing + * Connection instance. + * @param Configuration $config The Configuration instance to use. + * @param EventManager $eventManager The EventManager instance to use. + * @return EntityManager The created EntityManager. + */ + public static function create($conn, Configuration $config, EventManager $eventManager = null) + { + if ( ! $config->getMetadataDriverImpl()) { + throw ORMException::missingMappingDriverImpl(); + } + + switch (true) { + case (is_array($conn)): + $conn = \Doctrine\DBAL\DriverManager::getConnection( + $conn, $config, ($eventManager ?: new EventManager()) + ); + break; + + case ($conn instanceof Connection): + if ($eventManager !== null && $conn->getEventManager() !== $eventManager) { + throw ORMException::mismatchedEventManager(); + } + break; + + default: + throw new \InvalidArgumentException("Invalid argument: " . $conn); + } + + return new EntityManager($conn, $config, $conn->getEventManager()); + } + + /** + * Gets the enabled filters. + * + * @return FilterCollection The active filter collection. + */ + public function getFilters() + { + if (null === $this->filterCollection) { + $this->filterCollection = new FilterCollection($this); + } + + return $this->filterCollection; + } + + /** + * Checks whether the state of the filter collection is clean. + * + * @return boolean True, if the filter collection is clean. + */ + public function isFiltersStateClean() + { + return null === $this->filterCollection + || $this->filterCollection->isClean(); + } + + /** + * Checks whether the Entity Manager has filters. + * + * @return True, if the EM has a filter collection. + */ + public function hasFilters() + { + return null !== $this->filterCollection; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/EntityNotFoundException.php b/vendor/doctrine/orm/lib/Doctrine/ORM/EntityNotFoundException.php new file mode 100644 index 0000000..2e58132 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/EntityNotFoundException.php @@ -0,0 +1,34 @@ +. + */ + +namespace Doctrine\ORM; + +/** + * Exception thrown when a Proxy fails to retrieve an Entity result. + * + * @author robo + * @since 2.0 + */ +class EntityNotFoundException extends ORMException +{ + public function __construct() + { + parent::__construct('Entity was not found.'); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php b/vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php new file mode 100644 index 0000000..17cc298 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php @@ -0,0 +1,265 @@ +. + */ + +namespace Doctrine\ORM; + +use Doctrine\DBAL\LockMode; +use Doctrine\Common\Persistence\ObjectRepository; + +/** + * An EntityRepository serves as a repository for entities with generic as well as + * business specific methods for retrieving entities. + * + * This class is designed for inheritance and users can subclass this class to + * write their own repositories with business-specific methods to locate entities. + * + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class EntityRepository implements ObjectRepository +{ + /** + * @var string + */ + protected $_entityName; + + /** + * @var EntityManager + */ + protected $_em; + + /** + * @var \Doctrine\ORM\Mapping\ClassMetadata + */ + protected $_class; + + /** + * Initializes a new EntityRepository. + * + * @param EntityManager $em The EntityManager to use. + * @param ClassMetadata $classMetadata The class descriptor. + */ + public function __construct($em, Mapping\ClassMetadata $class) + { + $this->_entityName = $class->name; + $this->_em = $em; + $this->_class = $class; + } + + /** + * Create a new QueryBuilder instance that is prepopulated for this entity name + * + * @param string $alias + * @return QueryBuilder $qb + */ + public function createQueryBuilder($alias) + { + return $this->_em->createQueryBuilder() + ->select($alias) + ->from($this->_entityName, $alias); + } + + /** + * Create a new Query instance based on a predefined metadata named query. + * + * @param string $queryName + * @return Query + */ + public function createNamedQuery($queryName) + { + return $this->_em->createQuery($this->_class->getNamedQuery($queryName)); + } + + /** + * Clears the repository, causing all managed entities to become detached. + */ + public function clear() + { + $this->_em->clear($this->_class->rootEntityName); + } + + /** + * Finds an entity by its primary key / identifier. + * + * @param $id The identifier. + * @param int $lockMode + * @param int $lockVersion + * @return object The entity. + */ + public function find($id, $lockMode = LockMode::NONE, $lockVersion = null) + { + if ( ! is_array($id)) { + $id = array($this->_class->identifier[0] => $id); + } + $sortedId = array(); + foreach ($this->_class->identifier as $identifier) { + if (!isset($id[$identifier])) { + throw ORMException::missingIdentifierField($this->_class->name, $identifier); + } + $sortedId[$identifier] = $id[$identifier]; + } + + // Check identity map first + if ($entity = $this->_em->getUnitOfWork()->tryGetById($sortedId, $this->_class->rootEntityName)) { + if ( ! ($entity instanceof $this->_class->name)) { + return null; + } + + if ($lockMode !== LockMode::NONE) { + $this->_em->lock($entity, $lockMode, $lockVersion); + } + + return $entity; // Hit! + } + + switch ($lockMode) { + case LockMode::NONE: + return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($sortedId); + + case LockMode::OPTIMISTIC: + if ( ! $this->_class->isVersioned) { + throw OptimisticLockException::notVersioned($this->_entityName); + } + + $entity = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($sortedId); + + $this->_em->getUnitOfWork()->lock($entity, $lockMode, $lockVersion); + + return $entity; + + default: + if ( ! $this->_em->getConnection()->isTransactionActive()) { + throw TransactionRequiredException::transactionRequired(); + } + + return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($sortedId, null, null, array(), $lockMode); + } + } + + /** + * Finds all entities in the repository. + * + * @return array The entities. + */ + public function findAll() + { + return $this->findBy(array()); + } + + /** + * Finds entities by a set of criteria. + * + * @param array $criteria + * @param array|null $orderBy + * @param int|null $limit + * @param int|null $offset + * @return array The objects. + */ + public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) + { + return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->loadAll($criteria, $orderBy, $limit, $offset); + } + + /** + * Finds a single entity by a set of criteria. + * + * @param array $criteria + * @return object + */ + public function findOneBy(array $criteria) + { + return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($criteria, null, null, array(), 0, 1); + } + + /** + * Adds support for magic finders. + * + * @return array|object The found entity/entities. + * @throws BadMethodCallException If the method called is an invalid find* method + * or no find* method at all and therefore an invalid + * method call. + */ + public function __call($method, $arguments) + { + switch (true) { + case (substr($method, 0, 6) == 'findBy'): + $by = substr($method, 6, strlen($method)); + $method = 'findBy'; + break; + + case (substr($method, 0, 9) == 'findOneBy'): + $by = substr($method, 9, strlen($method)); + $method = 'findOneBy'; + break; + + default: + throw new \BadMethodCallException( + "Undefined method '$method'. The method name must start with ". + "either findBy or findOneBy!" + ); + } + + if (empty($arguments)) { + throw ORMException::findByRequiresParameter($method . $by); + } + + $fieldName = lcfirst(\Doctrine\Common\Util\Inflector::classify($by)); + + if ($this->_class->hasField($fieldName) || $this->_class->hasAssociation($fieldName)) { + return $this->$method(array($fieldName => $arguments[0])); + } + + throw ORMException::invalidFindByCall($this->_entityName, $fieldName, $method.$by); + } + + /** + * @return string + */ + protected function getEntityName() + { + return $this->_entityName; + } + + /** + * @return string + */ + public function getClassName() + { + return $this->getEntityName(); + } + + /** + * @return EntityManager + */ + protected function getEntityManager() + { + return $this->_em; + } + + /** + * @return Mapping\ClassMetadata + */ + protected function getClassMetadata() + { + return $this->_class; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Event/LifecycleEventArgs.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Event/LifecycleEventArgs.php new file mode 100644 index 0000000..6740a3e --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Event/LifecycleEventArgs.php @@ -0,0 +1,77 @@ +. +*/ + +namespace Doctrine\ORM\Event; + +use Doctrine\Common\EventArgs; +use Doctrine\ORM\EntityManager; + +/** + * Lifecycle Events are triggered by the UnitOfWork during lifecycle transitions + * of entities. + * + * @link www.doctrine-project.org + * @since 2.0 + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class LifecycleEventArgs extends EventArgs +{ + /** + * @var \Doctrine\ORM\EntityManager + */ + private $em; + + /** + * @var object + */ + private $entity; + + /** + * Constructor + * + * @param object $entity + * @param \Doctrine\ORM\EntityManager $em + */ + public function __construct($entity, EntityManager $em) + { + $this->entity = $entity; + $this->em = $em; + } + + /** + * Retireve associated Entity. + * + * @return object + */ + public function getEntity() + { + return $this->entity; + } + + /** + * Retrieve associated EntityManager. + * + * @return \Doctrine\ORM\EntityManager + */ + public function getEntityManager() + { + return $this->em; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Event/LoadClassMetadataEventArgs.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Event/LoadClassMetadataEventArgs.php new file mode 100644 index 0000000..901bf3a --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Event/LoadClassMetadataEventArgs.php @@ -0,0 +1,76 @@ +. + */ + +namespace Doctrine\ORM\Event; + +use Doctrine\Common\EventArgs; +use Doctrine\ORM\Mapping\ClassMetadataInfo; +use Doctrine\ORM\EntityManager; + +/** + * Class that holds event arguments for a loadMetadata event. + * + * @author Jonathan H. Wage + * @since 2.0 + */ +class LoadClassMetadataEventArgs extends EventArgs +{ + /** + * @var \Doctrine\ORM\Mapping\ClassMetadata + */ + private $classMetadata; + + /** + * @var \Doctrine\ORM\EntityManager + */ + private $em; + + /** + * Constructor. + * + * @param \Doctrine\ORM\Mapping\ClassMetadataInfo $classMetadata + * @param \Doctrine\ORM\EntityManager $em + */ + public function __construct(ClassMetadataInfo $classMetadata, EntityManager $em) + { + $this->classMetadata = $classMetadata; + $this->em = $em; + } + + /** + * Retrieve associated ClassMetadata. + * + * @return \Doctrine\ORM\Mapping\ClassMetadataInfo + */ + public function getClassMetadata() + { + return $this->classMetadata; + } + + /** + * Retrieve associated EntityManager. + * + * @return \Doctrine\ORM\EntityManager + */ + public function getEntityManager() + { + return $this->em; + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Event/OnClearEventArgs.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Event/OnClearEventArgs.php new file mode 100644 index 0000000..542ac45 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Event/OnClearEventArgs.php @@ -0,0 +1,84 @@ +. + */ + +namespace Doctrine\ORM\Event; + +/** + * Provides event arguments for the onClear event. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class OnClearEventArgs extends \Doctrine\Common\EventArgs +{ + /** + * @var \Doctrine\ORM\EntityManager + */ + private $em; + + /** + * @var string + */ + private $entityClass; + + /** + * Constructor. + * + * @param \Doctrine\ORM\EntityManager $em + * @param string $entityClass Optional entity class + */ + public function __construct($em, $entityClass = null) + { + $this->em = $em; + $this->entityClass = $entityClass; + } + + /** + * Retrieve associated EntityManager. + * + * @return \Doctrine\ORM\EntityManager + */ + public function getEntityManager() + { + return $this->em; + } + + /** + * Name of the entity class that is cleared, or empty if all are cleared. + * + * @return string + */ + public function getEntityClass() + { + return $this->entityClass; + } + + /** + * Check if event clears all entities. + * + * @return bool + */ + public function clearsAllEntities() + { + return ($this->entityClass === null); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Event/OnFlushEventArgs.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Event/OnFlushEventArgs.php new file mode 100644 index 0000000..c4aeb2a --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Event/OnFlushEventArgs.php @@ -0,0 +1,86 @@ +. +*/ + +namespace Doctrine\ORM\Event; + +use Doctrine\ORM\EntityManager; + +/** + * Provides event arguments for the preFlush event. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class OnFlushEventArgs extends \Doctrine\Common\EventArgs +{ + /** + * @var Doctirne\ORM\EntityManager + */ + private $em; + + //private $entitiesToPersist = array(); + //private $entitiesToRemove = array(); + + /** + * Constructor. + * + * @param \Doctrine\ORM\EntityManager $em + */ + public function __construct(EntityManager $em) + { + $this->em = $em; + } + + /** + * Retrieve associated EntityManager. + * + * @return \Doctrine\ORM\EntityManager + */ + public function getEntityManager() + { + return $this->em; + } + + /* + public function addEntityToPersist($entity) + { + + } + + public function addEntityToRemove($entity) + { + + } + + public function addEntityToUpdate($entity) + { + + } + + public function getEntitiesToPersist() + { + return $this->_entitiesToPersist; + } + */ +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Event/PostFlushEventArgs.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Event/PostFlushEventArgs.php new file mode 100644 index 0000000..f45030d --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Event/PostFlushEventArgs.php @@ -0,0 +1,61 @@ +. + */ + +namespace Doctrine\ORM\Event; + +use Doctrine\ORM\EntityManager; +use Doctrine\Common\EventArgs; + +/** + * Provides event arguments for the postFlush event. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Daniel Freudenberger + */ +class PostFlushEventArgs extends EventArgs +{ + /** + * @var \Doctrine\ORM\EntityManager + */ + private $em; + + /** + * Constructor. + * + * @param \Doctrine\ORM\EntityManager $em + */ + public function __construct(EntityManager $em) + { + $this->em = $em; + } + + /** + * Retrieve associated EntityManager. + * + * @return \Doctrine\ORM\EntityManager + */ + public function getEntityManager() + { + return $this->em; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Event/PreFlushEventArgs.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Event/PreFlushEventArgs.php new file mode 100644 index 0000000..b86967a --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Event/PreFlushEventArgs.php @@ -0,0 +1,53 @@ +. +*/ + +namespace Doctrine\ORM\Event; + +/** + * Provides event arguments for the preFlush event. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.0 + * @version $Revision$ + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class PreFlushEventArgs extends \Doctrine\Common\EventArgs +{ + /** + * @var EntityManager + */ + private $_em; + + public function __construct($em) + { + $this->_em = $em; + } + + /** + * @return EntityManager + */ + public function getEntityManager() + { + return $this->_em; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Event/PreUpdateEventArgs.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Event/PreUpdateEventArgs.php new file mode 100644 index 0000000..0bebba1 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Event/PreUpdateEventArgs.php @@ -0,0 +1,131 @@ +. + */ + +namespace Doctrine\ORM\Event; + +use Doctrine\Common\EventArgs, + Doctrine\ORM\EntityManager; + +/** + * Class that holds event arguments for a preInsert/preUpdate event. + * + * @author Guilherme Blanco + * @author Roman Borschel + * @author Benjamin Eberlei + * @since 2.0 + */ +class PreUpdateEventArgs extends LifecycleEventArgs +{ + /** + * @var array + */ + private $entityChangeSet; + + /** + * Constructor. + * + * @param object $entity + * @param \Doctrine\ORM\EntityManager $em + * @param array $changeSet + */ + public function __construct($entity, EntityManager $em, array &$changeSet) + { + parent::__construct($entity, $em); + + $this->entityChangeSet = &$changeSet; + } + + /** + * Retrieve entity changeset. + * + * @return array + */ + public function getEntityChangeSet() + { + return $this->entityChangeSet; + } + + /** + * Check if field has a changeset. + * + * @return boolean + */ + public function hasChangedField($field) + { + return isset($this->entityChangeSet[$field]); + } + + /** + * Get the old value of the changeset of the changed field. + * + * @param string $field + * @return mixed + */ + public function getOldValue($field) + { + $this->assertValidField($field); + + return $this->entityChangeSet[$field][0]; + } + + /** + * Get the new value of the changeset of the changed field. + * + * @param string $field + * @return mixed + */ + public function getNewValue($field) + { + $this->assertValidField($field); + + return $this->entityChangeSet[$field][1]; + } + + /** + * Set the new value of this field. + * + * @param string $field + * @param mixed $value + */ + public function setNewValue($field, $value) + { + $this->assertValidField($field); + + $this->entityChangeSet[$field][1] = $value; + } + + /** + * Assert the field exists in changeset. + * + * @param string $field + */ + private function assertValidField($field) + { + if ( ! isset($this->entityChangeSet[$field])) { + throw new \InvalidArgumentException(sprintf( + 'Field "%s" is not a valid field of the entity "%s" in PreUpdateEventArgs.', + $field, + get_class($this->getEntity()) + )); + } + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Events.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Events.php new file mode 100644 index 0000000..45424e7 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Events.php @@ -0,0 +1,148 @@ +. + */ + +namespace Doctrine\ORM; + +/** + * Container for all ORM events. + * + * This class cannot be instantiated. + * + * @author Roman Borschel + * @since 2.0 + */ +final class Events +{ + private function __construct() {} + /** + * The preRemove event occurs for a given entity before the respective + * EntityManager remove operation for that entity is executed. + * + * This is an entity lifecycle event. + * + * @var string + */ + const preRemove = 'preRemove'; + /** + * The postRemove event occurs for an entity after the entity has + * been deleted. It will be invoked after the database delete operations. + * + * This is an entity lifecycle event. + * + * @var string + */ + const postRemove = 'postRemove'; + /** + * The prePersist event occurs for a given entity before the respective + * EntityManager persist operation for that entity is executed. + * + * This is an entity lifecycle event. + * + * @var string + */ + const prePersist = 'prePersist'; + /** + * The postPersist event occurs for an entity after the entity has + * been made persistent. It will be invoked after the database insert operations. + * Generated primary key values are available in the postPersist event. + * + * This is an entity lifecycle event. + * + * @var string + */ + const postPersist = 'postPersist'; + /** + * The preUpdate event occurs before the database update operations to + * entity data. + * + * This is an entity lifecycle event. + * + * @var string + */ + const preUpdate = 'preUpdate'; + /** + * The postUpdate event occurs after the database update operations to + * entity data. + * + * This is an entity lifecycle event. + * + * @var string + */ + const postUpdate = 'postUpdate'; + /** + * The postLoad event occurs for an entity after the entity has been loaded + * into the current EntityManager from the database or after the refresh operation + * has been applied to it. + * + * Note that the postLoad event occurs for an entity before any associations have been + * initialized. Therefore it is not safe to access associations in a postLoad callback + * or event handler. + * + * This is an entity lifecycle event. + * + * @var string + */ + const postLoad = 'postLoad'; + /** + * The loadClassMetadata event occurs after the mapping metadata for a class + * has been loaded from a mapping source (annotations/xml/yaml). + * + * @var string + */ + const loadClassMetadata = 'loadClassMetadata'; + + /** + * The preFlush event occurs when the EntityManager#flush() operation is invoked, + * but before any changes to managed entites have been calculated. This event is + * always raised right after EntityManager#flush() call. + */ + const preFlush = 'preFlush'; + + /** + * The onFlush event occurs when the EntityManager#flush() operation is invoked, + * after any changes to managed entities have been determined but before any + * actual database operations are executed. The event is only raised if there is + * actually something to do for the underlying UnitOfWork. If nothing needs to be done, + * the onFlush event is not raised. + * + * @var string + */ + const onFlush = 'onFlush'; + + /** + * The postFlush event occurs when the EntityManager#flush() operation is invoked and + * after all actual database operations are executed successfully. The event is only raised if there is + * actually something to do for the underlying UnitOfWork. If nothing needs to be done, + * the postFlush event is not raised. The event won't be raised if an error occurs during the + * flush operation. + * + * @var string + */ + const postFlush = 'postFlush'; + + /** + * The onClear event occurs when the EntityManager#clear() operation is invoked, + * after all references to entities have been removed from the unit of work. + * + * @var string + */ + const onClear = 'onClear'; +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Id/AbstractIdGenerator.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Id/AbstractIdGenerator.php new file mode 100644 index 0000000..d27c00b --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Id/AbstractIdGenerator.php @@ -0,0 +1,48 @@ +. + */ + +namespace Doctrine\ORM\Id; + +use Doctrine\ORM\EntityManager; + +abstract class AbstractIdGenerator +{ + /** + * Generates an identifier for an entity. + * + * @param \Doctrine\ORM\Entity $entity + * @return mixed + */ + abstract public function generate(EntityManager $em, $entity); + + /** + * Gets whether this generator is a post-insert generator which means that + * {@link generate()} must be called after the entity has been inserted + * into the database. + * + * By default, this method returns FALSE. Generators that have this requirement + * must override this method and return TRUE. + * + * @return boolean + */ + public function isPostInsertGenerator() + { + return false; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Id/AssignedGenerator.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Id/AssignedGenerator.php new file mode 100644 index 0000000..c9f9ada --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Id/AssignedGenerator.php @@ -0,0 +1,71 @@ +. + */ + +namespace Doctrine\ORM\Id; + +use Doctrine\ORM\EntityManager; +use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\ORM\ORMException; + +/** + * Special generator for application-assigned identifiers (doesnt really generate anything). + * + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class AssignedGenerator extends AbstractIdGenerator +{ + /** + * Returns the identifier assigned to the given entity. + * + * @param object $entity + * @return mixed + * @override + */ + public function generate(EntityManager $em, $entity) + { + $class = $em->getClassMetadata(get_class($entity)); + $idFields = $class->getIdentifierFieldNames(); + $identifier = array(); + + foreach ($idFields as $idField) { + $value = $class->reflFields[$idField]->getValue($entity); + + if ( ! isset($value)) { + throw ORMException::entityMissingAssignedIdForField($entity, $idField); + } + + if (isset($class->associationMappings[$idField])) { + if ( ! $em->getUnitOfWork()->isInIdentityMap($value)) { + throw ORMException::entityMissingForeignAssignedId($entity, $value); + } + + // NOTE: Single Columns as associated identifiers only allowed - this constraint it is enforced. + $value = current($em->getUnitOfWork()->getEntityIdentifier($value)); + } + + $identifier[$idField] = $value; + } + + return $identifier; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Id/IdentityGenerator.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Id/IdentityGenerator.php new file mode 100644 index 0000000..d244871 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Id/IdentityGenerator.php @@ -0,0 +1,59 @@ +. + */ + +namespace Doctrine\ORM\Id; + +use Doctrine\ORM\EntityManager; + +/** + * Id generator that obtains IDs from special "identity" columns. These are columns + * that automatically get a database-generated, auto-incremented identifier on INSERT. + * This generator obtains the last insert id after such an insert. + */ +class IdentityGenerator extends AbstractIdGenerator +{ + /** @var string The name of the sequence to pass to lastInsertId(), if any. */ + private $_seqName; + + /** + * @param string $seqName The name of the sequence to pass to lastInsertId() + * to obtain the last generated identifier within the current + * database session/connection, if any. + */ + public function __construct($seqName = null) + { + $this->_seqName = $seqName; + } + + /** + * {@inheritdoc} + */ + public function generate(EntityManager $em, $entity) + { + return (int)$em->getConnection()->lastInsertId($this->_seqName); + } + + /** + * {@inheritdoc} + */ + public function isPostInsertGenerator() + { + return true; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Id/SequenceGenerator.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Id/SequenceGenerator.php new file mode 100644 index 0000000..7924061 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Id/SequenceGenerator.php @@ -0,0 +1,106 @@ +. + */ + +namespace Doctrine\ORM\Id; + +use Serializable, Doctrine\ORM\EntityManager; + +/** + * Represents an ID generator that uses a database sequence. + * + * @since 2.0 + * @author Roman Borschel + */ +class SequenceGenerator extends AbstractIdGenerator implements Serializable +{ + private $_allocationSize; + private $_sequenceName; + private $_nextValue = 0; + private $_maxValue = null; + + /** + * Initializes a new sequence generator. + * + * @param \Doctrine\ORM\EntityManager $em The EntityManager to use. + * @param string $sequenceName The name of the sequence. + * @param integer $allocationSize The allocation size of the sequence. + */ + public function __construct($sequenceName, $allocationSize) + { + $this->_sequenceName = $sequenceName; + $this->_allocationSize = $allocationSize; + } + + /** + * Generates an ID for the given entity. + * + * @param object $entity + * @return integer|float The generated value. + * @override + */ + public function generate(EntityManager $em, $entity) + { + if ($this->_maxValue === null || $this->_nextValue == $this->_maxValue) { + // Allocate new values + $conn = $em->getConnection(); + $sql = $conn->getDatabasePlatform()->getSequenceNextValSQL($this->_sequenceName); + + $this->_nextValue = (int)$conn->fetchColumn($sql); + $this->_maxValue = $this->_nextValue + $this->_allocationSize; + } + + return $this->_nextValue++; + } + + /** + * Gets the maximum value of the currently allocated bag of values. + * + * @return integer|float + */ + public function getCurrentMaxValue() + { + return $this->_maxValue; + } + + /** + * Gets the next value that will be returned by generate(). + * + * @return integer|float + */ + public function getNextValue() + { + return $this->_nextValue; + } + + public function serialize() + { + return serialize(array( + 'allocationSize' => $this->_allocationSize, + 'sequenceName' => $this->_sequenceName + )); + } + + public function unserialize($serialized) + { + $array = unserialize($serialized); + + $this->_sequenceName = $array['sequenceName']; + $this->_allocationSize = $array['allocationSize']; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Id/TableGenerator.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Id/TableGenerator.php new file mode 100644 index 0000000..24b1d90 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Id/TableGenerator.php @@ -0,0 +1,81 @@ +. + */ + +namespace Doctrine\ORM\Id; + +use Doctrine\ORM\EntityManager; + +/** + * Id generator that uses a single-row database table and a hi/lo algorithm. + * + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class TableGenerator extends AbstractIdGenerator +{ + private $_tableName; + private $_sequenceName; + private $_allocationSize; + private $_nextValue; + private $_maxValue; + + public function __construct($tableName, $sequenceName = 'default', $allocationSize = 10) + { + $this->_tableName = $tableName; + $this->_sequenceName = $sequenceName; + $this->_allocationSize = $allocationSize; + } + + public function generate(EntityManager $em, $entity) + { + if ($this->_maxValue === null || $this->_nextValue == $this->_maxValue) { + // Allocate new values + $conn = $em->getConnection(); + + if ($conn->getTransactionNestingLevel() === 0) { + // use select for update + $sql = $conn->getDatabasePlatform()->getTableHiLoCurrentValSql($this->_tableName, $this->_sequenceName); + $currentLevel = $conn->fetchColumn($sql); + + if ($currentLevel != null) { + $this->_nextValue = $currentLevel; + $this->_maxValue = $this->_nextValue + $this->_allocationSize; + + $updateSql = $conn->getDatabasePlatform()->getTableHiLoUpdateNextValSql( + $this->_tableName, $this->_sequenceName, $this->_allocationSize + ); + + if ($conn->executeUpdate($updateSql, array(1 => $currentLevel, 2 => $currentLevel+1)) !== 1) { + // no affected rows, concurrency issue, throw exception + } + } else { + // no current level returned, TableGenerator seems to be broken, throw exception + } + } else { + // only table locks help here, implement this or throw exception? + // or do we want to work with table locks exclusively? + } + } + + return $this->_nextValue++; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/CommitOrderCalculator.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/CommitOrderCalculator.php new file mode 100644 index 0000000..049cab0 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/CommitOrderCalculator.php @@ -0,0 +1,118 @@ +. + */ + +namespace Doctrine\ORM\Internal; + +/** + * The CommitOrderCalculator is used by the UnitOfWork to sort out the + * correct order in which changes to entities need to be persisted. + * + * @since 2.0 + * @author Roman Borschel + * @author Guilherme Blanco + */ +class CommitOrderCalculator +{ + const NOT_VISITED = 1; + const IN_PROGRESS = 2; + const VISITED = 3; + + private $_nodeStates = array(); + private $_classes = array(); // The nodes to sort + private $_relatedClasses = array(); + private $_sorted = array(); + + /** + * Clears the current graph. + * + * @return void + */ + public function clear() + { + $this->_classes = + $this->_relatedClasses = array(); + } + + /** + * Gets a valid commit order for all current nodes. + * + * Uses a depth-first search (DFS) to traverse the graph. + * The desired topological sorting is the reverse postorder of these searches. + * + * @return array The list of ordered classes. + */ + public function getCommitOrder() + { + // Check whether we need to do anything. 0 or 1 node is easy. + $nodeCount = count($this->_classes); + + if ($nodeCount <= 1) { + return ($nodeCount == 1) ? array_values($this->_classes) : array(); + } + + // Init + foreach ($this->_classes as $node) { + $this->_nodeStates[$node->name] = self::NOT_VISITED; + } + + // Go + foreach ($this->_classes as $node) { + if ($this->_nodeStates[$node->name] == self::NOT_VISITED) { + $this->_visitNode($node); + } + } + + $sorted = array_reverse($this->_sorted); + + $this->_sorted = $this->_nodeStates = array(); + + return $sorted; + } + + private function _visitNode($node) + { + $this->_nodeStates[$node->name] = self::IN_PROGRESS; + + if (isset($this->_relatedClasses[$node->name])) { + foreach ($this->_relatedClasses[$node->name] as $relatedNode) { + if ($this->_nodeStates[$relatedNode->name] == self::NOT_VISITED) { + $this->_visitNode($relatedNode); + } + } + } + + $this->_nodeStates[$node->name] = self::VISITED; + $this->_sorted[] = $node; + } + + public function addDependency($fromClass, $toClass) + { + $this->_relatedClasses[$fromClass->name][] = $toClass; + } + + public function hasClass($className) + { + return isset($this->_classes[$className]); + } + + public function addClass($class) + { + $this->_classes[$class->name] = $class; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php new file mode 100644 index 0000000..83609d5 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php @@ -0,0 +1,389 @@ +. + */ + +namespace Doctrine\ORM\Internal\Hydration; + +use PDO, + Doctrine\DBAL\Connection, + Doctrine\DBAL\Types\Type, + Doctrine\ORM\EntityManager, + Doctrine\ORM\Events, + Doctrine\ORM\Mapping\ClassMetadata; + +/** + * Base class for all hydrators. A hydrator is a class that provides some form + * of transformation of an SQL result set into another structure. + * + * @since 2.0 + * @author Konsta Vesterinen + * @author Roman Borschel + * @author Guilherme Blanco + */ +abstract class AbstractHydrator +{ + /** @var ResultSetMapping The ResultSetMapping. */ + protected $_rsm; + + /** @var EntityManager The EntityManager instance. */ + protected $_em; + + /** @var AbstractPlatform The dbms Platform instance */ + protected $_platform; + + /** @var UnitOfWork The UnitOfWork of the associated EntityManager. */ + protected $_uow; + + /** @var array The cache used during row-by-row hydration. */ + protected $_cache = array(); + + /** @var Statement The statement that provides the data to hydrate. */ + protected $_stmt; + + /** @var array The query hints. */ + protected $_hints; + + /** + * Initializes a new instance of a class derived from AbstractHydrator. + * + * @param \Doctrine\ORM\EntityManager $em The EntityManager to use. + */ + public function __construct(EntityManager $em) + { + $this->_em = $em; + $this->_platform = $em->getConnection()->getDatabasePlatform(); + $this->_uow = $em->getUnitOfWork(); + } + + /** + * Initiates a row-by-row hydration. + * + * @param object $stmt + * @param object $resultSetMapping + * + * @return IterableResult + */ + public function iterate($stmt, $resultSetMapping, array $hints = array()) + { + $this->_stmt = $stmt; + $this->_rsm = $resultSetMapping; + $this->_hints = $hints; + + $evm = $this->_em->getEventManager(); + $evm->addEventListener(array(Events::onClear), $this); + + $this->prepare(); + + return new IterableResult($this); + } + + /** + * Hydrates all rows returned by the passed statement instance at once. + * + * @param object $stmt + * @param object $resultSetMapping + * @return mixed + */ + public function hydrateAll($stmt, $resultSetMapping, array $hints = array()) + { + $this->_stmt = $stmt; + $this->_rsm = $resultSetMapping; + $this->_hints = $hints; + + $this->prepare(); + + $result = $this->hydrateAllData(); + + $this->cleanup(); + + return $result; + } + + /** + * Hydrates a single row returned by the current statement instance during + * row-by-row hydration with {@link iterate()}. + * + * @return mixed + */ + public function hydrateRow() + { + $row = $this->_stmt->fetch(PDO::FETCH_ASSOC); + + if ( ! $row) { + $this->cleanup(); + + return false; + } + + $result = array(); + + $this->hydrateRowData($row, $this->_cache, $result); + + return $result; + } + + /** + * Excutes one-time preparation tasks, once each time hydration is started + * through {@link hydrateAll} or {@link iterate()}. + */ + protected function prepare() + {} + + /** + * Excutes one-time cleanup tasks at the end of a hydration that was initiated + * through {@link hydrateAll} or {@link iterate()}. + */ + protected function cleanup() + { + $this->_rsm = null; + + $this->_stmt->closeCursor(); + $this->_stmt = null; + } + + /** + * Hydrates a single row from the current statement instance. + * + * Template method. + * + * @param array $data The row data. + * @param array $cache The cache to use. + * @param mixed $result The result to fill. + */ + protected function hydrateRowData(array $data, array &$cache, array &$result) + { + throw new HydrationException("hydrateRowData() not implemented by this hydrator."); + } + + /** + * Hydrates all rows from the current statement instance at once. + */ + abstract protected function hydrateAllData(); + + /** + * Processes a row of the result set. + * + * Used for identity-based hydration (HYDRATE_OBJECT and HYDRATE_ARRAY). + * Puts the elements of a result row into a new array, grouped by the dql alias + * they belong to. The column names in the result set are mapped to their + * field names during this procedure as well as any necessary conversions on + * the values applied. Scalar values are kept in a specfic key 'scalars'. + * + * @param array $data SQL Result Row + * @param array &$cache Cache for column to field result information + * @param array &$id Dql-Alias => ID-Hash + * @param array &$nonemptyComponents Does this DQL-Alias has at least one non NULL value? + * + * @return array An array with all the fields (name => value) of the data row, + * grouped by their component alias. + */ + protected function gatherRowData(array $data, array &$cache, array &$id, array &$nonemptyComponents) + { + $rowData = array(); + + foreach ($data as $key => $value) { + // Parse each column name only once. Cache the results. + if ( ! isset($cache[$key])) { + switch (true) { + // NOTE: Most of the times it's a field mapping, so keep it first!!! + case (isset($this->_rsm->fieldMappings[$key])): + $fieldName = $this->_rsm->fieldMappings[$key]; + $classMetadata = $this->_em->getClassMetadata($this->_rsm->declaringClasses[$key]); + + $cache[$key]['fieldName'] = $fieldName; + $cache[$key]['type'] = Type::getType($classMetadata->fieldMappings[$fieldName]['type']); + $cache[$key]['isIdentifier'] = $classMetadata->isIdentifier($fieldName); + $cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key]; + break; + + case (isset($this->_rsm->scalarMappings[$key])): + $cache[$key]['fieldName'] = $this->_rsm->scalarMappings[$key]; + $cache[$key]['type'] = Type::getType($this->_rsm->typeMappings[$key]); + $cache[$key]['isScalar'] = true; + break; + + case (isset($this->_rsm->metaMappings[$key])): + // Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns). + $fieldName = $this->_rsm->metaMappings[$key]; + $classMetadata = $this->_em->getClassMetadata($this->_rsm->aliasMap[$this->_rsm->columnOwnerMap[$key]]); + + $cache[$key]['isMetaColumn'] = true; + $cache[$key]['fieldName'] = $fieldName; + $cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key]; + $cache[$key]['isIdentifier'] = isset($this->_rsm->isIdentifierColumn[$cache[$key]['dqlAlias']][$key]); + break; + + default: + // this column is a left over, maybe from a LIMIT query hack for example in Oracle or DB2 + // maybe from an additional column that has not been defined in a NativeQuery ResultSetMapping. + continue 2; + } + } + + if (isset($cache[$key]['isScalar'])) { + $value = $cache[$key]['type']->convertToPHPValue($value, $this->_platform); + + $rowData['scalars'][$cache[$key]['fieldName']] = $value; + + continue; + } + + $dqlAlias = $cache[$key]['dqlAlias']; + + if ($cache[$key]['isIdentifier']) { + $id[$dqlAlias] .= '|' . $value; + } + + if (isset($cache[$key]['isMetaColumn'])) { + if ( ! isset($rowData[$dqlAlias][$cache[$key]['fieldName']]) && $value !== null) { + $rowData[$dqlAlias][$cache[$key]['fieldName']] = $value; + if ($cache[$key]['isIdentifier']) { + $nonemptyComponents[$dqlAlias] = true; + } + } + + continue; + } + + // in an inheritance hierarchy the same field could be defined several times. + // We overwrite this value so long we dont have a non-null value, that value we keep. + // Per definition it cannot be that a field is defined several times and has several values. + if (isset($rowData[$dqlAlias][$cache[$key]['fieldName']]) && $value === null) { + continue; + } + + $rowData[$dqlAlias][$cache[$key]['fieldName']] = $cache[$key]['type']->convertToPHPValue($value, $this->_platform); + + if ( ! isset($nonemptyComponents[$dqlAlias]) && $value !== null) { + $nonemptyComponents[$dqlAlias] = true; + } + } + + return $rowData; + } + + /** + * Processes a row of the result set. + * + * Used for HYDRATE_SCALAR. This is a variant of _gatherRowData() that + * simply converts column names to field names and properly converts the + * values according to their types. The resulting row has the same number + * of elements as before. + * + * @param array $data + * @param array $cache + * + * @return array The processed row. + */ + protected function gatherScalarRowData(&$data, &$cache) + { + $rowData = array(); + + foreach ($data as $key => $value) { + // Parse each column name only once. Cache the results. + if ( ! isset($cache[$key])) { + switch (true) { + // NOTE: During scalar hydration, most of the times it's a scalar mapping, keep it first!!! + case (isset($this->_rsm->scalarMappings[$key])): + $cache[$key]['fieldName'] = $this->_rsm->scalarMappings[$key]; + $cache[$key]['isScalar'] = true; + break; + + case (isset($this->_rsm->fieldMappings[$key])): + $fieldName = $this->_rsm->fieldMappings[$key]; + $classMetadata = $this->_em->getClassMetadata($this->_rsm->declaringClasses[$key]); + + $cache[$key]['fieldName'] = $fieldName; + $cache[$key]['type'] = Type::getType($classMetadata->fieldMappings[$fieldName]['type']); + $cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key]; + break; + + case (isset($this->_rsm->metaMappings[$key])): + // Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns). + $cache[$key]['isMetaColumn'] = true; + $cache[$key]['fieldName'] = $this->_rsm->metaMappings[$key]; + $cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key]; + break; + + default: + // this column is a left over, maybe from a LIMIT query hack for example in Oracle or DB2 + // maybe from an additional column that has not been defined in a NativeQuery ResultSetMapping. + continue 2; + } + } + + $fieldName = $cache[$key]['fieldName']; + + switch (true) { + case (isset($cache[$key]['isScalar'])): + $rowData[$fieldName] = $value; + break; + + case (isset($cache[$key]['isMetaColumn'])): + $rowData[$cache[$key]['dqlAlias'] . '_' . $fieldName] = $value; + break; + + default: + $value = $cache[$key]['type']->convertToPHPValue($value, $this->_platform); + + $rowData[$cache[$key]['dqlAlias'] . '_' . $fieldName] = $value; + } + } + + return $rowData; + } + + /** + * Register entity as managed in UnitOfWork. + * + * @param \Doctrine\ORM\Mapping\ClassMetadata $class + * @param object $entity + * @param array $data + * + * @todo The "$id" generation is the same of UnitOfWork#createEntity. Remove this duplication somehow + */ + protected function registerManaged(ClassMetadata $class, $entity, array $data) + { + if ($class->isIdentifierComposite) { + $id = array(); + foreach ($class->identifier as $fieldName) { + if (isset($class->associationMappings[$fieldName])) { + $id[$fieldName] = $data[$class->associationMappings[$fieldName]['joinColumns'][0]['name']]; + } else { + $id[$fieldName] = $data[$fieldName]; + } + } + } else { + if (isset($class->associationMappings[$class->identifier[0]])) { + $id = array($class->identifier[0] => $data[$class->associationMappings[$class->identifier[0]]['joinColumns'][0]['name']]); + } else { + $id = array($class->identifier[0] => $data[$class->identifier[0]]); + } + } + + $this->_em->getUnitOfWork()->registerManaged($entity, $id, $data); + } + + /** + * When executed in a hydrate() loop we have to clear internal state to + * decrease memory consumption. + */ + public function onClear($eventArgs) + { + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ArrayHydrator.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ArrayHydrator.php new file mode 100644 index 0000000..9a8fcee --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ArrayHydrator.php @@ -0,0 +1,289 @@ +. + */ + +namespace Doctrine\ORM\Internal\Hydration; + +use PDO, Doctrine\DBAL\Connection, Doctrine\ORM\Mapping\ClassMetadata; + +/** + * The ArrayHydrator produces a nested array "graph" that is often (not always) + * interchangeable with the corresponding object graph for read-only access. + * + * @since 2.0 + * @author Roman Borschel + * @author Guilherme Blanco + */ +class ArrayHydrator extends AbstractHydrator +{ + private $_ce = array(); + private $_rootAliases = array(); + private $_isSimpleQuery = false; + private $_identifierMap = array(); + private $_resultPointers = array(); + private $_idTemplate = array(); + private $_resultCounter = 0; + + /** + * {@inheritdoc} + */ + protected function prepare() + { + $this->_isSimpleQuery = count($this->_rsm->aliasMap) <= 1; + $this->_identifierMap = array(); + $this->_resultPointers = array(); + $this->_idTemplate = array(); + $this->_resultCounter = 0; + + foreach ($this->_rsm->aliasMap as $dqlAlias => $className) { + $this->_identifierMap[$dqlAlias] = array(); + $this->_resultPointers[$dqlAlias] = array(); + $this->_idTemplate[$dqlAlias] = ''; + } + } + + /** + * {@inheritdoc} + */ + protected function hydrateAllData() + { + $result = array(); + $cache = array(); + + while ($data = $this->_stmt->fetch(PDO::FETCH_ASSOC)) { + $this->hydrateRowData($data, $cache, $result); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + protected function hydrateRowData(array $row, array &$cache, array &$result) + { + // 1) Initialize + $id = $this->_idTemplate; // initialize the id-memory + $nonemptyComponents = array(); + $rowData = $this->gatherRowData($row, $cache, $id, $nonemptyComponents); + + // Extract scalar values. They're appended at the end. + if (isset($rowData['scalars'])) { + $scalars = $rowData['scalars']; + + unset($rowData['scalars']); + + if (empty($rowData)) { + ++$this->_resultCounter; + } + } + + // 2) Now hydrate the data found in the current row. + foreach ($rowData as $dqlAlias => $data) { + $index = false; + + if (isset($this->_rsm->parentAliasMap[$dqlAlias])) { + // It's a joined result + + $parent = $this->_rsm->parentAliasMap[$dqlAlias]; + $path = $parent . '.' . $dqlAlias; + + // missing parent data, skipping as RIGHT JOIN hydration is not supported. + if ( ! isset($nonemptyComponents[$parent]) ) { + continue; + } + + // Get a reference to the right element in the result tree. + // This element will get the associated element attached. + if ($this->_rsm->isMixed && isset($this->_rootAliases[$parent])) { + $first = reset($this->_resultPointers); + // TODO: Exception if $key === null ? + $baseElement =& $this->_resultPointers[$parent][key($first)]; + } else if (isset($this->_resultPointers[$parent])) { + $baseElement =& $this->_resultPointers[$parent]; + } else { + unset($this->_resultPointers[$dqlAlias]); // Ticket #1228 + continue; + } + + $relationAlias = $this->_rsm->relationMap[$dqlAlias]; + $relation = $this->getClassMetadata($this->_rsm->aliasMap[$parent])->associationMappings[$relationAlias]; + + // Check the type of the relation (many or single-valued) + if ( ! ($relation['type'] & ClassMetadata::TO_ONE)) { + $oneToOne = false; + + if (isset($nonemptyComponents[$dqlAlias])) { + if ( ! isset($baseElement[$relationAlias])) { + $baseElement[$relationAlias] = array(); + } + + $indexExists = isset($this->_identifierMap[$path][$id[$parent]][$id[$dqlAlias]]); + $index = $indexExists ? $this->_identifierMap[$path][$id[$parent]][$id[$dqlAlias]] : false; + $indexIsValid = $index !== false ? isset($baseElement[$relationAlias][$index]) : false; + + if ( ! $indexExists || ! $indexIsValid) { + $element = $data; + if (isset($this->_rsm->indexByMap[$dqlAlias])) { + $baseElement[$relationAlias][$row[$this->_rsm->indexByMap[$dqlAlias]]] = $element; + } else { + $baseElement[$relationAlias][] = $element; + } + + end($baseElement[$relationAlias]); + + $this->_identifierMap[$path][$id[$parent]][$id[$dqlAlias]] = key($baseElement[$relationAlias]); + } + } else if ( ! isset($baseElement[$relationAlias])) { + $baseElement[$relationAlias] = array(); + } + } else { + $oneToOne = true; + + if ( ! isset($nonemptyComponents[$dqlAlias]) && ! isset($baseElement[$relationAlias])) { + $baseElement[$relationAlias] = null; + } else if ( ! isset($baseElement[$relationAlias])) { + $baseElement[$relationAlias] = $data; + } + } + + $coll =& $baseElement[$relationAlias]; + + if ($coll !== null) { + $this->updateResultPointer($coll, $index, $dqlAlias, $oneToOne); + } + + } else { + // It's a root result element + + $this->_rootAliases[$dqlAlias] = true; // Mark as root + $entityKey = $this->_rsm->entityMappings[$dqlAlias] ?: 0; + + // if this row has a NULL value for the root result id then make it a null result. + if ( ! isset($nonemptyComponents[$dqlAlias]) ) { + if ($this->_rsm->isMixed) { + $result[] = array($entityKey => null); + } else { + $result[] = null; + } + $resultKey = $this->_resultCounter; + ++$this->_resultCounter; + continue; + } + + // Check for an existing element + if ($this->_isSimpleQuery || ! isset($this->_identifierMap[$dqlAlias][$id[$dqlAlias]])) { + $element = $rowData[$dqlAlias]; + if ($this->_rsm->isMixed) { + $element = array($entityKey => $element); + } + + if (isset($this->_rsm->indexByMap[$dqlAlias])) { + $resultKey = $row[$this->_rsm->indexByMap[$dqlAlias]]; + $result[$resultKey] = $element; + } else { + $resultKey = $this->_resultCounter; + $result[] = $element; + ++$this->_resultCounter; + } + + $this->_identifierMap[$dqlAlias][$id[$dqlAlias]] = $resultKey; + } else { + $index = $this->_identifierMap[$dqlAlias][$id[$dqlAlias]]; + $resultKey = $index; + /*if ($this->_rsm->isMixed) { + $result[] =& $result[$index]; + ++$this->_resultCounter; + }*/ + } + $this->updateResultPointer($result, $index, $dqlAlias, false); + } + } + + // Append scalar values to mixed result sets + if (isset($scalars)) { + if ( ! isset($resultKey) ) { + // this only ever happens when no object is fetched (scalar result only) + if (isset($this->_rsm->indexByMap['scalars'])) { + $resultKey = $row[$this->_rsm->indexByMap['scalars']]; + } else { + $resultKey = $this->_resultCounter - 1; + } + } + + foreach ($scalars as $name => $value) { + $result[$resultKey][$name] = $value; + } + } + } + + /** + * Updates the result pointer for an Entity. The result pointers point to the + * last seen instance of each Entity type. This is used for graph construction. + * + * @param array $coll The element. + * @param boolean|integer $index Index of the element in the collection. + * @param string $dqlAlias + * @param boolean $oneToOne Whether it is a single-valued association or not. + */ + private function updateResultPointer(array &$coll, $index, $dqlAlias, $oneToOne) + { + if ($coll === null) { + unset($this->_resultPointers[$dqlAlias]); // Ticket #1228 + + return; + } + + if ($index !== false) { + $this->_resultPointers[$dqlAlias] =& $coll[$index]; + + return; + } + + if ( ! $coll) { + return; + } + + if ($oneToOne) { + $this->_resultPointers[$dqlAlias] =& $coll; + + return; + } + + end($coll); + $this->_resultPointers[$dqlAlias] =& $coll[key($coll)]; + + return; + } + + /** + * Retrieve ClassMetadata associated to entity class name. + * + * @param string $className + * + * @return \Doctrine\ORM\Mapping\ClassMetadata + */ + private function getClassMetadata($className) + { + if ( ! isset($this->_ce[$className])) { + $this->_ce[$className] = $this->_em->getClassMetadata($className); + } + + return $this->_ce[$className]; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/HydrationException.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/HydrationException.php new file mode 100644 index 0000000..147f6ac --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/HydrationException.php @@ -0,0 +1,26 @@ +. + */ + +namespace Doctrine\ORM\Internal\Hydration; + +/** + * Represents a result structure that can be iterated over, hydrating row-by-row + * during the iteration. An IterableResult is obtained by AbstractHydrator#iterate(). + * + * @author robo + * @since 2.0 + */ +class IterableResult implements \Iterator +{ + /** + * @var \Doctrine\ORM\Internal\Hydration\AbstractHydrator + */ + private $_hydrator; + + /** + * @var boolean + */ + private $_rewinded = false; + + /** + * @var integer + */ + private $_key = -1; + + /** + * @var object + */ + private $_current = null; + + /** + * @param \Doctrine\ORM\Internal\Hydration\AbstractHydrator $hydrator + */ + public function __construct($hydrator) + { + $this->_hydrator = $hydrator; + } + + public function rewind() + { + if ($this->_rewinded == true) { + throw new HydrationException("Can only iterate a Result once."); + } else { + $this->_current = $this->next(); + $this->_rewinded = true; + } + } + + /** + * Gets the next set of results. + * + * @return array + */ + public function next() + { + $this->_current = $this->_hydrator->hydrateRow(); + $this->_key++; + return $this->_current; + } + + /** + * @return mixed + */ + public function current() + { + return $this->_current; + } + + /** + * @return int + */ + public function key() + { + return $this->_key; + } + + /** + * @return bool + */ + public function valid() + { + return ($this->_current!=false); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php new file mode 100644 index 0000000..2f960da --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php @@ -0,0 +1,536 @@ +. + */ + +namespace Doctrine\ORM\Internal\Hydration; + +use PDO, + Doctrine\ORM\Mapping\ClassMetadata, + Doctrine\ORM\PersistentCollection, + Doctrine\ORM\Query, + Doctrine\ORM\Event\LifecycleEventArgs, + Doctrine\ORM\Events, + Doctrine\Common\Collections\ArrayCollection, + Doctrine\Common\Collections\Collection, + Doctrine\ORM\Proxy\Proxy; + +/** + * The ObjectHydrator constructs an object graph out of an SQL result set. + * + * @since 2.0 + * @author Roman Borschel + * @author Guilherme Blanco + * + * @internal Highly performance-sensitive code. + */ +class ObjectHydrator extends AbstractHydrator +{ + /* Local ClassMetadata cache to avoid going to the EntityManager all the time. + * This local cache is maintained between hydration runs and not cleared. + */ + private $_ce = array(); + + /* The following parts are reinitialized on every hydration run. */ + + private $_identifierMap; + private $_resultPointers; + private $_idTemplate; + private $_resultCounter; + private $_rootAliases = array(); + private $_initializedCollections = array(); + private $_existingCollections = array(); + + + /** @override */ + protected function prepare() + { + $this->_identifierMap = + $this->_resultPointers = + $this->_idTemplate = array(); + + $this->_resultCounter = 0; + + if ( ! isset($this->_hints['deferEagerLoad'])) { + $this->_hints['deferEagerLoad'] = true; + } + + foreach ($this->_rsm->aliasMap as $dqlAlias => $className) { + $this->_identifierMap[$dqlAlias] = array(); + $this->_idTemplate[$dqlAlias] = ''; + + if ( ! isset($this->_ce[$className])) { + $this->_ce[$className] = $this->_em->getClassMetadata($className); + } + + // Remember which associations are "fetch joined", so that we know where to inject + // collection stubs or proxies and where not. + if ( ! isset($this->_rsm->relationMap[$dqlAlias])) { + continue; + } + + if ( ! isset($this->_rsm->aliasMap[$this->_rsm->parentAliasMap[$dqlAlias]])) { + throw HydrationException::parentObjectOfRelationNotFound($dqlAlias, $this->_rsm->parentAliasMap[$dqlAlias]); + } + + $sourceClassName = $this->_rsm->aliasMap[$this->_rsm->parentAliasMap[$dqlAlias]]; + $sourceClass = $this->_getClassMetadata($sourceClassName); + $assoc = $sourceClass->associationMappings[$this->_rsm->relationMap[$dqlAlias]]; + + $this->_hints['fetched'][$this->_rsm->parentAliasMap[$dqlAlias]][$assoc['fieldName']] = true; + + if ($assoc['type'] === ClassMetadata::MANY_TO_MANY) { + continue; + } + + // Mark any non-collection opposite sides as fetched, too. + if ($assoc['mappedBy']) { + $this->_hints['fetched'][$dqlAlias][$assoc['mappedBy']] = true; + + continue; + } + + // handle fetch-joined owning side bi-directional one-to-one associations + if ($assoc['inversedBy']) { + $class = $this->_ce[$className]; + $inverseAssoc = $class->associationMappings[$assoc['inversedBy']]; + + if ( ! ($inverseAssoc['type'] & ClassMetadata::TO_ONE)) { + continue; + } + + $this->_hints['fetched'][$dqlAlias][$inverseAssoc['fieldName']] = true; + } + } + } + + /** + * {@inheritdoc} + */ + protected function cleanup() + { + $eagerLoad = (isset($this->_hints['deferEagerLoad'])) && $this->_hints['deferEagerLoad'] == true; + + parent::cleanup(); + + $this->_identifierMap = + $this->_initializedCollections = + $this->_existingCollections = + $this->_resultPointers = array(); + + if ($eagerLoad) { + $this->_em->getUnitOfWork()->triggerEagerLoads(); + } + } + + /** + * {@inheritdoc} + */ + protected function hydrateAllData() + { + $result = array(); + $cache = array(); + + while ($row = $this->_stmt->fetch(PDO::FETCH_ASSOC)) { + $this->hydrateRowData($row, $cache, $result); + } + + // Take snapshots from all newly initialized collections + foreach ($this->_initializedCollections as $coll) { + $coll->takeSnapshot(); + } + + return $result; + } + + /** + * Initializes a related collection. + * + * @param object $entity The entity to which the collection belongs. + * @param ClassMetadata $class + * @param string $name The name of the field on the entity that holds the collection. + * @param string $parentDqlAlias Alias of the parent fetch joining this collection. + */ + private function _initRelatedCollection($entity, $class, $fieldName, $parentDqlAlias) + { + $oid = spl_object_hash($entity); + $relation = $class->associationMappings[$fieldName]; + $value = $class->reflFields[$fieldName]->getValue($entity); + + if ($value === null) { + $value = new ArrayCollection; + } + + if ( ! $value instanceof PersistentCollection) { + $value = new PersistentCollection( + $this->_em, $this->_ce[$relation['targetEntity']], $value + ); + $value->setOwner($entity, $relation); + + $class->reflFields[$fieldName]->setValue($entity, $value); + $this->_uow->setOriginalEntityProperty($oid, $fieldName, $value); + + $this->_initializedCollections[$oid . $fieldName] = $value; + } else if ( + isset($this->_hints[Query::HINT_REFRESH]) || + isset($this->_hints['fetched'][$parentDqlAlias][$fieldName]) && + ! $value->isInitialized() + ) { + // Is already PersistentCollection, but either REFRESH or FETCH-JOIN and UNINITIALIZED! + $value->setDirty(false); + $value->setInitialized(true); + $value->unwrap()->clear(); + + $this->_initializedCollections[$oid . $fieldName] = $value; + } else { + // Is already PersistentCollection, and DON'T REFRESH or FETCH-JOIN! + $this->_existingCollections[$oid . $fieldName] = $value; + } + + return $value; + } + + /** + * Gets an entity instance. + * + * @param $data The instance data. + * @param $dqlAlias The DQL alias of the entity's class. + * @return object The entity. + */ + private function _getEntity(array $data, $dqlAlias) + { + $className = $this->_rsm->aliasMap[$dqlAlias]; + + if (isset($this->_rsm->discriminatorColumns[$dqlAlias])) { + $discrColumn = $this->_rsm->metaMappings[$this->_rsm->discriminatorColumns[$dqlAlias]]; + + if ($data[$discrColumn] === "") { + throw HydrationException::emptyDiscriminatorValue($dqlAlias); + } + + $className = $this->_ce[$className]->discriminatorMap[$data[$discrColumn]]; + + unset($data[$discrColumn]); + } + + if (isset($this->_hints[Query::HINT_REFRESH_ENTITY]) && isset($this->_rootAliases[$dqlAlias])) { + $this->registerManaged($this->_ce[$className], $this->_hints[Query::HINT_REFRESH_ENTITY], $data); + } + + $this->_hints['fetchAlias'] = $dqlAlias; + + return $this->_uow->createEntity($className, $data, $this->_hints); + } + + private function _getEntityFromIdentityMap($className, array $data) + { + // TODO: Abstract this code and UnitOfWork::createEntity() equivalent? + $class = $this->_ce[$className]; + + /* @var $class ClassMetadata */ + if ($class->isIdentifierComposite) { + $idHash = ''; + foreach ($class->identifier as $fieldName) { + if (isset($class->associationMappings[$fieldName])) { + $idHash .= $data[$class->associationMappings[$fieldName]['joinColumns'][0]['name']] . ' '; + } else { + $idHash .= $data[$fieldName] . ' '; + } + } + return $this->_uow->tryGetByIdHash(rtrim($idHash), $class->rootEntityName); + } else if (isset($class->associationMappings[$class->identifier[0]])) { + return $this->_uow->tryGetByIdHash($data[$class->associationMappings[$class->identifier[0]]['joinColumns'][0]['name']], $class->rootEntityName); + } else { + return $this->_uow->tryGetByIdHash($data[$class->identifier[0]], $class->rootEntityName); + } + } + + /** + * Gets a ClassMetadata instance from the local cache. + * If the instance is not yet in the local cache, it is loaded into the + * local cache. + * + * @param string $className The name of the class. + * @return ClassMetadata + */ + private function _getClassMetadata($className) + { + if ( ! isset($this->_ce[$className])) { + $this->_ce[$className] = $this->_em->getClassMetadata($className); + } + + return $this->_ce[$className]; + } + + /** + * Hydrates a single row in an SQL result set. + * + * @internal + * First, the data of the row is split into chunks where each chunk contains data + * that belongs to a particular component/class. Afterwards, all these chunks + * are processed, one after the other. For each chunk of class data only one of the + * following code paths is executed: + * + * Path A: The data chunk belongs to a joined/associated object and the association + * is collection-valued. + * Path B: The data chunk belongs to a joined/associated object and the association + * is single-valued. + * Path C: The data chunk belongs to a root result element/object that appears in the topmost + * level of the hydrated result. A typical example are the objects of the type + * specified by the FROM clause in a DQL query. + * + * @param array $data The data of the row to process. + * @param array $cache The cache to use. + * @param array $result The result array to fill. + */ + protected function hydrateRowData(array $row, array &$cache, array &$result) + { + // Initialize + $id = $this->_idTemplate; // initialize the id-memory + $nonemptyComponents = array(); + // Split the row data into chunks of class data. + $rowData = $this->gatherRowData($row, $cache, $id, $nonemptyComponents); + + // Extract scalar values. They're appended at the end. + if (isset($rowData['scalars'])) { + $scalars = $rowData['scalars']; + + unset($rowData['scalars']); + + if (empty($rowData)) { + ++$this->_resultCounter; + } + } + + // Hydrate the data chunks + foreach ($rowData as $dqlAlias => $data) { + $entityName = $this->_rsm->aliasMap[$dqlAlias]; + + if (isset($this->_rsm->parentAliasMap[$dqlAlias])) { + // It's a joined result + + $parentAlias = $this->_rsm->parentAliasMap[$dqlAlias]; + // we need the $path to save into the identifier map which entities were already + // seen for this parent-child relationship + $path = $parentAlias . '.' . $dqlAlias; + + // We have a RIGHT JOIN result here. Doctrine cannot hydrate RIGHT JOIN Object-Graphs + if (!isset($nonemptyComponents[$parentAlias])) { + // TODO: Add special case code where we hydrate the right join objects into identity map at least + continue; + } + + // Get a reference to the parent object to which the joined element belongs. + if ($this->_rsm->isMixed && isset($this->_rootAliases[$parentAlias])) { + $first = reset($this->_resultPointers); + $parentObject = $first[key($first)]; + } else if (isset($this->_resultPointers[$parentAlias])) { + $parentObject = $this->_resultPointers[$parentAlias]; + } else { + // Parent object of relation not found, so skip it. + continue; + } + + $parentClass = $this->_ce[$this->_rsm->aliasMap[$parentAlias]]; + $oid = spl_object_hash($parentObject); + $relationField = $this->_rsm->relationMap[$dqlAlias]; + $relation = $parentClass->associationMappings[$relationField]; + $reflField = $parentClass->reflFields[$relationField]; + + // Check the type of the relation (many or single-valued) + if ( ! ($relation['type'] & ClassMetadata::TO_ONE)) { + $reflFieldValue = $reflField->getValue($parentObject); + // PATH A: Collection-valued association + if (isset($nonemptyComponents[$dqlAlias])) { + $collKey = $oid . $relationField; + if (isset($this->_initializedCollections[$collKey])) { + $reflFieldValue = $this->_initializedCollections[$collKey]; + } else if ( ! isset($this->_existingCollections[$collKey])) { + $reflFieldValue = $this->_initRelatedCollection($parentObject, $parentClass, $relationField, $parentAlias); + } + + $indexExists = isset($this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]]); + $index = $indexExists ? $this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] : false; + $indexIsValid = $index !== false ? isset($reflFieldValue[$index]) : false; + + if ( ! $indexExists || ! $indexIsValid) { + if (isset($this->_existingCollections[$collKey])) { + // Collection exists, only look for the element in the identity map. + if ($element = $this->_getEntityFromIdentityMap($entityName, $data)) { + $this->_resultPointers[$dqlAlias] = $element; + } else { + unset($this->_resultPointers[$dqlAlias]); + } + } else { + $element = $this->_getEntity($data, $dqlAlias); + + if (isset($this->_rsm->indexByMap[$dqlAlias])) { + $indexValue = $row[$this->_rsm->indexByMap[$dqlAlias]]; + $reflFieldValue->hydrateSet($indexValue, $element); + $this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] = $indexValue; + } else { + $reflFieldValue->hydrateAdd($element); + $reflFieldValue->last(); + $this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] = $reflFieldValue->key(); + } + // Update result pointer + $this->_resultPointers[$dqlAlias] = $element; + } + } else { + // Update result pointer + $this->_resultPointers[$dqlAlias] = $reflFieldValue[$index]; + } + } else if ( ! $reflFieldValue) { + $reflFieldValue = $this->_initRelatedCollection($parentObject, $parentClass, $relationField, $parentAlias); + } else if ($reflFieldValue instanceof PersistentCollection && $reflFieldValue->isInitialized() === false) { + $reflFieldValue->setInitialized(true); + } + + } else { + // PATH B: Single-valued association + $reflFieldValue = $reflField->getValue($parentObject); + if ( ! $reflFieldValue || isset($this->_hints[Query::HINT_REFRESH]) || ($reflFieldValue instanceof Proxy && !$reflFieldValue->__isInitialized__)) { + // we only need to take action if this value is null, + // we refresh the entity or its an unitialized proxy. + if (isset($nonemptyComponents[$dqlAlias])) { + $element = $this->_getEntity($data, $dqlAlias); + $reflField->setValue($parentObject, $element); + $this->_uow->setOriginalEntityProperty($oid, $relationField, $element); + $targetClass = $this->_ce[$relation['targetEntity']]; + + if ($relation['isOwningSide']) { + //TODO: Just check hints['fetched'] here? + // If there is an inverse mapping on the target class its bidirectional + if ($relation['inversedBy']) { + $inverseAssoc = $targetClass->associationMappings[$relation['inversedBy']]; + if ($inverseAssoc['type'] & ClassMetadata::TO_ONE) { + $targetClass->reflFields[$inverseAssoc['fieldName']]->setValue($element, $parentObject); + $this->_uow->setOriginalEntityProperty(spl_object_hash($element), $inverseAssoc['fieldName'], $parentObject); + } + } else if ($parentClass === $targetClass && $relation['mappedBy']) { + // Special case: bi-directional self-referencing one-one on the same class + $targetClass->reflFields[$relationField]->setValue($element, $parentObject); + } + } else { + // For sure bidirectional, as there is no inverse side in unidirectional mappings + $targetClass->reflFields[$relation['mappedBy']]->setValue($element, $parentObject); + $this->_uow->setOriginalEntityProperty(spl_object_hash($element), $relation['mappedBy'], $parentObject); + } + // Update result pointer + $this->_resultPointers[$dqlAlias] = $element; + } else { + $this->_uow->setOriginalEntityProperty($oid, $relationField, null); + } + // else leave $reflFieldValue null for single-valued associations + } else { + // Update result pointer + $this->_resultPointers[$dqlAlias] = $reflFieldValue; + } + } + } else { + // PATH C: Its a root result element + $this->_rootAliases[$dqlAlias] = true; // Mark as root alias + $entityKey = $this->_rsm->entityMappings[$dqlAlias] ?: 0; + + // if this row has a NULL value for the root result id then make it a null result. + if ( ! isset($nonemptyComponents[$dqlAlias]) ) { + if ($this->_rsm->isMixed) { + $result[] = array($entityKey => null); + } else { + $result[] = null; + } + $resultKey = $this->_resultCounter; + ++$this->_resultCounter; + continue; + } + + // check for existing result from the iterations before + if ( ! isset($this->_identifierMap[$dqlAlias][$id[$dqlAlias]])) { + $element = $this->_getEntity($rowData[$dqlAlias], $dqlAlias); + if ($this->_rsm->isMixed) { + $element = array($entityKey => $element); + } + + if (isset($this->_rsm->indexByMap[$dqlAlias])) { + $resultKey = $row[$this->_rsm->indexByMap[$dqlAlias]]; + + if (isset($this->_hints['collection'])) { + $this->_hints['collection']->hydrateSet($resultKey, $element); + } + + $result[$resultKey] = $element; + } else { + $resultKey = $this->_resultCounter; + ++$this->_resultCounter; + + if (isset($this->_hints['collection'])) { + $this->_hints['collection']->hydrateAdd($element); + } + + $result[] = $element; + } + + $this->_identifierMap[$dqlAlias][$id[$dqlAlias]] = $resultKey; + + // Update result pointer + $this->_resultPointers[$dqlAlias] = $element; + + } else { + // Update result pointer + $index = $this->_identifierMap[$dqlAlias][$id[$dqlAlias]]; + $this->_resultPointers[$dqlAlias] = $result[$index]; + $resultKey = $index; + /*if ($this->_rsm->isMixed) { + $result[] = $result[$index]; + ++$this->_resultCounter; + }*/ + } + } + } + + // Append scalar values to mixed result sets + if (isset($scalars)) { + if ( ! isset($resultKey) ) { + if (isset($this->_rsm->indexByMap['scalars'])) { + $resultKey = $row[$this->_rsm->indexByMap['scalars']]; + } else { + $resultKey = $this->_resultCounter - 1; + } + } + + foreach ($scalars as $name => $value) { + $result[$resultKey][$name] = $value; + } + } + } + + /** + * When executed in a hydrate() loop we may have to clear internal state to + * decrease memory consumption. + */ + public function onClear($eventArgs) + { + parent::onClear($eventArgs); + + $aliases = array_keys($this->_identifierMap); + $this->_identifierMap = array(); + + foreach ($aliases as $alias) { + $this->_identifierMap[$alias] = array(); + } + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ScalarHydrator.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ScalarHydrator.php new file mode 100644 index 0000000..d02651b --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ScalarHydrator.php @@ -0,0 +1,57 @@ +. + */ + +namespace Doctrine\ORM\Internal\Hydration; + +use Doctrine\DBAL\Connection; + +/** + * Hydrator that produces flat, rectangular results of scalar data. + * The created result is almost the same as a regular SQL result set, except + * that column names are mapped to field names and data type conversions take place. + * + * @since 2.0 + * @author Roman Borschel + * @author Guilherme Blanco + */ +class ScalarHydrator extends AbstractHydrator +{ + /** + * {@inheritdoc} + */ + protected function hydrateAllData() + { + $result = array(); + $cache = array(); + + while ($data = $this->_stmt->fetch(\PDO::FETCH_ASSOC)) { + $this->hydrateRowData($data, $cache, $result); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + protected function hydrateRowData(array $data, array &$cache, array &$result) + { + $result[] = $this->gatherScalarRowData($data, $cache); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php new file mode 100644 index 0000000..09c2c7f --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php @@ -0,0 +1,183 @@ +. + */ + +namespace Doctrine\ORM\Internal\Hydration; + +use \PDO, + Doctrine\DBAL\Types\Type, + Doctrine\ORM\Mapping\ClassMetadata, + Doctrine\ORM\Event\LifecycleEventArgs, + Doctrine\ORM\Events, + Doctrine\ORM\Query; + +class SimpleObjectHydrator extends AbstractHydrator +{ + /** + * @var ClassMetadata + */ + private $class; + + /** + * @var array + */ + private $declaringClasses = array(); + + /** + * {@inheritdoc} + */ + protected function hydrateAllData() + { + $result = array(); + $cache = array(); + + while ($row = $this->_stmt->fetch(PDO::FETCH_ASSOC)) { + $this->hydrateRowData($row, $cache, $result); + } + + $this->_em->getUnitOfWork()->triggerEagerLoads(); + + return $result; + } + + /** + * {@inheritdoc} + */ + protected function prepare() + { + if (count($this->_rsm->aliasMap) !== 1) { + throw new \RuntimeException("Cannot use SimpleObjectHydrator with a ResultSetMapping that contains more than one object result."); + } + + if ($this->_rsm->scalarMappings) { + throw new \RuntimeException("Cannot use SimpleObjectHydrator with a ResultSetMapping that contains scalar mappings."); + } + + $this->class = $this->_em->getClassMetadata(reset($this->_rsm->aliasMap)); + + // We only need to add declaring classes if we have inheritance. + if ($this->class->inheritanceType === ClassMetadata::INHERITANCE_TYPE_NONE) { + return; + } + + foreach ($this->_rsm->declaringClasses AS $column => $class) { + $this->declaringClasses[$column] = $this->_em->getClassMetadata($class); + } + } + + /** + * {@inheritdoc} + */ + protected function hydrateRowData(array $sqlResult, array &$cache, array &$result) + { + $entityName = $this->class->name; + $data = array(); + + // We need to find the correct entity class name if we have inheritance in resultset + if ($this->class->inheritanceType !== ClassMetadata::INHERITANCE_TYPE_NONE) { + $discrColumnName = $this->_platform->getSQLResultCasing($this->class->discriminatorColumn['name']); + + if ($sqlResult[$discrColumnName] === '') { + throw HydrationException::emptyDiscriminatorValue(key($this->_rsm->aliasMap)); + } + + $entityName = $this->class->discriminatorMap[$sqlResult[$discrColumnName]]; + + unset($sqlResult[$discrColumnName]); + } + + foreach ($sqlResult as $column => $value) { + // Hydrate column information if not yet present + if ( ! isset($cache[$column])) { + if (($info = $this->hydrateColumnInfo($entityName, $column)) === null) { + continue; + } + + $cache[$column] = $info; + } + + // Convert field to a valid PHP value + if (isset($cache[$column]['field'])) { + $type = Type::getType($cache[$column]['class']->fieldMappings[$cache[$column]['name']]['type']); + $value = $type->convertToPHPValue($value, $this->_platform); + } + + // Prevent overwrite in case of inherit classes using same property name (See AbstractHydrator) + if (isset($cache[$column]) && ( ! isset($data[$cache[$column]['name']]) || $value !== null)) { + $data[$cache[$column]['name']] = $value; + } + } + + if (isset($this->_hints[Query::HINT_REFRESH_ENTITY])) { + $this->registerManaged($this->class, $this->_hints[Query::HINT_REFRESH_ENTITY], $data); + } + + $uow = $this->_em->getUnitOfWork(); + $entity = $uow->createEntity($entityName, $data, $this->_hints); + + $result[] = $entity; + } + + /** + * Retrieve column information form ResultSetMapping. + * + * @param string $entityName + * @param string $column + * + * @return array + */ + protected function hydrateColumnInfo($entityName, $column) + { + switch (true) { + case (isset($this->_rsm->fieldMappings[$column])): + $class = isset($this->declaringClasses[$column]) + ? $this->declaringClasses[$column] + : $this->class; + + // If class is not part of the inheritance, ignore + if ( ! ($class->name === $entityName || is_subclass_of($entityName, $class->name))) { + return null; + } + + return array( + 'class' => $class, + 'name' => $this->_rsm->fieldMappings[$column], + 'field' => true, + ); + + case (isset($this->_rsm->relationMap[$column])): + $class = isset($this->_rsm->relationMap[$column]) + ? $this->_rsm->relationMap[$column] + : $this->class; + + // If class is not self referencing, ignore + if ( ! ($class === $entityName || is_subclass_of($entityName, $class))) { + return null; + } + + // TODO: Decide what to do with associations. It seems original code is incomplete. + // One solution is to load the association, but it might require extra efforts. + return array('name' => $column); + + default: + return array( + 'name' => $this->_rsm->metaMappings[$column] + ); + } + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/SingleScalarHydrator.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/SingleScalarHydrator.php new file mode 100644 index 0000000..a5dabc6 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/SingleScalarHydrator.php @@ -0,0 +1,56 @@ +. + */ + +namespace Doctrine\ORM\Internal\Hydration; + +use Doctrine\DBAL\Connection, + Doctrine\ORM\NoResultException, + Doctrine\ORM\NonUniqueResultException; + +/** + * Hydrator that hydrates a single scalar value from the result set. + * + * @since 2.0 + * @author Roman Borschel + * @author Guilherme Blanco + */ +class SingleScalarHydrator extends AbstractHydrator +{ + /** + * {@inheritdoc} + */ + protected function hydrateAllData() + { + $data = $this->_stmt->fetchAll(\PDO::FETCH_ASSOC); + $numRows = count($data); + + if ($numRows === 0) { + throw new NoResultException(); + } + + if ($numRows > 1 || count($data[key($data)]) > 1) { + throw new NonUniqueResultException(); + } + + $cache = array(); + $result = $this->gatherScalarRowData($data[key($data)], $cache); + + return array_shift($result); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Annotation.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Annotation.php new file mode 100644 index 0000000..dd8f4ef --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Annotation.php @@ -0,0 +1,24 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +interface Annotation +{ +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Builder/AssociationBuilder.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Builder/AssociationBuilder.php new file mode 100644 index 0000000..843e2ce --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Builder/AssociationBuilder.php @@ -0,0 +1,167 @@ +. + */ + + +namespace Doctrine\ORM\Mapping\Builder; + +use Doctrine\ORM\Mapping\ClassMetadata; + +class AssociationBuilder +{ + /** + * @var ClassMetadataBuilder + */ + protected $builder; + + /** + * @var array + */ + protected $mapping; + + /** + * @var array + */ + protected $joinColumns; + + /** + * + * @var int + */ + protected $type; + + /** + * @param ClassMetadataBuilder $builder + * @param array $mapping + */ + public function __construct(ClassMetadataBuilder $builder, array $mapping, $type) + { + $this->builder = $builder; + $this->mapping = $mapping; + $this->type = $type; + } + + public function mappedBy($fieldName) + { + $this->mapping['mappedBy'] = $fieldName; + return $this; + } + + public function inversedBy($fieldName) + { + $this->mapping['inversedBy'] = $fieldName; + return $this; + } + + public function cascadeAll() + { + $this->mapping['cascade'] = array("ALL"); + return $this; + } + + public function cascadePersist() + { + $this->mapping['cascade'][] = "persist"; + return $this; + } + + public function cascadeRemove() + { + $this->mapping['cascade'][] = "remove"; + return $this; + } + + public function cascadeMerge() + { + $this->mapping['cascade'][] = "merge"; + return $this; + } + + public function cascadeDetach() + { + $this->mapping['cascade'][] = "detach"; + return $this; + } + + public function cascadeRefresh() + { + $this->mapping['cascade'][] = "refresh"; + return $this; + } + + public function fetchExtraLazy() + { + $this->mapping['fetch'] = ClassMetadata::FETCH_EXTRA_LAZY; + return $this; + } + + public function fetchEager() + { + $this->mapping['fetch'] = ClassMetadata::FETCH_EAGER; + return $this; + } + + public function fetchLazy() + { + $this->mapping['fetch'] = ClassMetadata::FETCH_LAZY; + return $this; + } + + /** + * Add Join Columns + * + * @param string $columnName + * @param string $referencedColumnName + * @param bool $nullable + * @param bool $unique + * @param string $onDelete + * @param string $columnDef + */ + public function addJoinColumn($columnName, $referencedColumnName, $nullable = true, $unique = false, $onDelete = null, $columnDef = null) + { + $this->joinColumns[] = array( + 'name' => $columnName, + 'referencedColumnName' => $referencedColumnName, + 'nullable' => $nullable, + 'unique' => $unique, + 'onDelete' => $onDelete, + 'columnDefinition' => $columnDef, + ); + return $this; + } + + /** + * @return ClassMetadataBuilder + */ + public function build() + { + $mapping = $this->mapping; + if ($this->joinColumns) { + $mapping['joinColumns'] = $this->joinColumns; + } + $cm = $this->builder->getClassMetadata(); + if ($this->type == ClassMetadata::MANY_TO_ONE) { + $cm->mapManyToOne($mapping); + } else if ($this->type == ClassMetadata::ONE_TO_ONE) { + $cm->mapOneToOne($mapping); + } else { + throw new \InvalidArgumentException("Type should be a ToOne Assocation here"); + } + return $this->builder; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Builder/ClassMetadataBuilder.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Builder/ClassMetadataBuilder.php new file mode 100644 index 0000000..fb1f1d5 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Builder/ClassMetadataBuilder.php @@ -0,0 +1,470 @@ +. + */ + +namespace Doctrine\ORM\Mapping\Builder; + +use Doctrine\ORM\Mapping\ClassMetadata, + Doctrine\ORM\Mapping\ClassMetadataInfo; + +/** + * Builder Object for ClassMetadata + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.2 + * @author Benjamin Eberlei + * @author Guilherme Blanco + */ +class ClassMetadataBuilder +{ + /** + * @var \Doctrine\ORM\Mapping\ClassMetadataInfo + */ + private $cm; + + /** + * @param \Doctrine\ORM\Mapping\ClassMetadataInfo $cm + */ + public function __construct(ClassMetadataInfo $cm) + { + $this->cm = $cm; + } + + /** + * @return ClassMetadata + */ + public function getClassMetadata() + { + return $this->cm; + } + + /** + * Mark the class as mapped superclass. + * + * @return ClassMetadataBuilder + */ + public function setMappedSuperClass() + { + $this->cm->isMappedSuperclass = true; + + return $this; + } + + /** + * Set custom Repository class name + * + * @param string $repositoryClassName + * @return ClassMetadataBuilder + */ + public function setCustomRepositoryClass($repositoryClassName) + { + $this->cm->setCustomRepositoryClass($repositoryClassName); + + return $this; + } + + /** + * Mark class read only + * + * @return ClassMetadataBuilder + */ + public function setReadOnly() + { + $this->cm->markReadOnly(); + + return $this; + } + + /** + * Set the table name + * + * @param string $name + * @return ClassMetadataBuilder + */ + public function setTable($name) + { + $this->cm->setPrimaryTable(array('name' => $name)); + + return $this; + } + + /** + * Add Index + * + * @param array $columns + * @param string $name + * @return ClassMetadataBuilder + */ + public function addIndex(array $columns, $name) + { + if (!isset($this->cm->table['indexes'])) { + $this->cm->table['indexes'] = array(); + } + + $this->cm->table['indexes'][$name] = array('columns' => $columns); + + return $this; + } + + /** + * Add Unique Constraint + * + * @param array $columns + * @param string $name + * @return ClassMetadataBuilder + */ + public function addUniqueConstraint(array $columns, $name) + { + if ( ! isset($this->cm->table['uniqueConstraints'])) { + $this->cm->table['uniqueConstraints'] = array(); + } + + $this->cm->table['uniqueConstraints'][$name] = array('columns' => $columns); + + return $this; + } + + /** + * Add named query + * + * @param string $name + * @param string $dqlQuery + * @return ClassMetadataBuilder + */ + public function addNamedQuery($name, $dqlQuery) + { + $this->cm->addNamedQuery(array( + 'name' => $name, + 'query' => $dqlQuery, + )); + + return $this; + } + + /** + * Set class as root of a joined table inheritance hierachy. + * + * @return ClassMetadataBuilder + */ + public function setJoinedTableInheritance() + { + $this->cm->setInheritanceType(ClassMetadata::INHERITANCE_TYPE_JOINED); + + return $this; + } + + /** + * Set class as root of a single table inheritance hierachy. + * + * @return ClassMetadataBuilder + */ + public function setSingleTableInheritance() + { + $this->cm->setInheritanceType(ClassMetadata::INHERITANCE_TYPE_SINGLE_TABLE); + + return $this; + } + + /** + * Set the discriminator column details. + * + * @param string $name + * @param string $type + */ + public function setDiscriminatorColumn($name, $type = 'string', $length = 255) + { + $this->cm->setDiscriminatorColumn(array( + 'name' => $name, + 'type' => $type, + 'length' => $length, + )); + + return $this; + } + + /** + * Add a subclass to this inheritance hierachy. + * + * @param string $name + * @param string $class + * @return ClassMetadataBuilder + */ + public function addDiscriminatorMapClass($name, $class) + { + $this->cm->addDiscriminatorMapClass($name, $class); + + return $this; + } + + /** + * Set deferred explicit change tracking policy. + * + * @return ClassMetadataBuilder + */ + public function setChangeTrackingPolicyDeferredExplicit() + { + $this->cm->setChangeTrackingPolicy(ClassMetadata::CHANGETRACKING_DEFERRED_EXPLICIT); + + return $this; + } + + /** + * Set notify change tracking policy. + * + * @return ClassMetadataBuilder + */ + public function setChangeTrackingPolicyNotify() + { + $this->cm->setChangeTrackingPolicy(ClassMetadata::CHANGETRACKING_NOTIFY); + + return $this; + } + + /** + * Add lifecycle event + * + * @param string $methodName + * @param string $event + * @return ClassMetadataBuilder + */ + public function addLifecycleEvent($methodName, $event) + { + $this->cm->addLifecycleCallback($methodName, $event); + + return $this; + } + + /** + * Add Field + * + * @param string $name + * @param string $type + * @param array $mapping + */ + public function addField($name, $type, array $mapping = array()) + { + $mapping['fieldName'] = $name; + $mapping['type'] = $type; + + $this->cm->mapField($mapping); + + return $this; + } + + /** + * Create a field builder. + * + * @param string $name + * @param string $type + * @return FieldBuilder + */ + public function createField($name, $type) + { + return new FieldBuilder( + $this, + array( + 'fieldName' => $name, + 'type' => $type + ) + ); + } + + /** + * Add a simple many to one association, optionally with the inversed by field. + * + * @param string $name + * @param string $targetEntity + * @param string|null $inversedBy + * @return ClassMetadataBuilder + */ + public function addManyToOne($name, $targetEntity, $inversedBy = null) + { + $builder = $this->createManyToOne($name, $targetEntity); + + if ($inversedBy) { + $builder->inversedBy($inversedBy); + } + + return $builder->build(); + } + + /** + * Create a ManyToOne Assocation Builder. + * + * Note: This method does not add the association, you have to call build() on the AssociationBuilder. + * + * @param string $name + * @param string $targetEntity + * @return AssociationBuilder + */ + public function createManyToOne($name, $targetEntity) + { + return new AssociationBuilder( + $this, + array( + 'fieldName' => $name, + 'targetEntity' => $targetEntity + ), + ClassMetadata::MANY_TO_ONE + ); + } + + /** + * Create OneToOne Assocation Builder + * + * @param string $name + * @param string $targetEntity + * @return AssociationBuilder + */ + public function createOneToOne($name, $targetEntity) + { + return new AssociationBuilder( + $this, + array( + 'fieldName' => $name, + 'targetEntity' => $targetEntity + ), + ClassMetadata::ONE_TO_ONE + ); + } + + /** + * Add simple inverse one-to-one assocation. + * + * @param string $name + * @param string $targetEntity + * @param string $mappedBy + * @return ClassMetadataBuilder + */ + public function addInverseOneToOne($name, $targetEntity, $mappedBy) + { + $builder = $this->createOneToOne($name, $targetEntity); + $builder->mappedBy($mappedBy); + + return $builder->build(); + } + + /** + * Add simple owning one-to-one assocation. + * + * @param string $name + * @param string $targetEntity + * @param string $inversedBy + * @return ClassMetadataBuilder + */ + public function addOwningOneToOne($name, $targetEntity, $inversedBy = null) + { + $builder = $this->createOneToOne($name, $targetEntity); + + if ($inversedBy) { + $builder->inversedBy($inversedBy); + } + + return $builder->build(); + } + + /** + * Create ManyToMany Assocation Builder + * + * @param string $name + * @param string $targetEntity + * @return ManyToManyAssociationBuilder + */ + public function createManyToMany($name, $targetEntity) + { + return new ManyToManyAssociationBuilder( + $this, + array( + 'fieldName' => $name, + 'targetEntity' => $targetEntity + ), + ClassMetadata::MANY_TO_MANY + ); + } + + /** + * Add a simple owning many to many assocation. + * + * @param string $name + * @param string $targetEntity + * @param string|null $inversedBy + * @return ClassMetadataBuilder + */ + public function addOwningManyToMany($name, $targetEntity, $inversedBy = null) + { + $builder = $this->createManyToMany($name, $targetEntity); + + if ($inversedBy) { + $builder->inversedBy($inversedBy); + } + + return $builder->build(); + } + + /** + * Add a simple inverse many to many assocation. + * + * @param string $name + * @param string $targetEntity + * @param string $mappedBy + * @return ClassMetadataBuilder + */ + public function addInverseManyToMany($name, $targetEntity, $mappedBy) + { + $builder = $this->createManyToMany($name, $targetEntity); + $builder->mappedBy($mappedBy); + + return $builder->build(); + } + + /** + * Create a one to many assocation builder + * + * @param string $name + * @param string $targetEntity + * @return OneToManyAssociationBuilder + */ + public function createOneToMany($name, $targetEntity) + { + return new OneToManyAssociationBuilder( + $this, + array( + 'fieldName' => $name, + 'targetEntity' => $targetEntity + ), + ClassMetadata::ONE_TO_MANY + ); + } + + /** + * Add simple OneToMany assocation. + * + * @param string $name + * @param string $targetEntity + * @param string $mappedBy + * @return ClassMetadataBuilder + */ + public function addOneToMany($name, $targetEntity, $mappedBy) + { + $builder = $this->createOneToMany($name, $targetEntity); + $builder->mappedBy($mappedBy); + + return $builder->build(); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Builder/FieldBuilder.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Builder/FieldBuilder.php new file mode 100644 index 0000000..3f4a5bb --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Builder/FieldBuilder.php @@ -0,0 +1,223 @@ +. + */ + + +namespace Doctrine\ORM\Mapping\Builder; + +/** + * Field Builder + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.2 + * @author Benjamin Eberlei + */ +class FieldBuilder +{ + /** + * @var ClassMetadataBuilder + */ + private $builder; + /** + * @var array + */ + private $mapping; + /** + * @var bool + */ + private $version; + + /** + * @var string + */ + private $generatedValue; + + /** + * @var array + */ + private $sequenceDef; + + /** + * + * @param ClassMetadataBuilder $builder + * @param array $mapping + */ + public function __construct(ClassMetadataBuilder $builder, array $mapping) + { + $this->builder = $builder; + $this->mapping = $mapping; + } + + /** + * Set length. + * + * @param int $length + * @return FieldBuilder + */ + public function length($length) + { + $this->mapping['length'] = $length; + return $this; + } + + /** + * Set nullable + * + * @param bool + * @return FieldBuilder + */ + public function nullable($flag = true) + { + $this->mapping['nullable'] = (bool)$flag; + return $this; + } + + /** + * Set Unique + * + * @param bool + * @return FieldBuilder + */ + public function unique($flag = true) + { + $this->mapping['unique'] = (bool)$flag; + return $this; + } + + /** + * Set column name + * + * @param string $name + * @return FieldBuilder + */ + public function columnName($name) + { + $this->mapping['columnName'] = $name; + return $this; + } + + /** + * Set Precision + * + * @param int $p + * @return FieldBuilder + */ + public function precision($p) + { + $this->mapping['precision'] = $p; + return $this; + } + + /** + * Set scale. + * + * @param int $s + * @return FieldBuilder + */ + public function scale($s) + { + $this->mapping['scale'] = $s; + return $this; + } + + /** + * Set field as primary key. + * + * @return FieldBuilder + */ + public function isPrimaryKey() + { + $this->mapping['id'] = true; + return $this; + } + + /** + * @param int $strategy + * @return FieldBuilder + */ + public function generatedValue($strategy = 'AUTO') + { + $this->generatedValue = $strategy; + return $this; + } + + /** + * Set field versioned + * + * @return FieldBuilder + */ + public function isVersionField() + { + $this->version = true; + return $this; + } + + /** + * Set Sequence Generator + * + * @param string $sequenceName + * @param int $allocationSize + * @param int $initialValue + * @return FieldBuilder + */ + public function setSequenceGenerator($sequenceName, $allocationSize = 1, $initialValue = 1) + { + $this->sequenceDef = array( + 'sequenceName' => $sequenceName, + 'allocationSize' => $allocationSize, + 'initialValue' => $initialValue, + ); + return $this; + } + + /** + * Set column definition. + * + * @param string $def + * @return FieldBuilder + */ + public function columnDefinition($def) + { + $this->mapping['columnDefinition'] = $def; + return $this; + } + + /** + * Finalize this field and attach it to the ClassMetadata. + * + * Without this call a FieldBuilder has no effect on the ClassMetadata. + * + * @return ClassMetadataBuilder + */ + public function build() + { + $cm = $this->builder->getClassMetadata(); + if ($this->generatedValue) { + $cm->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' . $this->generatedValue)); + } + if ($this->version) { + $cm->setVersionMapping($this->mapping); + } + $cm->mapField($this->mapping); + if ($this->sequenceDef) { + $cm->setSequenceGeneratorDefinition($this->sequenceDef); + } + return $this->builder; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Builder/ManyToManyAssociationBuilder.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Builder/ManyToManyAssociationBuilder.php new file mode 100644 index 0000000..c1dd1e5 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Builder/ManyToManyAssociationBuilder.php @@ -0,0 +1,86 @@ +. + */ + + +namespace Doctrine\ORM\Mapping\Builder; + +/** + * ManyToMany Association Builder + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.0 + * @author Benjamin Eberlei + */ +class ManyToManyAssociationBuilder extends OneToManyAssociationBuilder +{ + private $joinTableName; + + private $inverseJoinColumns = array(); + + public function setJoinTable($name) + { + $this->joinTableName = $name; + return $this; + } + + /** + * Add Inverse Join Columns + * + * @param string $columnName + * @param string $referencedColumnName + * @param bool $nullable + * @param bool $unique + * @param string $onDelete + * @param string $columnDef + */ + public function addInverseJoinColumn($columnName, $referencedColumnName, $nullable = true, $unique = false, $onDelete = null, $columnDef = null) + { + $this->inverseJoinColumns[] = array( + 'name' => $columnName, + 'referencedColumnName' => $referencedColumnName, + 'nullable' => $nullable, + 'unique' => $unique, + 'onDelete' => $onDelete, + 'columnDefinition' => $columnDef, + ); + return $this; + } + + /** + * @return ClassMetadataBuilder + */ + public function build() + { + $mapping = $this->mapping; + $mapping['joinTable'] = array(); + if ($this->joinColumns) { + $mapping['joinTable']['joinColumns'] = $this->joinColumns; + } + if ($this->inverseJoinColumns) { + $mapping['joinTable']['inverseJoinColumns'] = $this->inverseJoinColumns; + } + if ($this->joinTableName) { + $mapping['joinTable']['name'] = $this->joinTableName; + } + $cm = $this->builder->getClassMetadata(); + $cm->mapManyToMany($mapping); + return $this->builder; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Builder/OneToManyAssociationBuilder.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Builder/OneToManyAssociationBuilder.php new file mode 100644 index 0000000..be55c2d --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Builder/OneToManyAssociationBuilder.php @@ -0,0 +1,62 @@ +. + */ + + +namespace Doctrine\ORM\Mapping\Builder; + +/** + * OneToMany Association Builder + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.0 + * @author Benjamin Eberlei + */ +class OneToManyAssociationBuilder extends AssociationBuilder +{ + /** + * @param array $fieldNames + * @return OneToManyAssociationBuilder + */ + public function setOrderBy(array $fieldNames) + { + $this->mapping['orderBy'] = $fieldNames; + return $this; + } + + public function setIndexBy($fieldName) + { + $this->mapping['indexBy'] = $fieldName; + return $this; + } + + /** + * @return ClassMetadataBuilder + */ + public function build() + { + $mapping = $this->mapping; + if ($this->joinColumns) { + $mapping['joinColumns'] = $this->joinColumns; + } + $cm = $this->builder->getClassMetadata(); + $cm->mapOneToMany($mapping); + return $this->builder; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ChangeTrackingPolicy.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ChangeTrackingPolicy.php new file mode 100644 index 0000000..a9cc372 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ChangeTrackingPolicy.php @@ -0,0 +1,30 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("CLASS") + */ +final class ChangeTrackingPolicy implements Annotation +{ + /** @var string */ + public $value; +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadata.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadata.php new file mode 100644 index 0000000..70b8f9e --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadata.php @@ -0,0 +1,44 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +use ReflectionClass, ReflectionProperty; + +/** + * A ClassMetadata instance holds all the object-relational mapping metadata + * of an entity and it's associations. + * + * Once populated, ClassMetadata instances are usually cached in a serialized form. + * + * IMPORTANT NOTE: + * + * The fields of this class are only public for 2 reasons: + * 1) To allow fast READ access. + * 2) To drastically reduce the size of a serialized instance (private/protected members + * get the whole class name, namespace inclusive, prepended to every property in + * the serialized representation). + * + * @author Roman Borschel + * @author Jonathan H. Wage + * @since 2.0 + */ +class ClassMetadata extends ClassMetadataInfo +{ +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php new file mode 100644 index 0000000..e2a5621 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php @@ -0,0 +1,593 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +use ReflectionException, + Doctrine\ORM\ORMException, + Doctrine\ORM\EntityManager, + Doctrine\DBAL\Platforms, + Doctrine\ORM\Events, + Doctrine\Common\Persistence\Mapping\RuntimeReflectionService, + Doctrine\Common\Persistence\Mapping\ReflectionService, + Doctrine\Common\Persistence\Mapping\ClassMetadataFactory as ClassMetadataFactoryInterface; + +/** + * The ClassMetadataFactory is used to create ClassMetadata objects that contain all the + * metadata mapping informations of a class which describes how a class should be mapped + * to a relational database. + * + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class ClassMetadataFactory implements ClassMetadataFactoryInterface +{ + /** + * @var EntityManager + */ + private $em; + + /** + * @var AbstractPlatform + */ + private $targetPlatform; + + /** + * @var \Doctrine\ORM\Mapping\Driver\Driver + */ + private $driver; + + /** + * @var \Doctrine\Common\EventManager + */ + private $evm; + + /** + * @var \Doctrine\Common\Cache\Cache + */ + private $cacheDriver; + + /** + * @var array + */ + private $loadedMetadata = array(); + + /** + * @var bool + */ + private $initialized = false; + + /** + * @var ReflectionService + */ + private $reflectionService; + + /** + * @param EntityManager $$em + */ + public function setEntityManager(EntityManager $em) + { + $this->em = $em; + } + + /** + * Sets the cache driver used by the factory to cache ClassMetadata instances. + * + * @param \Doctrine\Common\Cache\Cache $cacheDriver + */ + public function setCacheDriver($cacheDriver) + { + $this->cacheDriver = $cacheDriver; + } + + /** + * Gets the cache driver used by the factory to cache ClassMetadata instances. + * + * @return \Doctrine\Common\Cache\Cache + */ + public function getCacheDriver() + { + return $this->cacheDriver; + } + + public function getLoadedMetadata() + { + return $this->loadedMetadata; + } + + /** + * Forces the factory to load the metadata of all classes known to the underlying + * mapping driver. + * + * @return array The ClassMetadata instances of all mapped classes. + */ + public function getAllMetadata() + { + if ( ! $this->initialized) { + $this->initialize(); + } + + $metadata = array(); + foreach ($this->driver->getAllClassNames() as $className) { + $metadata[] = $this->getMetadataFor($className); + } + + return $metadata; + } + + /** + * Lazy initialization of this stuff, especially the metadata driver, + * since these are not needed at all when a metadata cache is active. + */ + private function initialize() + { + $this->driver = $this->em->getConfiguration()->getMetadataDriverImpl(); + $this->targetPlatform = $this->em->getConnection()->getDatabasePlatform(); + $this->evm = $this->em->getEventManager(); + $this->initialized = true; + } + + /** + * Gets the class metadata descriptor for a class. + * + * @param string $className The name of the class. + * @return \Doctrine\ORM\Mapping\ClassMetadata + */ + public function getMetadataFor($className) + { + if ( ! isset($this->loadedMetadata[$className])) { + $realClassName = $className; + + // Check for namespace alias + if (strpos($className, ':') !== false) { + list($namespaceAlias, $simpleClassName) = explode(':', $className); + $realClassName = $this->em->getConfiguration()->getEntityNamespace($namespaceAlias) . '\\' . $simpleClassName; + + if (isset($this->loadedMetadata[$realClassName])) { + // We do not have the alias name in the map, include it + $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName]; + + return $this->loadedMetadata[$realClassName]; + } + } + + if ($this->cacheDriver) { + if (($cached = $this->cacheDriver->fetch("$realClassName\$CLASSMETADATA")) !== false) { + $this->wakeupReflection($cached, $this->getReflectionService()); + $this->loadedMetadata[$realClassName] = $cached; + } else { + foreach ($this->loadMetadata($realClassName) as $loadedClassName) { + $this->cacheDriver->save( + "$loadedClassName\$CLASSMETADATA", $this->loadedMetadata[$loadedClassName], null + ); + } + } + } else { + $this->loadMetadata($realClassName); + } + + if ($className != $realClassName) { + // We do not have the alias name in the map, include it + $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName]; + } + } + + return $this->loadedMetadata[$className]; + } + + /** + * Checks whether the factory has the metadata for a class loaded already. + * + * @param string $className + * @return boolean TRUE if the metadata of the class in question is already loaded, FALSE otherwise. + */ + public function hasMetadataFor($className) + { + return isset($this->loadedMetadata[$className]); + } + + /** + * Sets the metadata descriptor for a specific class. + * + * NOTE: This is only useful in very special cases, like when generating proxy classes. + * + * @param string $className + * @param ClassMetadata $class + */ + public function setMetadataFor($className, $class) + { + $this->loadedMetadata[$className] = $class; + } + + /** + * Get array of parent classes for the given entity class + * + * @param string $name + * @return array $parentClasses + */ + protected function getParentClasses($name) + { + // Collect parent classes, ignoring transient (not-mapped) classes. + $parentClasses = array(); + foreach (array_reverse($this->getReflectionService()->getParentClasses($name)) as $parentClass) { + if ( ! $this->driver->isTransient($parentClass)) { + $parentClasses[] = $parentClass; + } + } + return $parentClasses; + } + + /** + * Loads the metadata of the class in question and all it's ancestors whose metadata + * is still not loaded. + * + * @param string $name The name of the class for which the metadata should get loaded. + * @param array $tables The metadata collection to which the loaded metadata is added. + */ + protected function loadMetadata($name) + { + if ( ! $this->initialized) { + $this->initialize(); + } + + $loaded = array(); + + $parentClasses = $this->getParentClasses($name); + $parentClasses[] = $name; + + // Move down the hierarchy of parent classes, starting from the topmost class + $parent = null; + $rootEntityFound = false; + $visited = array(); + foreach ($parentClasses as $className) { + if (isset($this->loadedMetadata[$className])) { + $parent = $this->loadedMetadata[$className]; + if ( ! $parent->isMappedSuperclass) { + $rootEntityFound = true; + array_unshift($visited, $className); + } + continue; + } + + $class = $this->newClassMetadataInstance($className); + $this->initializeReflection($class, $this->getReflectionService()); + + if ($parent) { + $class->setInheritanceType($parent->inheritanceType); + $class->setDiscriminatorColumn($parent->discriminatorColumn); + $class->setIdGeneratorType($parent->generatorType); + $this->addInheritedFields($class, $parent); + $this->addInheritedRelations($class, $parent); + $class->setIdentifier($parent->identifier); + $class->setVersioned($parent->isVersioned); + $class->setVersionField($parent->versionField); + $class->setDiscriminatorMap($parent->discriminatorMap); + $class->setLifecycleCallbacks($parent->lifecycleCallbacks); + $class->setChangeTrackingPolicy($parent->changeTrackingPolicy); + if ($parent->isMappedSuperclass) { + $class->setCustomRepositoryClass($parent->customRepositoryClassName); + } + } + + // Invoke driver + try { + $this->driver->loadMetadataForClass($className, $class); + } catch (ReflectionException $e) { + throw MappingException::reflectionFailure($className, $e); + } + + // If this class has a parent the id generator strategy is inherited. + // However this is only true if the hierachy of parents contains the root entity, + // if it consinsts of mapped superclasses these don't necessarily include the id field. + if ($parent && $rootEntityFound) { + if ($parent->isIdGeneratorSequence()) { + $class->setSequenceGeneratorDefinition($parent->sequenceGeneratorDefinition); + } else if ($parent->isIdGeneratorTable()) { + $class->getTableGeneratorDefinition($parent->tableGeneratorDefinition); + } + if ($parent->generatorType) { + $class->setIdGeneratorType($parent->generatorType); + } + if ($parent->idGenerator) { + $class->setIdGenerator($parent->idGenerator); + } + } else { + $this->completeIdGeneratorMapping($class); + } + + if ($parent && $parent->isInheritanceTypeSingleTable()) { + $class->setPrimaryTable($parent->table); + } + + if ($parent && $parent->containsForeignIdentifier) { + $class->containsForeignIdentifier = true; + } + + if ($parent && !empty ($parent->namedQueries)) { + $this->addInheritedNamedQueries($class, $parent); + } + + $class->setParentClasses($visited); + + if ($this->evm->hasListeners(Events::loadClassMetadata)) { + $eventArgs = new \Doctrine\ORM\Event\LoadClassMetadataEventArgs($class, $this->em); + $this->evm->dispatchEvent(Events::loadClassMetadata, $eventArgs); + } + $this->wakeupReflection($class, $this->getReflectionService()); + + $this->validateRuntimeMetadata($class, $parent); + + $this->loadedMetadata[$className] = $class; + + $parent = $class; + + if ( ! $class->isMappedSuperclass) { + $rootEntityFound = true; + array_unshift($visited, $className); + } + + $loaded[] = $className; + } + + return $loaded; + } + + /** + * Validate runtime metadata is correctly defined. + * + * @param ClassMetadata $class + * @param ClassMetadata $parent + */ + protected function validateRuntimeMetadata($class, $parent) + { + if ( ! $class->reflClass ) { + // only validate if there is a reflection class instance + return; + } + + $class->validateIdentifier(); + $class->validateAssocations(); + $class->validateLifecycleCallbacks($this->getReflectionService()); + + // verify inheritance + if (!$class->isMappedSuperclass && !$class->isInheritanceTypeNone()) { + if (!$parent) { + if (count($class->discriminatorMap) == 0) { + throw MappingException::missingDiscriminatorMap($class->name); + } + if (!$class->discriminatorColumn) { + throw MappingException::missingDiscriminatorColumn($class->name); + } + } else if ($parent && !$class->reflClass->isAbstract() && !in_array($class->name, array_values($class->discriminatorMap))) { + // enforce discriminator map for all entities of an inheritance hierachy, otherwise problems will occur. + throw MappingException::mappedClassNotPartOfDiscriminatorMap($class->name, $class->rootEntityName); + } + } else if ($class->isMappedSuperclass && $class->name == $class->rootEntityName && (count($class->discriminatorMap) || $class->discriminatorColumn)) { + // second condition is necessary for mapped superclasses in the middle of an inheritance hierachy + throw MappingException::noInheritanceOnMappedSuperClass($class->name); + } + } + + /** + * Creates a new ClassMetadata instance for the given class name. + * + * @param string $className + * @return \Doctrine\ORM\Mapping\ClassMetadata + */ + protected function newClassMetadataInstance($className) + { + return new ClassMetadata($className); + } + + /** + * Adds inherited fields to the subclass mapping. + * + * @param \Doctrine\ORM\Mapping\ClassMetadata $subClass + * @param \Doctrine\ORM\Mapping\ClassMetadata $parentClass + */ + private function addInheritedFields(ClassMetadata $subClass, ClassMetadata $parentClass) + { + foreach ($parentClass->fieldMappings as $fieldName => $mapping) { + if ( ! isset($mapping['inherited']) && ! $parentClass->isMappedSuperclass) { + $mapping['inherited'] = $parentClass->name; + } + if ( ! isset($mapping['declared'])) { + $mapping['declared'] = $parentClass->name; + } + $subClass->addInheritedFieldMapping($mapping); + } + foreach ($parentClass->reflFields as $name => $field) { + $subClass->reflFields[$name] = $field; + } + } + + /** + * Adds inherited association mappings to the subclass mapping. + * + * @param \Doctrine\ORM\Mapping\ClassMetadata $subClass + * @param \Doctrine\ORM\Mapping\ClassMetadata $parentClass + */ + private function addInheritedRelations(ClassMetadata $subClass, ClassMetadata $parentClass) + { + foreach ($parentClass->associationMappings as $field => $mapping) { + if ($parentClass->isMappedSuperclass) { + if ($mapping['type'] & ClassMetadata::TO_MANY && !$mapping['isOwningSide']) { + throw MappingException::illegalToManyAssocationOnMappedSuperclass($parentClass->name, $field); + } + $mapping['sourceEntity'] = $subClass->name; + } + + //$subclassMapping = $mapping; + if ( ! isset($mapping['inherited']) && ! $parentClass->isMappedSuperclass) { + $mapping['inherited'] = $parentClass->name; + } + if ( ! isset($mapping['declared'])) { + $mapping['declared'] = $parentClass->name; + } + $subClass->addInheritedAssociationMapping($mapping); + } + } + + /** + * Adds inherited named queries to the subclass mapping. + * + * @since 2.2 + * @param \Doctrine\ORM\Mapping\ClassMetadata $subClass + * @param \Doctrine\ORM\Mapping\ClassMetadata $parentClass + */ + private function addInheritedNamedQueries(ClassMetadata $subClass, ClassMetadata $parentClass) + { + foreach ($parentClass->namedQueries as $name => $query) { + if (!isset ($subClass->namedQueries[$name])) { + $subClass->addNamedQuery(array( + 'name' => $query['name'], + 'query' => $query['query'] + )); + } + } + } + + /** + * Completes the ID generator mapping. If "auto" is specified we choose the generator + * most appropriate for the targeted database platform. + * + * @param \Doctrine\ORM\Mapping\ClassMetadata $class + */ + private function completeIdGeneratorMapping(ClassMetadataInfo $class) + { + $idGenType = $class->generatorType; + if ($idGenType == ClassMetadata::GENERATOR_TYPE_AUTO) { + if ($this->targetPlatform->prefersSequences()) { + $class->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_SEQUENCE); + } else if ($this->targetPlatform->prefersIdentityColumns()) { + $class->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_IDENTITY); + } else { + $class->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_TABLE); + } + } + + // Create & assign an appropriate ID generator instance + switch ($class->generatorType) { + case ClassMetadata::GENERATOR_TYPE_IDENTITY: + // For PostgreSQL IDENTITY (SERIAL) we need a sequence name. It defaults to + // __seq in PostgreSQL for SERIAL columns. + // Not pretty but necessary and the simplest solution that currently works. + $seqName = $this->targetPlatform instanceof Platforms\PostgreSQLPlatform ? + $class->getTableName() . '_' . $class->columnNames[$class->identifier[0]] . '_seq' : + null; + $class->setIdGenerator(new \Doctrine\ORM\Id\IdentityGenerator($seqName)); + break; + case ClassMetadata::GENERATOR_TYPE_SEQUENCE: + // If there is no sequence definition yet, create a default definition + $definition = $class->sequenceGeneratorDefinition; + if ( ! $definition) { + $sequenceName = $class->getTableName() . '_' . $class->getSingleIdentifierColumnName() . '_seq'; + $definition['sequenceName'] = $this->targetPlatform->fixSchemaElementName($sequenceName); + $definition['allocationSize'] = 1; + $definition['initialValue'] = 1; + $class->setSequenceGeneratorDefinition($definition); + } + $sequenceGenerator = new \Doctrine\ORM\Id\SequenceGenerator( + $definition['sequenceName'], + $definition['allocationSize'] + ); + $class->setIdGenerator($sequenceGenerator); + break; + case ClassMetadata::GENERATOR_TYPE_NONE: + $class->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator()); + break; + case ClassMetadata::GENERATOR_TYPE_TABLE: + throw new ORMException("TableGenerator not yet implemented."); + break; + default: + throw new ORMException("Unknown generator type: " . $class->generatorType); + } + } + + /** + * Check if this class is mapped by this EntityManager + ClassMetadata configuration + * + * @param $class + * @return bool + */ + public function isTransient($class) + { + if ( ! $this->initialized) { + $this->initialize(); + } + + // Check for namespace alias + if (strpos($class, ':') !== false) { + list($namespaceAlias, $simpleClassName) = explode(':', $class); + $class = $this->em->getConfiguration()->getEntityNamespace($namespaceAlias) . '\\' . $simpleClassName; + } + + return $this->driver->isTransient($class); + } + + /** + * Get reflectionService. + * + * @return \Doctrine\Common\Persistence\Mapping\ReflectionService + */ + public function getReflectionService() + { + if ($this->reflectionService === null) { + $this->reflectionService = new RuntimeReflectionService(); + } + return $this->reflectionService; + } + + /** + * Set reflectionService. + * + * @param reflectionService the value to set. + */ + public function setReflectionService(ReflectionService $reflectionService) + { + $this->reflectionService = $reflectionService; + } + + /** + * Wakeup reflection after ClassMetadata gets unserialized from cache. + * + * @param ClassMetadataInfo $class + * @param ReflectionService $reflService + * @return void + */ + protected function wakeupReflection(ClassMetadataInfo $class, ReflectionService $reflService) + { + $class->wakeupReflection($reflService); + } + + /** + * Initialize Reflection after ClassMetadata was constructed. + * + * @param ClassMetadataInfo $class + * @param ReflectionService $reflService + * @return void + */ + protected function initializeReflection(ClassMetadataInfo $class, ReflectionService $reflService) + { + $class->initializeReflection($reflService); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php new file mode 100644 index 0000000..31e2b75 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -0,0 +1,2340 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +use Doctrine\DBAL\Types\Type; +use ReflectionClass; +use Doctrine\Common\Persistence\Mapping\ClassMetadata; + +/** + * A ClassMetadata instance holds all the object-relational mapping metadata + * of an entity and it's associations. + * + * Once populated, ClassMetadata instances are usually cached in a serialized form. + * + * IMPORTANT NOTE: + * + * The fields of this class are only public for 2 reasons: + * 1) To allow fast READ access. + * 2) To drastically reduce the size of a serialized instance (private/protected members + * get the whole class name, namespace inclusive, prepended to every property in + * the serialized representation). + * + * @author Roman Borschel + * @author Jonathan H. Wage + * @since 2.0 + */ +class ClassMetadataInfo implements ClassMetadata +{ + /* The inheritance mapping types */ + /** + * NONE means the class does not participate in an inheritance hierarchy + * and therefore does not need an inheritance mapping type. + */ + const INHERITANCE_TYPE_NONE = 1; + /** + * JOINED means the class will be persisted according to the rules of + * Class Table Inheritance. + */ + const INHERITANCE_TYPE_JOINED = 2; + /** + * SINGLE_TABLE means the class will be persisted according to the rules of + * Single Table Inheritance. + */ + const INHERITANCE_TYPE_SINGLE_TABLE = 3; + /** + * TABLE_PER_CLASS means the class will be persisted according to the rules + * of Concrete Table Inheritance. + */ + const INHERITANCE_TYPE_TABLE_PER_CLASS = 4; + + /* The Id generator types. */ + /** + * AUTO means the generator type will depend on what the used platform prefers. + * Offers full portability. + */ + const GENERATOR_TYPE_AUTO = 1; + /** + * SEQUENCE means a separate sequence object will be used. Platforms that do + * not have native sequence support may emulate it. Full portability is currently + * not guaranteed. + */ + const GENERATOR_TYPE_SEQUENCE = 2; + /** + * TABLE means a separate table is used for id generation. + * Offers full portability. + */ + const GENERATOR_TYPE_TABLE = 3; + /** + * IDENTITY means an identity column is used for id generation. The database + * will fill in the id column on insertion. Platforms that do not support + * native identity columns may emulate them. Full portability is currently + * not guaranteed. + */ + const GENERATOR_TYPE_IDENTITY = 4; + /** + * NONE means the class does not have a generated id. That means the class + * must have a natural, manually assigned id. + */ + const GENERATOR_TYPE_NONE = 5; + /** + * DEFERRED_IMPLICIT means that changes of entities are calculated at commit-time + * by doing a property-by-property comparison with the original data. This will + * be done for all entities that are in MANAGED state at commit-time. + * + * This is the default change tracking policy. + */ + const CHANGETRACKING_DEFERRED_IMPLICIT = 1; + /** + * DEFERRED_EXPLICIT means that changes of entities are calculated at commit-time + * by doing a property-by-property comparison with the original data. This will + * be done only for entities that were explicitly saved (through persist() or a cascade). + */ + const CHANGETRACKING_DEFERRED_EXPLICIT = 2; + /** + * NOTIFY means that Doctrine relies on the entities sending out notifications + * when their properties change. Such entity classes must implement + * the NotifyPropertyChanged interface. + */ + const CHANGETRACKING_NOTIFY = 3; + /** + * Specifies that an association is to be fetched when it is first accessed. + */ + const FETCH_LAZY = 2; + /** + * Specifies that an association is to be fetched when the owner of the + * association is fetched. + */ + const FETCH_EAGER = 3; + /** + * Specifies that an association is to be fetched lazy (on first access) and that + * commands such as Collection#count, Collection#slice are issued directly against + * the database if the collection is not yet initialized. + */ + const FETCH_EXTRA_LAZY = 4; + /** + * Identifies a one-to-one association. + */ + const ONE_TO_ONE = 1; + /** + * Identifies a many-to-one association. + */ + const MANY_TO_ONE = 2; + /** + * Identifies a one-to-many association. + */ + const ONE_TO_MANY = 4; + /** + * Identifies a many-to-many association. + */ + const MANY_TO_MANY = 8; + /** + * Combined bitmask for to-one (single-valued) associations. + */ + const TO_ONE = 3; + /** + * Combined bitmask for to-many (collection-valued) associations. + */ + const TO_MANY = 12; + + /** + * READ-ONLY: The name of the entity class. + */ + public $name; + + /** + * READ-ONLY: The namespace the entity class is contained in. + * + * @var string + * @todo Not really needed. Usage could be localized. + */ + public $namespace; + + /** + * READ-ONLY: The name of the entity class that is at the root of the mapped entity inheritance + * hierarchy. If the entity is not part of a mapped inheritance hierarchy this is the same + * as {@link $entityName}. + * + * @var string + */ + public $rootEntityName; + + /** + * The name of the custom repository class used for the entity class. + * (Optional). + * + * @var string + */ + public $customRepositoryClassName; + + /** + * READ-ONLY: Whether this class describes the mapping of a mapped superclass. + * + * @var boolean + */ + public $isMappedSuperclass = false; + + /** + * READ-ONLY: The names of the parent classes (ancestors). + * + * @var array + */ + public $parentClasses = array(); + + /** + * READ-ONLY: The names of all subclasses (descendants). + * + * @var array + */ + public $subClasses = array(); + + /** + * READ-ONLY: The named queries allowed to be called directly from Repository. + * + * @var array + */ + public $namedQueries = array(); + + /** + * READ-ONLY: The field names of all fields that are part of the identifier/primary key + * of the mapped entity class. + * + * @var array + */ + public $identifier = array(); + + /** + * READ-ONLY: The inheritance mapping type used by the class. + * + * @var integer + */ + public $inheritanceType = self::INHERITANCE_TYPE_NONE; + + /** + * READ-ONLY: The Id generator type used by the class. + * + * @var string + */ + public $generatorType = self::GENERATOR_TYPE_NONE; + + /** + * READ-ONLY: The field mappings of the class. + * Keys are field names and values are mapping definitions. + * + * The mapping definition array has the following values: + * + * - fieldName (string) + * The name of the field in the Entity. + * + * - type (string) + * The type name of the mapped field. Can be one of Doctrine's mapping types + * or a custom mapping type. + * + * - columnName (string, optional) + * The column name. Optional. Defaults to the field name. + * + * - length (integer, optional) + * The database length of the column. Optional. Default value taken from + * the type. + * + * - id (boolean, optional) + * Marks the field as the primary key of the entity. Multiple fields of an + * entity can have the id attribute, forming a composite key. + * + * - nullable (boolean, optional) + * Whether the column is nullable. Defaults to FALSE. + * + * - columnDefinition (string, optional, schema-only) + * The SQL fragment that is used when generating the DDL for the column. + * + * - precision (integer, optional, schema-only) + * The precision of a decimal column. Only valid if the column type is decimal. + * + * - scale (integer, optional, schema-only) + * The scale of a decimal column. Only valid if the column type is decimal. + * + [* - 'unique'] (string, optional, schema-only) + * Whether a unique constraint should be generated for the column. + * + * @var array + */ + public $fieldMappings = array(); + + /** + * READ-ONLY: An array of field names. Used to look up field names from column names. + * Keys are column names and values are field names. + * This is the reverse lookup map of $_columnNames. + * + * @var array + */ + public $fieldNames = array(); + + /** + * READ-ONLY: A map of field names to column names. Keys are field names and values column names. + * Used to look up column names from field names. + * This is the reverse lookup map of $_fieldNames. + * + * @var array + * @todo We could get rid of this array by just using $fieldMappings[$fieldName]['columnName']. + */ + public $columnNames = array(); + + /** + * READ-ONLY: The discriminator value of this class. + * + * This does only apply to the JOINED and SINGLE_TABLE inheritance mapping strategies + * where a discriminator column is used. + * + * @var mixed + * @see discriminatorColumn + */ + public $discriminatorValue; + + /** + * READ-ONLY: The discriminator map of all mapped classes in the hierarchy. + * + * This does only apply to the JOINED and SINGLE_TABLE inheritance mapping strategies + * where a discriminator column is used. + * + * @var mixed + * @see discriminatorColumn + */ + public $discriminatorMap = array(); + + /** + * READ-ONLY: The definition of the discriminator column used in JOINED and SINGLE_TABLE + * inheritance mappings. + * + * @var array + */ + public $discriminatorColumn; + + /** + * READ-ONLY: The primary table definition. The definition is an array with the + * following entries: + * + * name => + * schema => + * indexes => array + * uniqueConstraints => array + * + * @var array + */ + public $table; + + /** + * READ-ONLY: The registered lifecycle callbacks for entities of this class. + * + * @var array + */ + public $lifecycleCallbacks = array(); + + /** + * READ-ONLY: The association mappings of this class. + * + * The mapping definition array supports the following keys: + * + * - fieldName (string) + * The name of the field in the entity the association is mapped to. + * + * - targetEntity (string) + * The class name of the target entity. If it is fully-qualified it is used as is. + * If it is a simple, unqualified class name the namespace is assumed to be the same + * as the namespace of the source entity. + * + * - mappedBy (string, required for bidirectional associations) + * The name of the field that completes the bidirectional association on the owning side. + * This key must be specified on the inverse side of a bidirectional association. + * + * - inversedBy (string, required for bidirectional associations) + * The name of the field that completes the bidirectional association on the inverse side. + * This key must be specified on the owning side of a bidirectional association. + * + * - cascade (array, optional) + * The names of persistence operations to cascade on the association. The set of possible + * values are: "persist", "remove", "detach", "merge", "refresh", "all" (implies all others). + * + * - orderBy (array, one-to-many/many-to-many only) + * A map of field names (of the target entity) to sorting directions (ASC/DESC). + * Example: array('priority' => 'desc') + * + * - fetch (integer, optional) + * The fetching strategy to use for the association, usually defaults to FETCH_LAZY. + * Possible values are: ClassMetadata::FETCH_EAGER, ClassMetadata::FETCH_LAZY. + * + * - joinTable (array, optional, many-to-many only) + * Specification of the join table and its join columns (foreign keys). + * Only valid for many-to-many mappings. Note that one-to-many associations can be mapped + * through a join table by simply mapping the association as many-to-many with a unique + * constraint on the join table. + * + * - indexBy (string, optional, to-many only) + * Specification of a field on target-entity that is used to index the collection by. + * This field HAS to be either the primary key or a unique column. Otherwise the collection + * does not contain all the entities that are actually related. + * + * A join table definition has the following structure: + *
    +     * array(
    +     *     'name' => ,
    +     *      'joinColumns' => array(),
    +     *      'inverseJoinColumns' => array()
    +     * )
    +     * 
    + * + * + * @var array + */ + public $associationMappings = array(); + + /** + * READ-ONLY: Flag indicating whether the identifier/primary key of the class is composite. + * + * @var boolean + */ + public $isIdentifierComposite = false; + + /** + * READ-ONLY: Flag indicating wheather the identifier/primary key contains at least one foreign key association. + * + * This flag is necessary because some code blocks require special treatment of this cases. + * + * @var boolean + */ + public $containsForeignIdentifier = false; + + /** + * READ-ONLY: The ID generator used for generating IDs for this class. + * + * @var AbstractIdGenerator + * @todo Remove! + */ + public $idGenerator; + + /** + * READ-ONLY: The definition of the sequence generator of this class. Only used for the + * SEQUENCE generation strategy. + * + * The definition has the following structure: + * + * array( + * 'sequenceName' => 'name', + * 'allocationSize' => 20, + * 'initialValue' => 1 + * ) + * + * + * @var array + * @todo Merge with tableGeneratorDefinition into generic generatorDefinition + */ + public $sequenceGeneratorDefinition; + + /** + * READ-ONLY: The definition of the table generator of this class. Only used for the + * TABLE generation strategy. + * + * @var array + * @todo Merge with tableGeneratorDefinition into generic generatorDefinition + */ + public $tableGeneratorDefinition; + + /** + * READ-ONLY: The policy used for change-tracking on entities of this class. + * + * @var integer + */ + public $changeTrackingPolicy = self::CHANGETRACKING_DEFERRED_IMPLICIT; + + /** + * READ-ONLY: A flag for whether or not instances of this class are to be versioned + * with optimistic locking. + * + * @var boolean $isVersioned + */ + public $isVersioned; + + /** + * READ-ONLY: The name of the field which is used for versioning in optimistic locking (if any). + * + * @var mixed $versionField + */ + public $versionField; + + /** + * The ReflectionClass instance of the mapped class. + * + * @var ReflectionClass + */ + public $reflClass; + + /** + * Is this entity marked as "read-only"? + * + * That means it is never considered for change-tracking in the UnitOfWork. It is a very helpful performance + * optimization for entities that are immutable, either in your domain or through the relation database + * (coming from a view, or a history table for example). + * + * @var bool + */ + public $isReadOnly = false; + + /** + * The ReflectionProperty instances of the mapped class. + * + * @var array + */ + public $reflFields = array(); + + /** + * The prototype from which new instances of the mapped class are created. + * + * @var object + */ + private $_prototype; + + /** + * Initializes a new ClassMetadata instance that will hold the object-relational mapping + * metadata of the class with the given name. + * + * @param string $entityName The name of the entity class the new instance is used for. + */ + public function __construct($entityName) + { + $this->name = $entityName; + $this->rootEntityName = $entityName; + } + + /** + * Gets the ReflectionPropertys of the mapped class. + * + * @return array An array of ReflectionProperty instances. + */ + public function getReflectionProperties() + { + return $this->reflFields; + } + + /** + * Gets a ReflectionProperty for a specific field of the mapped class. + * + * @param string $name + * @return ReflectionProperty + */ + public function getReflectionProperty($name) + { + return $this->reflFields[$name]; + } + + /** + * Gets the ReflectionProperty for the single identifier field. + * + * @return ReflectionProperty + * @throws BadMethodCallException If the class has a composite identifier. + */ + public function getSingleIdReflectionProperty() + { + if ($this->isIdentifierComposite) { + throw new \BadMethodCallException("Class " . $this->name . " has a composite identifier."); + } + return $this->reflFields[$this->identifier[0]]; + } + + /** + * Extracts the identifier values of an entity of this class. + * + * For composite identifiers, the identifier values are returned as an array + * with the same order as the field order in {@link identifier}. + * + * @param object $entity + * @return array + */ + public function getIdentifierValues($entity) + { + if ($this->isIdentifierComposite) { + $id = array(); + + foreach ($this->identifier as $idField) { + $value = $this->reflFields[$idField]->getValue($entity); + + if ($value !== null) { + $id[$idField] = $value; + } + } + + return $id; + } + + $value = $this->reflFields[$this->identifier[0]]->getValue($entity); + + if ($value !== null) { + return array($this->identifier[0] => $value); + } + + return array(); + } + + /** + * Populates the entity identifier of an entity. + * + * @param object $entity + * @param mixed $id + * @todo Rename to assignIdentifier() + */ + public function setIdentifierValues($entity, array $id) + { + foreach ($id as $idField => $idValue) { + $this->reflFields[$idField]->setValue($entity, $idValue); + } + } + + /** + * Sets the specified field to the specified value on the given entity. + * + * @param object $entity + * @param string $field + * @param mixed $value + */ + public function setFieldValue($entity, $field, $value) + { + $this->reflFields[$field]->setValue($entity, $value); + } + + /** + * Gets the specified field's value off the given entity. + * + * @param object $entity + * @param string $field + */ + public function getFieldValue($entity, $field) + { + return $this->reflFields[$field]->getValue($entity); + } + + /** + * Creates a string representation of this instance. + * + * @return string The string representation of this instance. + * @todo Construct meaningful string representation. + */ + public function __toString() + { + return __CLASS__ . '@' . spl_object_hash($this); + } + + /** + * Determines which fields get serialized. + * + * It is only serialized what is necessary for best unserialization performance. + * That means any metadata properties that are not set or empty or simply have + * their default value are NOT serialized. + * + * Parts that are also NOT serialized because they can not be properly unserialized: + * - reflClass (ReflectionClass) + * - reflFields (ReflectionProperty array) + * + * @return array The names of all the fields that should be serialized. + */ + public function __sleep() + { + // This metadata is always serialized/cached. + $serialized = array( + 'associationMappings', + 'columnNames', //TODO: Not really needed. Can use fieldMappings[$fieldName]['columnName'] + 'fieldMappings', + 'fieldNames', + 'identifier', + 'isIdentifierComposite', // TODO: REMOVE + 'name', + 'namespace', // TODO: REMOVE + 'table', + 'rootEntityName', + 'idGenerator', //TODO: Does not really need to be serialized. Could be moved to runtime. + ); + + // The rest of the metadata is only serialized if necessary. + if ($this->changeTrackingPolicy != self::CHANGETRACKING_DEFERRED_IMPLICIT) { + $serialized[] = 'changeTrackingPolicy'; + } + + if ($this->customRepositoryClassName) { + $serialized[] = 'customRepositoryClassName'; + } + + if ($this->inheritanceType != self::INHERITANCE_TYPE_NONE) { + $serialized[] = 'inheritanceType'; + $serialized[] = 'discriminatorColumn'; + $serialized[] = 'discriminatorValue'; + $serialized[] = 'discriminatorMap'; + $serialized[] = 'parentClasses'; + $serialized[] = 'subClasses'; + } + + if ($this->generatorType != self::GENERATOR_TYPE_NONE) { + $serialized[] = 'generatorType'; + if ($this->generatorType == self::GENERATOR_TYPE_SEQUENCE) { + $serialized[] = 'sequenceGeneratorDefinition'; + } + } + + if ($this->isMappedSuperclass) { + $serialized[] = 'isMappedSuperclass'; + } + + if ($this->containsForeignIdentifier) { + $serialized[] = 'containsForeignIdentifier'; + } + + if ($this->isVersioned) { + $serialized[] = 'isVersioned'; + $serialized[] = 'versionField'; + } + + if ($this->lifecycleCallbacks) { + $serialized[] = 'lifecycleCallbacks'; + } + + if ($this->namedQueries) { + $serialized[] = 'namedQueries'; + } + + if ($this->isReadOnly) { + $serialized[] = 'isReadOnly'; + } + + return $serialized; + } + + /** + * Creates a new instance of the mapped class, without invoking the constructor. + * + * @return object + */ + public function newInstance() + { + if ($this->_prototype === null) { + $this->_prototype = unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name)); + } + + return clone $this->_prototype; + } + /** + * Restores some state that can not be serialized/unserialized. + * + * @param ReflectionService $reflService + * @return void + */ + public function wakeupReflection($reflService) + { + // Restore ReflectionClass and properties + $this->reflClass = $reflService->getClass($this->name); + + foreach ($this->fieldMappings as $field => $mapping) { + $this->reflFields[$field] = isset($mapping['declared']) + ? $reflService->getAccessibleProperty($mapping['declared'], $field) + : $reflService->getAccessibleProperty($this->name, $field); + } + + foreach ($this->associationMappings as $field => $mapping) { + $this->reflFields[$field] = isset($mapping['declared']) + ? $reflService->getAccessibleProperty($mapping['declared'], $field) + : $reflService->getAccessibleProperty($this->name, $field); + } + } + + /** + * Initializes a new ClassMetadata instance that will hold the object-relational mapping + * metadata of the class with the given name. + * + * @param string $entityName The name of the entity class the new instance is used for. + */ + public function initializeReflection($reflService) + { + $this->reflClass = $reflService->getClass($this->name); + $this->namespace = $reflService->getClassNamespace($this->name); + $this->table['name'] = $reflService->getClassShortName($this->name); + + if ($this->reflClass) { + $this->name = $this->rootEntityName = $this->reflClass->getName(); + } + } + + /** + * Validate Identifier + * + * @return void + */ + public function validateIdentifier() + { + // Verify & complete identifier mapping + if ( ! $this->identifier && ! $this->isMappedSuperclass) { + throw MappingException::identifierRequired($this->name); + } + + if ($this->usesIdGenerator() && $this->isIdentifierComposite) { + throw MappingException::compositeKeyAssignedIdGeneratorRequired($this->name); + } + } + + /** + * Validate association targets actually exist. + * + * @return void + */ + public function validateAssocations() + { + foreach ($this->associationMappings as $field => $mapping) { + if ( ! \Doctrine\Common\ClassLoader::classExists($mapping['targetEntity']) ) { + throw MappingException::invalidTargetEntityClass($mapping['targetEntity'], $this->name, $mapping['fieldName']); + } + } + } + + /** + * Validate lifecycle callbacks + * + * @param ReflectionService $reflService + * @return void + */ + public function validateLifecycleCallbacks($reflService) + { + foreach ($this->lifecycleCallbacks as $event => $callbacks) { + foreach ($callbacks as $callbackFuncName) { + if ( ! $reflService->hasPublicMethod($this->name, $callbackFuncName)) { + throw MappingException::lifecycleCallbackMethodNotFound($this->name, $callbackFuncName); + } + } + } + } + + /** + * Gets the ReflectionClass instance of the mapped class. + * + * @return ReflectionClass + */ + public function getReflectionClass() + { + return $this->reflClass; + } + + /** + * Sets the change tracking policy used by this class. + * + * @param integer $policy + */ + public function setChangeTrackingPolicy($policy) + { + $this->changeTrackingPolicy = $policy; + } + + /** + * Whether the change tracking policy of this class is "deferred explicit". + * + * @return boolean + */ + public function isChangeTrackingDeferredExplicit() + { + return $this->changeTrackingPolicy == self::CHANGETRACKING_DEFERRED_EXPLICIT; + } + + /** + * Whether the change tracking policy of this class is "deferred implicit". + * + * @return boolean + */ + public function isChangeTrackingDeferredImplicit() + { + return $this->changeTrackingPolicy == self::CHANGETRACKING_DEFERRED_IMPLICIT; + } + + /** + * Whether the change tracking policy of this class is "notify". + * + * @return boolean + */ + public function isChangeTrackingNotify() + { + return $this->changeTrackingPolicy == self::CHANGETRACKING_NOTIFY; + } + + /** + * Checks whether a field is part of the identifier/primary key field(s). + * + * @param string $fieldName The field name + * @return boolean TRUE if the field is part of the table identifier/primary key field(s), + * FALSE otherwise. + */ + public function isIdentifier($fieldName) + { + if ( ! $this->isIdentifierComposite) { + return $fieldName === $this->identifier[0]; + } + return in_array($fieldName, $this->identifier); + } + + /** + * Check if the field is unique. + * + * @param string $fieldName The field name + * @return boolean TRUE if the field is unique, FALSE otherwise. + */ + public function isUniqueField($fieldName) + { + $mapping = $this->getFieldMapping($fieldName); + if ($mapping !== false) { + return isset($mapping['unique']) && $mapping['unique'] == true; + } + return false; + } + + /** + * Check if the field is not null. + * + * @param string $fieldName The field name + * @return boolean TRUE if the field is not null, FALSE otherwise. + */ + public function isNullable($fieldName) + { + $mapping = $this->getFieldMapping($fieldName); + if ($mapping !== false) { + return isset($mapping['nullable']) && $mapping['nullable'] == true; + } + return false; + } + + /** + * Gets a column name for a field name. + * If the column name for the field cannot be found, the given field name + * is returned. + * + * @param string $fieldName The field name. + * @return string The column name. + */ + public function getColumnName($fieldName) + { + return isset($this->columnNames[$fieldName]) ? + $this->columnNames[$fieldName] : $fieldName; + } + + /** + * Gets the mapping of a (regular) field that holds some data but not a + * reference to another object. + * + * @param string $fieldName The field name. + * @return array The field mapping. + */ + public function getFieldMapping($fieldName) + { + if ( ! isset($this->fieldMappings[$fieldName])) { + throw MappingException::mappingNotFound($this->name, $fieldName); + } + return $this->fieldMappings[$fieldName]; + } + + /** + * Gets the mapping of an association. + * + * @see ClassMetadataInfo::$associationMappings + * @param string $fieldName The field name that represents the association in + * the object model. + * @return array The mapping. + */ + public function getAssociationMapping($fieldName) + { + if ( ! isset($this->associationMappings[$fieldName])) { + throw MappingException::mappingNotFound($this->name, $fieldName); + } + return $this->associationMappings[$fieldName]; + } + + /** + * Gets all association mappings of the class. + * + * @return array + */ + public function getAssociationMappings() + { + return $this->associationMappings; + } + + /** + * Gets the field name for a column name. + * If no field name can be found the column name is returned. + * + * @param string $columnName column name + * @return string column alias + */ + public function getFieldName($columnName) + { + return isset($this->fieldNames[$columnName]) ? + $this->fieldNames[$columnName] : $columnName; + } + + /** + * Gets the named query. + * + * @see ClassMetadataInfo::$namedQueries + * @throws MappingException + * @param string $queryName The query name + * @return string + */ + public function getNamedQuery($queryName) + { + if ( ! isset($this->namedQueries[$queryName])) { + throw MappingException::queryNotFound($this->name, $queryName); + } + return $this->namedQueries[$queryName]['dql']; + } + + /** + * Gets all named queries of the class. + * + * @return array + */ + public function getNamedQueries() + { + return $this->namedQueries; + } + + /** + * Validates & completes the given field mapping. + * + * @param array $mapping The field mapping to validated & complete. + * @return array The validated and completed field mapping. + */ + protected function _validateAndCompleteFieldMapping(array &$mapping) + { + // Check mandatory fields + if ( ! isset($mapping['fieldName']) || strlen($mapping['fieldName']) == 0) { + throw MappingException::missingFieldName($this->name); + } + if ( ! isset($mapping['type'])) { + // Default to string + $mapping['type'] = 'string'; + } + + // Complete fieldName and columnName mapping + if ( ! isset($mapping['columnName'])) { + $mapping['columnName'] = $mapping['fieldName']; + } else { + if ($mapping['columnName'][0] == '`') { + $mapping['columnName'] = trim($mapping['columnName'], '`'); + $mapping['quoted'] = true; + } + } + + $this->columnNames[$mapping['fieldName']] = $mapping['columnName']; + if (isset($this->fieldNames[$mapping['columnName']]) || ($this->discriminatorColumn != null && $this->discriminatorColumn['name'] == $mapping['columnName'])) { + throw MappingException::duplicateColumnName($this->name, $mapping['columnName']); + } + + $this->fieldNames[$mapping['columnName']] = $mapping['fieldName']; + + // Complete id mapping + if (isset($mapping['id']) && $mapping['id'] === true) { + if ($this->versionField == $mapping['fieldName']) { + throw MappingException::cannotVersionIdField($this->name, $mapping['fieldName']); + } + + if ( ! in_array($mapping['fieldName'], $this->identifier)) { + $this->identifier[] = $mapping['fieldName']; + } + // Check for composite key + if ( ! $this->isIdentifierComposite && count($this->identifier) > 1) { + $this->isIdentifierComposite = true; + } + } + + if (Type::hasType($mapping['type']) && Type::getType($mapping['type'])->canRequireSQLConversion()) { + if (isset($mapping['id']) && $mapping['id'] === true) { + throw MappingException::sqlConversionNotAllowedForIdentifiers($this->name, $mapping['fieldName'], $mapping['type']); + } + + $mapping['requireSQLConversion'] = true; + } + } + + /** + * Validates & completes the basic mapping information that is common to all + * association mappings (one-to-one, many-ot-one, one-to-many, many-to-many). + * + * @param array $mapping The mapping. + * @return array The updated mapping. + * @throws MappingException If something is wrong with the mapping. + */ + protected function _validateAndCompleteAssociationMapping(array $mapping) + { + if ( ! isset($mapping['mappedBy'])) { + $mapping['mappedBy'] = null; + } + if ( ! isset($mapping['inversedBy'])) { + $mapping['inversedBy'] = null; + } + $mapping['isOwningSide'] = true; // assume owning side until we hit mappedBy + + // unset optional indexBy attribute if its empty + if (!isset($mapping['indexBy']) || !$mapping['indexBy']) { + unset($mapping['indexBy']); + } + + // If targetEntity is unqualified, assume it is in the same namespace as + // the sourceEntity. + $mapping['sourceEntity'] = $this->name; + + if (isset($mapping['targetEntity'])) { + if (strlen($this->namespace) > 0 && strpos($mapping['targetEntity'], '\\') === false) { + $mapping['targetEntity'] = $this->namespace . '\\' . $mapping['targetEntity']; + } + + $mapping['targetEntity'] = ltrim($mapping['targetEntity'], '\\'); + } + + if ( ($mapping['type'] & self::MANY_TO_ONE) > 0 && + isset($mapping['orphanRemoval']) && + $mapping['orphanRemoval'] == true) { + + throw MappingException::illegalOrphanRemoval($this->name, $mapping['fieldName']); + } + + // Complete id mapping + if (isset($mapping['id']) && $mapping['id'] === true) { + if (isset($mapping['orphanRemoval']) && $mapping['orphanRemoval'] == true) { + throw MappingException::illegalOrphanRemovalOnIdentifierAssociation($this->name, $mapping['fieldName']); + } + + if ( ! in_array($mapping['fieldName'], $this->identifier)) { + if (count($mapping['joinColumns']) >= 2) { + throw MappingException::cannotMapCompositePrimaryKeyEntitiesAsForeignId( + $mapping['targetEntity'], $this->name, $mapping['fieldName'] + ); + } + + $this->identifier[] = $mapping['fieldName']; + $this->containsForeignIdentifier = true; + } + // Check for composite key + if ( ! $this->isIdentifierComposite && count($this->identifier) > 1) { + $this->isIdentifierComposite = true; + } + } + + // Mandatory attributes for both sides + // Mandatory: fieldName, targetEntity + if ( ! isset($mapping['fieldName']) || strlen($mapping['fieldName']) == 0) { + throw MappingException::missingFieldName($this->name); + } + if ( ! isset($mapping['targetEntity'])) { + throw MappingException::missingTargetEntity($mapping['fieldName']); + } + + // Mandatory and optional attributes for either side + if ( ! $mapping['mappedBy']) { + if (isset($mapping['joinTable']) && $mapping['joinTable']) { + if (isset($mapping['joinTable']['name']) && $mapping['joinTable']['name'][0] == '`') { + $mapping['joinTable']['name'] = trim($mapping['joinTable']['name'], '`'); + $mapping['joinTable']['quoted'] = true; + } + } + } else { + $mapping['isOwningSide'] = false; + } + + if (isset($mapping['id']) && $mapping['id'] === true && $mapping['type'] & self::TO_MANY) { + throw MappingException::illegalToManyIdentifierAssoaction($this->name, $mapping['fieldName']); + } + + // Fetch mode. Default fetch mode to LAZY, if not set. + if ( ! isset($mapping['fetch'])) { + $mapping['fetch'] = self::FETCH_LAZY; + } + + // Cascades + $cascades = isset($mapping['cascade']) ? array_map('strtolower', $mapping['cascade']) : array(); + + if (in_array('all', $cascades)) { + $cascades = array('remove', 'persist', 'refresh', 'merge', 'detach'); + } + + $mapping['cascade'] = $cascades; + $mapping['isCascadeRemove'] = in_array('remove', $cascades); + $mapping['isCascadePersist'] = in_array('persist', $cascades); + $mapping['isCascadeRefresh'] = in_array('refresh', $cascades); + $mapping['isCascadeMerge'] = in_array('merge', $cascades); + $mapping['isCascadeDetach'] = in_array('detach', $cascades); + + return $mapping; + } + + /** + * Validates & completes a one-to-one association mapping. + * + * @param array $mapping The mapping to validate & complete. + * @return array The validated & completed mapping. + * @override + */ + protected function _validateAndCompleteOneToOneMapping(array $mapping) + { + $mapping = $this->_validateAndCompleteAssociationMapping($mapping); + + if (isset($mapping['joinColumns']) && $mapping['joinColumns']) { + $mapping['isOwningSide'] = true; + } + + if ($mapping['isOwningSide']) { + if ( ! isset($mapping['joinColumns']) || ! $mapping['joinColumns']) { + // Apply default join column + $mapping['joinColumns'] = array(array( + 'name' => $mapping['fieldName'] . '_id', + 'referencedColumnName' => 'id' + )); + } + + $uniqueContraintColumns = array(); + foreach ($mapping['joinColumns'] as $key => &$joinColumn) { + if ($mapping['type'] === self::ONE_TO_ONE && ! $this->isInheritanceTypeSingleTable()) { + if (count($mapping['joinColumns']) == 1) { + if (! isset($mapping['id']) || ! $mapping['id']) { + $joinColumn['unique'] = true; + } + } else { + $uniqueContraintColumns[] = $joinColumn['name']; + } + } + if (empty($joinColumn['name'])) { + $joinColumn['name'] = $mapping['fieldName'] . '_id'; + } + if (empty($joinColumn['referencedColumnName'])) { + $joinColumn['referencedColumnName'] = 'id'; + } + $mapping['sourceToTargetKeyColumns'][$joinColumn['name']] = $joinColumn['referencedColumnName']; + $mapping['joinColumnFieldNames'][$joinColumn['name']] = isset($joinColumn['fieldName']) + ? $joinColumn['fieldName'] : $joinColumn['name']; + } + + if ($uniqueContraintColumns) { + if (!$this->table) { + throw new \RuntimeException("ClassMetadataInfo::setTable() has to be called before defining a one to one relationship."); + } + $this->table['uniqueConstraints'][$mapping['fieldName']."_uniq"] = array( + 'columns' => $uniqueContraintColumns + ); + } + + $mapping['targetToSourceKeyColumns'] = array_flip($mapping['sourceToTargetKeyColumns']); + } + + $mapping['orphanRemoval'] = isset($mapping['orphanRemoval']) ? (bool) $mapping['orphanRemoval'] : false; + $mapping['isCascadeRemove'] = $mapping['orphanRemoval'] ? true : $mapping['isCascadeRemove']; + + if (isset($mapping['id']) && $mapping['id'] === true && !$mapping['isOwningSide']) { + throw MappingException::illegalInverseIdentifierAssocation($this->name, $mapping['fieldName']); + } + + return $mapping; + } + + /** + * Validates and completes the mapping. + * + * @param array $mapping The mapping to validate and complete. + * @return array The validated and completed mapping. + * @override + */ + protected function _validateAndCompleteOneToManyMapping(array $mapping) + { + $mapping = $this->_validateAndCompleteAssociationMapping($mapping); + + // OneToMany-side MUST be inverse (must have mappedBy) + if ( ! isset($mapping['mappedBy'])) { + throw MappingException::oneToManyRequiresMappedBy($mapping['fieldName']); + } + + $mapping['orphanRemoval'] = isset($mapping['orphanRemoval']) ? (bool) $mapping['orphanRemoval'] : false; + $mapping['isCascadeRemove'] = $mapping['orphanRemoval'] ? true : $mapping['isCascadeRemove']; + + if (isset($mapping['orderBy'])) { + if ( ! is_array($mapping['orderBy'])) { + throw new \InvalidArgumentException("'orderBy' is expected to be an array, not ".gettype($mapping['orderBy'])); + } + } + + return $mapping; + } + + protected function _validateAndCompleteManyToManyMapping(array $mapping) + { + $mapping = $this->_validateAndCompleteAssociationMapping($mapping); + if ($mapping['isOwningSide']) { + if (strpos($mapping['sourceEntity'], '\\') !== false) { + $sourceShortName = strtolower(substr($mapping['sourceEntity'], strrpos($mapping['sourceEntity'], '\\') + 1)); + } else { + $sourceShortName = strtolower($mapping['sourceEntity']); + } + if (strpos($mapping['targetEntity'], '\\') !== false) { + $targetShortName = strtolower(substr($mapping['targetEntity'], strrpos($mapping['targetEntity'], '\\') + 1)); + } else { + $targetShortName = strtolower($mapping['targetEntity']); + } + + // owning side MUST have a join table + if ( ! isset($mapping['joinTable']['name'])) { + $mapping['joinTable']['name'] = $sourceShortName .'_' . $targetShortName; + } + if ( ! isset($mapping['joinTable']['joinColumns'])) { + $mapping['joinTable']['joinColumns'] = array(array( + 'name' => $sourceShortName . '_id', + 'referencedColumnName' => 'id', + 'onDelete' => 'CASCADE')); + } + if ( ! isset($mapping['joinTable']['inverseJoinColumns'])) { + $mapping['joinTable']['inverseJoinColumns'] = array(array( + 'name' => $targetShortName . '_id', + 'referencedColumnName' => 'id', + 'onDelete' => 'CASCADE')); + } + + foreach ($mapping['joinTable']['joinColumns'] as &$joinColumn) { + if (empty($joinColumn['name'])) { + $joinColumn['name'] = $sourceShortName . '_id'; + } + if (empty($joinColumn['referencedColumnName'])) { + $joinColumn['referencedColumnName'] = 'id'; + } + if (isset($joinColumn['onDelete']) && strtolower($joinColumn['onDelete']) == 'cascade') { + $mapping['isOnDeleteCascade'] = true; + } + $mapping['relationToSourceKeyColumns'][$joinColumn['name']] = $joinColumn['referencedColumnName']; + $mapping['joinTableColumns'][] = $joinColumn['name']; + } + + foreach ($mapping['joinTable']['inverseJoinColumns'] as &$inverseJoinColumn) { + if (empty($inverseJoinColumn['name'])) { + $inverseJoinColumn['name'] = $targetShortName . '_id'; + } + if (empty($inverseJoinColumn['referencedColumnName'])) { + $inverseJoinColumn['referencedColumnName'] = 'id'; + } + if (isset($inverseJoinColumn['onDelete']) && strtolower($inverseJoinColumn['onDelete']) == 'cascade') { + $mapping['isOnDeleteCascade'] = true; + } + $mapping['relationToTargetKeyColumns'][$inverseJoinColumn['name']] = $inverseJoinColumn['referencedColumnName']; + $mapping['joinTableColumns'][] = $inverseJoinColumn['name']; + } + } + + $mapping['orphanRemoval'] = isset($mapping['orphanRemoval']) ? (bool) $mapping['orphanRemoval'] : false; + + if (isset($mapping['orderBy'])) { + if ( ! is_array($mapping['orderBy'])) { + throw new \InvalidArgumentException("'orderBy' is expected to be an array, not ".gettype($mapping['orderBy'])); + } + } + + return $mapping; + } + + /** + * Gets the identifier (primary key) field names of the class. + * + * @return mixed + */ + public function getIdentifierFieldNames() + { + return $this->identifier; + } + + /** + * Gets the name of the single id field. Note that this only works on + * entity classes that have a single-field pk. + * + * @return string + * @throws MappingException If the class has a composite primary key. + */ + public function getSingleIdentifierFieldName() + { + if ($this->isIdentifierComposite) { + throw MappingException::singleIdNotAllowedOnCompositePrimaryKey($this->name); + } + return $this->identifier[0]; + } + + /** + * Gets the column name of the single id column. Note that this only works on + * entity classes that have a single-field pk. + * + * @return string + * @throws MappingException If the class has a composite primary key. + */ + public function getSingleIdentifierColumnName() + { + return $this->getColumnName($this->getSingleIdentifierFieldName()); + } + + /** + * INTERNAL: + * Sets the mapped identifier/primary key fields of this class. + * Mainly used by the ClassMetadataFactory to assign inherited identifiers. + * + * @param array $identifier + */ + public function setIdentifier(array $identifier) + { + $this->identifier = $identifier; + $this->isIdentifierComposite = (count($this->identifier) > 1); + } + + /** + * Gets the mapped identifier field of this class. + * + * @return string $identifier + */ + public function getIdentifier() + { + return $this->identifier; + } + + /** + * Checks whether the class has a (mapped) field with a certain name. + * + * @return boolean + */ + public function hasField($fieldName) + { + return isset($this->fieldMappings[$fieldName]); + } + + /** + * Gets an array containing all the column names. + * + * @return array + */ + public function getColumnNames(array $fieldNames = null) + { + if ($fieldNames === null) { + return array_keys($this->fieldNames); + } else { + $columnNames = array(); + foreach ($fieldNames as $fieldName) { + $columnNames[] = $this->getColumnName($fieldName); + } + return $columnNames; + } + } + + /** + * Returns an array with all the identifier column names. + * + * @return array + */ + public function getIdentifierColumnNames() + { + $columnNames = array(); + + foreach ($this->identifier as $idProperty) { + if (isset($this->fieldMappings[$idProperty])) { + $columnNames[] = $this->fieldMappings[$idProperty]['columnName']; + + continue; + } + + // Association defined as Id field + $joinColumns = $this->associationMappings[$idProperty]['joinColumns']; + $assocColumnNames = array_map(function ($joinColumn) { return $joinColumn['name']; }, $joinColumns); + + $columnNames = array_merge($columnNames, $assocColumnNames); + } + + return $columnNames; + } + + /** + * Sets the type of Id generator to use for the mapped class. + */ + public function setIdGeneratorType($generatorType) + { + $this->generatorType = $generatorType; + } + + /** + * Checks whether the mapped class uses an Id generator. + * + * @return boolean TRUE if the mapped class uses an Id generator, FALSE otherwise. + */ + public function usesIdGenerator() + { + return $this->generatorType != self::GENERATOR_TYPE_NONE; + } + + /** + * @return boolean + */ + public function isInheritanceTypeNone() + { + return $this->inheritanceType == self::INHERITANCE_TYPE_NONE; + } + + /** + * Checks whether the mapped class uses the JOINED inheritance mapping strategy. + * + * @return boolean TRUE if the class participates in a JOINED inheritance mapping, + * FALSE otherwise. + */ + public function isInheritanceTypeJoined() + { + return $this->inheritanceType == self::INHERITANCE_TYPE_JOINED; + } + + /** + * Checks whether the mapped class uses the SINGLE_TABLE inheritance mapping strategy. + * + * @return boolean TRUE if the class participates in a SINGLE_TABLE inheritance mapping, + * FALSE otherwise. + */ + public function isInheritanceTypeSingleTable() + { + return $this->inheritanceType == self::INHERITANCE_TYPE_SINGLE_TABLE; + } + + /** + * Checks whether the mapped class uses the TABLE_PER_CLASS inheritance mapping strategy. + * + * @return boolean TRUE if the class participates in a TABLE_PER_CLASS inheritance mapping, + * FALSE otherwise. + */ + public function isInheritanceTypeTablePerClass() + { + return $this->inheritanceType == self::INHERITANCE_TYPE_TABLE_PER_CLASS; + } + + /** + * Checks whether the class uses an identity column for the Id generation. + * + * @return boolean TRUE if the class uses the IDENTITY generator, FALSE otherwise. + */ + public function isIdGeneratorIdentity() + { + return $this->generatorType == self::GENERATOR_TYPE_IDENTITY; + } + + /** + * Checks whether the class uses a sequence for id generation. + * + * @return boolean TRUE if the class uses the SEQUENCE generator, FALSE otherwise. + */ + public function isIdGeneratorSequence() + { + return $this->generatorType == self::GENERATOR_TYPE_SEQUENCE; + } + + /** + * Checks whether the class uses a table for id generation. + * + * @return boolean TRUE if the class uses the TABLE generator, FALSE otherwise. + */ + public function isIdGeneratorTable() + { + $this->generatorType == self::GENERATOR_TYPE_TABLE; + } + + /** + * Checks whether the class has a natural identifier/pk (which means it does + * not use any Id generator. + * + * @return boolean + */ + public function isIdentifierNatural() + { + return $this->generatorType == self::GENERATOR_TYPE_NONE; + } + + /** + * Gets the type of a field. + * + * @param string $fieldName + * @return \Doctrine\DBAL\Types\Type + */ + public function getTypeOfField($fieldName) + { + return isset($this->fieldMappings[$fieldName]) ? + $this->fieldMappings[$fieldName]['type'] : null; + } + + /** + * Gets the type of a column. + * + * @return \Doctrine\DBAL\Types\Type + */ + public function getTypeOfColumn($columnName) + { + return $this->getTypeOfField($this->getFieldName($columnName)); + } + + /** + * Gets the name of the primary table. + * + * @return string + */ + public function getTableName() + { + return $this->table['name']; + } + + /** + * Gets the table name to use for temporary identifier tables of this class. + * + * @return string + */ + public function getTemporaryIdTableName() + { + // replace dots with underscores because PostgreSQL creates temporary tables in a special schema + return str_replace('.', '_', $this->getTableName() . '_id_tmp'); + } + + /** + * Sets the mapped subclasses of this class. + * + * @param array $subclasses The names of all mapped subclasses. + */ + public function setSubclasses(array $subclasses) + { + foreach ($subclasses as $subclass) { + if (strpos($subclass, '\\') === false && strlen($this->namespace)) { + $this->subClasses[] = $this->namespace . '\\' . $subclass; + } else { + $this->subClasses[] = $subclass; + } + } + } + + /** + * Sets the parent class names. + * Assumes that the class names in the passed array are in the order: + * directParent -> directParentParent -> directParentParentParent ... -> root. + */ + public function setParentClasses(array $classNames) + { + $this->parentClasses = $classNames; + if (count($classNames) > 0) { + $this->rootEntityName = array_pop($classNames); + } + } + + /** + * Sets the inheritance type used by the class and it's subclasses. + * + * @param integer $type + */ + public function setInheritanceType($type) + { + if ( ! $this->_isInheritanceType($type)) { + throw MappingException::invalidInheritanceType($this->name, $type); + } + $this->inheritanceType = $type; + } + + /** + * Checks whether a mapped field is inherited from an entity superclass. + * + * @return boolean TRUE if the field is inherited, FALSE otherwise. + */ + public function isInheritedField($fieldName) + { + return isset($this->fieldMappings[$fieldName]['inherited']); + } + + /** + * Checks whether a mapped association field is inherited from a superclass. + * + * @param string $fieldName + * @return boolean TRUE if the field is inherited, FALSE otherwise. + */ + public function isInheritedAssociation($fieldName) + { + return isset($this->associationMappings[$fieldName]['inherited']); + } + + /** + * Sets the name of the primary table the class is mapped to. + * + * @param string $tableName The table name. + * @deprecated Use {@link setPrimaryTable}. + */ + public function setTableName($tableName) + { + $this->table['name'] = $tableName; + } + + /** + * Sets the primary table definition. The provided array supports the + * following structure: + * + * name => (optional, defaults to class name) + * indexes => array of indexes (optional) + * uniqueConstraints => array of constraints (optional) + * + * If a key is omitted, the current value is kept. + * + * @param array $table The table description. + */ + public function setPrimaryTable(array $table) + { + if (isset($table['name'])) { + if ($table['name'][0] == '`') { + $this->table['name'] = str_replace("`", "", $table['name']); + $this->table['quoted'] = true; + } else { + $this->table['name'] = $table['name']; + } + } + + if (isset($table['indexes'])) { + $this->table['indexes'] = $table['indexes']; + } + + if (isset($table['uniqueConstraints'])) { + $this->table['uniqueConstraints'] = $table['uniqueConstraints']; + } + } + + /** + * Checks whether the given type identifies an inheritance type. + * + * @param integer $type + * @return boolean TRUE if the given type identifies an inheritance type, FALSe otherwise. + */ + private function _isInheritanceType($type) + { + return $type == self::INHERITANCE_TYPE_NONE || + $type == self::INHERITANCE_TYPE_SINGLE_TABLE || + $type == self::INHERITANCE_TYPE_JOINED || + $type == self::INHERITANCE_TYPE_TABLE_PER_CLASS; + } + + /** + * Adds a mapped field to the class. + * + * @param array $mapping The field mapping. + */ + public function mapField(array $mapping) + { + $this->_validateAndCompleteFieldMapping($mapping); + if (isset($this->fieldMappings[$mapping['fieldName']]) || isset($this->associationMappings[$mapping['fieldName']])) { + throw MappingException::duplicateFieldMapping($this->name, $mapping['fieldName']); + } + $this->fieldMappings[$mapping['fieldName']] = $mapping; + } + + /** + * INTERNAL: + * Adds an association mapping without completing/validating it. + * This is mainly used to add inherited association mappings to derived classes. + * + * @param array $mapping + */ + public function addInheritedAssociationMapping(array $mapping/*, $owningClassName = null*/) + { + if (isset($this->associationMappings[$mapping['fieldName']])) { + throw MappingException::duplicateAssociationMapping($this->name, $mapping['fieldName']); + } + $this->associationMappings[$mapping['fieldName']] = $mapping; + } + + /** + * INTERNAL: + * Adds a field mapping without completing/validating it. + * This is mainly used to add inherited field mappings to derived classes. + * + * @param array $mapping + */ + public function addInheritedFieldMapping(array $fieldMapping) + { + $this->fieldMappings[$fieldMapping['fieldName']] = $fieldMapping; + $this->columnNames[$fieldMapping['fieldName']] = $fieldMapping['columnName']; + $this->fieldNames[$fieldMapping['columnName']] = $fieldMapping['fieldName']; + } + + /** + * INTERNAL: + * Adds a named query to this class. + * + * @throws MappingException + * @param array $queryMapping + */ + public function addNamedQuery(array $queryMapping) + { + if (isset($this->namedQueries[$queryMapping['name']])) { + throw MappingException::duplicateQueryMapping($this->name, $queryMapping['name']); + } + + $name = $queryMapping['name']; + $query = $queryMapping['query']; + $dql = str_replace('__CLASS__', $this->name, $query); + $this->namedQueries[$name] = array( + 'name' => $name, + 'query' => $query, + 'dql' => $dql + ); + } + + /** + * Adds a one-to-one mapping. + * + * @param array $mapping The mapping. + */ + public function mapOneToOne(array $mapping) + { + $mapping['type'] = self::ONE_TO_ONE; + $mapping = $this->_validateAndCompleteOneToOneMapping($mapping); + $this->_storeAssociationMapping($mapping); + } + + /** + * Adds a one-to-many mapping. + * + * @param array $mapping The mapping. + */ + public function mapOneToMany(array $mapping) + { + $mapping['type'] = self::ONE_TO_MANY; + $mapping = $this->_validateAndCompleteOneToManyMapping($mapping); + $this->_storeAssociationMapping($mapping); + } + + /** + * Adds a many-to-one mapping. + * + * @param array $mapping The mapping. + */ + public function mapManyToOne(array $mapping) + { + $mapping['type'] = self::MANY_TO_ONE; + // A many-to-one mapping is essentially a one-one backreference + $mapping = $this->_validateAndCompleteOneToOneMapping($mapping); + $this->_storeAssociationMapping($mapping); + } + + /** + * Adds a many-to-many mapping. + * + * @param array $mapping The mapping. + */ + public function mapManyToMany(array $mapping) + { + $mapping['type'] = self::MANY_TO_MANY; + $mapping = $this->_validateAndCompleteManyToManyMapping($mapping); + $this->_storeAssociationMapping($mapping); + } + + /** + * Stores the association mapping. + * + * @param array $assocMapping + */ + protected function _storeAssociationMapping(array $assocMapping) + { + $sourceFieldName = $assocMapping['fieldName']; + + if (isset($this->fieldMappings[$sourceFieldName]) || isset($this->associationMappings[$sourceFieldName])) { + throw MappingException::duplicateFieldMapping($this->name, $sourceFieldName); + } + + $this->associationMappings[$sourceFieldName] = $assocMapping; + } + + /** + * Registers a custom repository class for the entity class. + * + * @param string $mapperClassName The class name of the custom mapper. + */ + public function setCustomRepositoryClass($repositoryClassName) + { + if ($repositoryClassName !== null && strpos($repositoryClassName, '\\') === false + && strlen($this->namespace) > 0) { + $repositoryClassName = $this->namespace . '\\' . $repositoryClassName; + } + $this->customRepositoryClassName = $repositoryClassName; + } + + /** + * Dispatches the lifecycle event of the given entity to the registered + * lifecycle callbacks and lifecycle listeners. + * + * @param string $event The lifecycle event. + * @param Entity $entity The Entity on which the event occured. + */ + public function invokeLifecycleCallbacks($lifecycleEvent, $entity) + { + foreach ($this->lifecycleCallbacks[$lifecycleEvent] as $callback) { + $entity->$callback(); + } + } + + /** + * Whether the class has any attached lifecycle listeners or callbacks for a lifecycle event. + * + * @param string $lifecycleEvent + * @return boolean + */ + public function hasLifecycleCallbacks($lifecycleEvent) + { + return isset($this->lifecycleCallbacks[$lifecycleEvent]); + } + + /** + * Gets the registered lifecycle callbacks for an event. + * + * @param string $event + * @return array + */ + public function getLifecycleCallbacks($event) + { + return isset($this->lifecycleCallbacks[$event]) ? $this->lifecycleCallbacks[$event] : array(); + } + + /** + * Adds a lifecycle callback for entities of this class. + * + * @param string $callback + * @param string $event + */ + public function addLifecycleCallback($callback, $event) + { + $this->lifecycleCallbacks[$event][] = $callback; + } + + /** + * Sets the lifecycle callbacks for entities of this class. + * Any previously registered callbacks are overwritten. + * + * @param array $callbacks + */ + public function setLifecycleCallbacks(array $callbacks) + { + $this->lifecycleCallbacks = $callbacks; + } + + /** + * Sets the discriminator column definition. + * + * @param array $columnDef + * @see getDiscriminatorColumn() + */ + public function setDiscriminatorColumn($columnDef) + { + if ($columnDef !== null) { + if (isset($this->fieldNames[$columnDef['name']])) { + throw MappingException::duplicateColumnName($this->name, $columnDef['name']); + } + + if ( ! isset($columnDef['name'])) { + throw MappingException::nameIsMandatoryForDiscriminatorColumns($this->name, $columnDef); + } + if ( ! isset($columnDef['fieldName'])) { + $columnDef['fieldName'] = $columnDef['name']; + } + if ( ! isset($columnDef['type'])) { + $columnDef['type'] = "string"; + } + if (in_array($columnDef['type'], array("boolean", "array", "object", "datetime", "time", "date"))) { + throw MappingException::invalidDiscriminatorColumnType($this->name, $columnDef['type']); + } + + $this->discriminatorColumn = $columnDef; + } + } + + /** + * Sets the discriminator values used by this class. + * Used for JOINED and SINGLE_TABLE inheritance mapping strategies. + * + * @param array $map + */ + public function setDiscriminatorMap(array $map) + { + foreach ($map as $value => $className) { + $this->addDiscriminatorMapClass($value, $className); + } + } + + /** + * Add one entry of the discriminator map with a new class and corresponding name. + * + * @param string $name + * @param string $className + */ + public function addDiscriminatorMapClass($name, $className) + { + if (strlen($this->namespace) > 0 && strpos($className, '\\') === false) { + $className = $this->namespace . '\\' . $className; + } + + $className = ltrim($className, '\\'); + $this->discriminatorMap[$name] = $className; + + if ($this->name == $className) { + $this->discriminatorValue = $name; + } else { + if ( ! class_exists($className)) { + throw MappingException::invalidClassInDiscriminatorMap($className, $this->name); + } + if (is_subclass_of($className, $this->name) && ! in_array($className, $this->subClasses)) { + $this->subClasses[] = $className; + } + } + } + + /** + * Checks whether the class has a named query with the given query name. + * + * @param string $fieldName + * @return boolean + */ + public function hasNamedQuery($queryName) + { + return isset($this->namedQueries[$queryName]); + } + + /** + * Checks whether the class has a mapped association with the given field name. + * + * @param string $fieldName + * @return boolean + */ + public function hasAssociation($fieldName) + { + return isset($this->associationMappings[$fieldName]); + } + + /** + * Checks whether the class has a mapped association for the specified field + * and if yes, checks whether it is a single-valued association (to-one). + * + * @param string $fieldName + * @return boolean TRUE if the association exists and is single-valued, FALSE otherwise. + */ + public function isSingleValuedAssociation($fieldName) + { + return isset($this->associationMappings[$fieldName]) && + ($this->associationMappings[$fieldName]['type'] & self::TO_ONE); + } + + /** + * Checks whether the class has a mapped association for the specified field + * and if yes, checks whether it is a collection-valued association (to-many). + * + * @param string $fieldName + * @return boolean TRUE if the association exists and is collection-valued, FALSE otherwise. + */ + public function isCollectionValuedAssociation($fieldName) + { + return isset($this->associationMappings[$fieldName]) && + ! ($this->associationMappings[$fieldName]['type'] & self::TO_ONE); + } + + /** + * Is this an association that only has a single join column? + * + * @param string $fieldName + * @return bool + */ + public function isAssociationWithSingleJoinColumn($fieldName) + { + return ( + isset($this->associationMappings[$fieldName]) && + isset($this->associationMappings[$fieldName]['joinColumns'][0]) && + !isset($this->associationMappings[$fieldName]['joinColumns'][1]) + ); + } + + /** + * Return the single association join column (if any). + * + * @param string $fieldName + * @return string + */ + public function getSingleAssociationJoinColumnName($fieldName) + { + if (!$this->isAssociationWithSingleJoinColumn($fieldName)) { + throw MappingException::noSingleAssociationJoinColumnFound($this->name, $fieldName); + } + return $this->associationMappings[$fieldName]['joinColumns'][0]['name']; + } + + /** + * Return the single association referenced join column name (if any). + * + * @param string $fieldName + * @return string + */ + public function getSingleAssociationReferencedJoinColumnName($fieldName) + { + if (!$this->isAssociationWithSingleJoinColumn($fieldName)) { + throw MappingException::noSingleAssociationJoinColumnFound($this->name, $fieldName); + } + return $this->associationMappings[$fieldName]['joinColumns'][0]['referencedColumnName']; + } + + /** + * Used to retrieve a fieldname for either field or association from a given column, + * + * This method is used in foreign-key as primary-key contexts. + * + * @param string $columnName + * @return string + */ + public function getFieldForColumn($columnName) + { + if (isset($this->fieldNames[$columnName])) { + return $this->fieldNames[$columnName]; + } else { + foreach ($this->associationMappings AS $assocName => $mapping) { + if ($this->isAssociationWithSingleJoinColumn($assocName) && + $this->associationMappings[$assocName]['joinColumns'][0]['name'] == $columnName) { + + return $assocName; + } + } + + throw MappingException::noFieldNameFoundForColumn($this->name, $columnName); + } + } + + /** + * Sets the ID generator used to generate IDs for instances of this class. + * + * @param AbstractIdGenerator $generator + */ + public function setIdGenerator($generator) + { + $this->idGenerator = $generator; + } + + /** + * Sets the definition of the sequence ID generator for this class. + * + * The definition must have the following structure: + * + * array( + * 'sequenceName' => 'name', + * 'allocationSize' => 20, + * 'initialValue' => 1 + * ) + * + * + * @param array $definition + */ + public function setSequenceGeneratorDefinition(array $definition) + { + $this->sequenceGeneratorDefinition = $definition; + } + + /** + * Sets the version field mapping used for versioning. Sets the default + * value to use depending on the column type. + * + * @param array $mapping The version field mapping array + */ + public function setVersionMapping(array &$mapping) + { + $this->isVersioned = true; + $this->versionField = $mapping['fieldName']; + + if ( ! isset($mapping['default'])) { + if (in_array($mapping['type'], array('integer', 'bigint', 'smallint'))) { + $mapping['default'] = 1; + } else if ($mapping['type'] == 'datetime') { + $mapping['default'] = 'CURRENT_TIMESTAMP'; + } else { + throw MappingException::unsupportedOptimisticLockingType($this->name, $mapping['fieldName'], $mapping['type']); + } + } + } + + /** + * Sets whether this class is to be versioned for optimistic locking. + * + * @param boolean $bool + */ + public function setVersioned($bool) + { + $this->isVersioned = $bool; + } + + /** + * Sets the name of the field that is to be used for versioning if this class is + * versioned for optimistic locking. + * + * @param string $versionField + */ + public function setVersionField($versionField) + { + $this->versionField = $versionField; + } + + /** + * Mark this class as read only, no change tracking is applied to it. + * + * @return void + */ + public function markReadOnly() + { + $this->isReadOnly = true; + } + + /** + * A numerically indexed list of field names of this persistent class. + * + * This array includes identifier fields if present on this class. + * + * @return array + */ + public function getFieldNames() + { + return array_keys($this->fieldMappings); + } + + /** + * A numerically indexed list of association names of this persistent class. + * + * This array includes identifier associations if present on this class. + * + * @return array + */ + public function getAssociationNames() + { + return array_keys($this->associationMappings); + } + + /** + * Returns the target class name of the given association. + * + * @param string $assocName + * @return string + */ + public function getAssociationTargetClass($assocName) + { + if ( ! isset($this->associationMappings[$assocName])) { + throw new \InvalidArgumentException("Association name expected, '" . $assocName ."' is not an association."); + } + + return $this->associationMappings[$assocName]['targetEntity']; + } + + /** + * Get fully-qualified class name of this persistent class. + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Gets the (possibly quoted) identifier column names for safe use in an SQL statement. + * + * @param AbstractPlatform $platform + * @return array + */ + public function getQuotedIdentifierColumnNames($platform) + { + $quotedColumnNames = array(); + + foreach ($this->identifier as $idProperty) { + if (isset($this->fieldMappings[$idProperty])) { + $quotedColumnNames[] = isset($this->fieldMappings[$idProperty]['quoted']) + ? $platform->quoteIdentifier($this->fieldMappings[$idProperty]['columnName']) + : $this->fieldMappings[$idProperty]['columnName']; + + continue; + } + + // Association defined as Id field + $joinColumns = $this->associationMappings[$idProperty]['joinColumns']; + $assocQuotedColumnNames = array_map( + function ($joinColumn) { + return isset($joinColumn['quoted']) + ? $platform->quoteIdentifier($joinColumn['name']) + : $joinColumn['name']; + }, + $joinColumns + ); + + $quotedColumnNames = array_merge($quotedColumnNames, $assocQuotedColumnNames); + } + + return $quotedColumnNames; + } + + /** + * Gets the (possibly quoted) column name of a mapped field for safe use + * in an SQL statement. + * + * @param string $field + * @param AbstractPlatform $platform + * @return string + */ + public function getQuotedColumnName($field, $platform) + { + return isset($this->fieldMappings[$field]['quoted']) + ? $platform->quoteIdentifier($this->fieldMappings[$field]['columnName']) + : $this->fieldMappings[$field]['columnName']; + } + + /** + * Gets the (possibly quoted) primary table name of this class for safe use + * in an SQL statement. + * + * @param AbstractPlatform $platform + * @return string + */ + public function getQuotedTableName($platform) + { + return isset($this->table['quoted']) ? $platform->quoteIdentifier($this->table['name']) : $this->table['name']; + } + + /** + * Gets the (possibly quoted) name of the join table. + * + * @param AbstractPlatform $platform + * @return string + */ + public function getQuotedJoinTableName(array $assoc, $platform) + { + return isset($assoc['joinTable']['quoted']) ? $platform->quoteIdentifier($assoc['joinTable']['name']) : $assoc['joinTable']['name']; + } + + /** + * @param string $fieldName + * @return bool + */ + public function isAssociationInverseSide($fieldName) + { + return isset($this->associationMappings[$fieldName]) && ! $this->associationMappings[$fieldName]['isOwningSide']; + } + + /** + * @param string $fieldName + * @return string + */ + public function getAssociationMappedByTargetField($fieldName) + { + return $this->associationMappings[$fieldName]['mappedBy']; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Column.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Column.php new file mode 100644 index 0000000..5f7dd7f --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Column.php @@ -0,0 +1,46 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("PROPERTY") + */ +final class Column implements Annotation +{ + /** @var string */ + public $name; + /** @var mixed */ + public $type = 'string'; + /** @var integer */ + public $length; + /** @var integer */ + public $precision = 0; // The precision for a decimal (exact numeric) column (Applies only for decimal column) + /** @var integer */ + public $scale = 0; // The scale for a decimal (exact numeric) column (Applies only for decimal column) + /** @var boolean */ + public $unique = false; + /** @var boolean */ + public $nullable = false; + /** @var array */ + public $options = array(); + /** @var string */ + public $columnDefinition; +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/DiscriminatorColumn.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/DiscriminatorColumn.php new file mode 100644 index 0000000..aec0115 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/DiscriminatorColumn.php @@ -0,0 +1,36 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("CLASS") + */ +final class DiscriminatorColumn implements Annotation +{ + /** @var string */ + public $name; + /** @var string */ + public $type; + /** @var integer */ + public $length; + /** @var mixed */ + public $fieldName; // field name used in non-object hydration (array/scalar) +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/DiscriminatorMap.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/DiscriminatorMap.php new file mode 100644 index 0000000..8505cf9 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/DiscriminatorMap.php @@ -0,0 +1,30 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("CLASS") + */ +final class DiscriminatorMap implements Annotation +{ + /** @var array */ + public $value; +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/AbstractFileDriver.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/AbstractFileDriver.php new file mode 100644 index 0000000..6953bf2 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/AbstractFileDriver.php @@ -0,0 +1,213 @@ +. + */ + +namespace Doctrine\ORM\Mapping\Driver; + +use Doctrine\ORM\Mapping\MappingException; + +/** + * Base driver for file-based metadata drivers. + * + * A file driver operates in a mode where it loads the mapping files of individual + * classes on demand. This requires the user to adhere to the convention of 1 mapping + * file per class and the file names of the mapping files must correspond to the full + * class name, including namespace, with the namespace delimiters '\', replaced by dots '.'. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan H. Wage + * @author Roman Borschel + */ +abstract class AbstractFileDriver implements Driver +{ + /** + * The paths where to look for mapping files. + * + * @var array + */ + protected $_paths = array(); + + /** + * The file extension of mapping documents. + * + * @var string + */ + protected $_fileExtension; + + /** + * Initializes a new FileDriver that looks in the given path(s) for mapping + * documents and operates in the specified operating mode. + * + * @param string|array $paths One or multiple paths where mapping documents can be found. + */ + public function __construct($paths) + { + $this->addPaths((array) $paths); + } + + /** + * Append lookup paths to metadata driver. + * + * @param array $paths + */ + public function addPaths(array $paths) + { + $this->_paths = array_unique(array_merge($this->_paths, $paths)); + } + + /** + * Retrieve the defined metadata lookup paths. + * + * @return array + */ + public function getPaths() + { + return $this->_paths; + } + + /** + * Get the file extension used to look for mapping files under + * + * @return void + */ + public function getFileExtension() + { + return $this->_fileExtension; + } + + /** + * Set the file extension used to look for mapping files under + * + * @param string $fileExtension The file extension to set + * @return void + */ + public function setFileExtension($fileExtension) + { + $this->_fileExtension = $fileExtension; + } + + /** + * Get the element of schema meta data for the class from the mapping file. + * This will lazily load the mapping file if it is not loaded yet + * + * @return array $element The element of schema meta data + */ + public function getElement($className) + { + $result = $this->_loadMappingFile($this->_findMappingFile($className)); + + if(!isset($result[$className])){ + throw MappingException::invalidMappingFile($className, str_replace('\\', '.', $className) . $this->_fileExtension); + } + return $result[$className]; + } + + /** + * Whether the class with the specified name should have its metadata loaded. + * This is only the case if it is either mapped as an Entity or a + * MappedSuperclass. + * + * @param string $className + * @return boolean + */ + public function isTransient($className) + { + $fileName = str_replace('\\', '.', $className) . $this->_fileExtension; + + // Check whether file exists + foreach ((array) $this->_paths as $path) { + if (file_exists($path . DIRECTORY_SEPARATOR . $fileName)) { + return false; + } + } + + return true; + } + + /** + * Gets the names of all mapped classes known to this driver. + * + * @return array The names of all mapped classes known to this driver. + */ + public function getAllClassNames() + { + $classes = array(); + + if ($this->_paths) { + foreach ((array) $this->_paths as $path) { + if ( ! is_dir($path)) { + throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path); + } + + $iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($path), + \RecursiveIteratorIterator::LEAVES_ONLY + ); + + foreach ($iterator as $file) { + if (($fileName = $file->getBasename($this->_fileExtension)) == $file->getBasename()) { + continue; + } + + // NOTE: All files found here means classes are not transient! + $classes[] = str_replace('.', '\\', $fileName); + } + } + } + + return $classes; + } + + /** + * Finds the mapping file for the class with the given name by searching + * through the configured paths. + * + * @param $className + * @return string The (absolute) file name. + * @throws MappingException + */ + protected function _findMappingFile($className) + { + $fileName = str_replace('\\', '.', $className) . $this->_fileExtension; + + // Check whether file exists + foreach ((array) $this->_paths as $path) { + if (file_exists($path . DIRECTORY_SEPARATOR . $fileName)) { + return $path . DIRECTORY_SEPARATOR . $fileName; + } + } + + throw MappingException::mappingFileNotFound($className, $fileName); + } + + /** + * Loads a mapping file with the given name and returns a map + * from class/entity names to their corresponding elements. + * + * @param string $file The mapping file to load. + * @return array + */ + abstract protected function _loadMappingFile($file); +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php new file mode 100644 index 0000000..ace39c4 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -0,0 +1,592 @@ +. + */ + +namespace Doctrine\ORM\Mapping\Driver; + +use Doctrine\Common\Cache\ArrayCache, + Doctrine\Common\Annotations\AnnotationReader, + Doctrine\Common\Annotations\AnnotationRegistry, + Doctrine\ORM\Mapping\ClassMetadataInfo, + Doctrine\ORM\Mapping\MappingException; + +/** + * The AnnotationDriver reads the mapping metadata from docblock annotations. + * + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan H. Wage + * @author Roman Borschel + */ +class AnnotationDriver implements Driver +{ + /** + * The AnnotationReader. + * + * @var AnnotationReader + */ + protected $_reader; + + /** + * The paths where to look for mapping files. + * + * @var array + */ + protected $_paths = array(); + + /** + * The file extension of mapping documents. + * + * @var string + */ + protected $_fileExtension = '.php'; + + /** + * @param array + */ + protected $_classNames; + + /** + * Initializes a new AnnotationDriver that uses the given AnnotationReader for reading + * docblock annotations. + * + * @param AnnotationReader $reader The AnnotationReader to use, duck-typed. + * @param string|array $paths One or multiple paths where mapping classes can be found. + */ + public function __construct($reader, $paths = null) + { + $this->_reader = $reader; + if ($paths) { + $this->addPaths((array) $paths); + } + } + + /** + * Append lookup paths to metadata driver. + * + * @param array $paths + */ + public function addPaths(array $paths) + { + $this->_paths = array_unique(array_merge($this->_paths, $paths)); + } + + /** + * Retrieve the defined metadata lookup paths. + * + * @return array + */ + public function getPaths() + { + return $this->_paths; + } + + /** + * Retrieve the current annotation reader + * + * @return AnnotationReader + */ + public function getReader() + { + return $this->_reader; + } + + /** + * Get the file extension used to look for mapping files under + * + * @return void + */ + public function getFileExtension() + { + return $this->_fileExtension; + } + + /** + * Set the file extension used to look for mapping files under + * + * @param string $fileExtension The file extension to set + * @return void + */ + public function setFileExtension($fileExtension) + { + $this->_fileExtension = $fileExtension; + } + + /** + * {@inheritdoc} + */ + public function loadMetadataForClass($className, ClassMetadataInfo $metadata) + { + $class = $metadata->getReflectionClass(); + if (!$class) { + // this happens when running annotation driver in combination with + // static reflection services. This is not the nicest fix + $class = new \ReflectionClass($metadata->name); + } + + $classAnnotations = $this->_reader->getClassAnnotations($class); + + if ($classAnnotations && is_numeric(key($classAnnotations))) { + foreach ($classAnnotations as $annot) { + $classAnnotations[get_class($annot)] = $annot; + } + } + + // Evaluate Entity annotation + if (isset($classAnnotations['Doctrine\ORM\Mapping\Entity'])) { + $entityAnnot = $classAnnotations['Doctrine\ORM\Mapping\Entity']; + if ($entityAnnot->repositoryClass !== null) { + $metadata->setCustomRepositoryClass($entityAnnot->repositoryClass); + } + if ($entityAnnot->readOnly) { + $metadata->markReadOnly(); + } + } else if (isset($classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass'])) { + $mappedSuperclassAnnot = $classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass']; + $metadata->setCustomRepositoryClass($mappedSuperclassAnnot->repositoryClass); + $metadata->isMappedSuperclass = true; + } else { + throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className); + } + + // Evaluate Table annotation + if (isset($classAnnotations['Doctrine\ORM\Mapping\Table'])) { + $tableAnnot = $classAnnotations['Doctrine\ORM\Mapping\Table']; + $primaryTable = array( + 'name' => $tableAnnot->name, + 'schema' => $tableAnnot->schema + ); + + if ($tableAnnot->indexes !== null) { + foreach ($tableAnnot->indexes as $indexAnnot) { + $index = array('columns' => $indexAnnot->columns); + + if ( ! empty($indexAnnot->name)) { + $primaryTable['indexes'][$indexAnnot->name] = $index; + } else { + $primaryTable['indexes'][] = $index; + } + } + } + + if ($tableAnnot->uniqueConstraints !== null) { + foreach ($tableAnnot->uniqueConstraints as $uniqueConstraintAnnot) { + $uniqueConstraint = array('columns' => $uniqueConstraintAnnot->columns); + + if ( ! empty($uniqueConstraintAnnot->name)) { + $primaryTable['uniqueConstraints'][$uniqueConstraintAnnot->name] = $uniqueConstraint; + } else { + $primaryTable['uniqueConstraints'][] = $uniqueConstraint; + } + } + } + + $metadata->setPrimaryTable($primaryTable); + } + + // Evaluate NamedQueries annotation + if (isset($classAnnotations['Doctrine\ORM\Mapping\NamedQueries'])) { + $namedQueriesAnnot = $classAnnotations['Doctrine\ORM\Mapping\NamedQueries']; + + if (!is_array($namedQueriesAnnot->value)) { + throw new \UnexpectedValueException("@NamedQueries should contain an array of @NamedQuery annotations."); + } + + foreach ($namedQueriesAnnot->value as $namedQuery) { + if (!($namedQuery instanceof \Doctrine\ORM\Mapping\NamedQuery)) { + throw new \UnexpectedValueException("@NamedQueries should contain an array of @NamedQuery annotations."); + } + $metadata->addNamedQuery(array( + 'name' => $namedQuery->name, + 'query' => $namedQuery->query + )); + } + } + + // Evaluate InheritanceType annotation + if (isset($classAnnotations['Doctrine\ORM\Mapping\InheritanceType'])) { + $inheritanceTypeAnnot = $classAnnotations['Doctrine\ORM\Mapping\InheritanceType']; + $metadata->setInheritanceType(constant('Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . $inheritanceTypeAnnot->value)); + + if ($metadata->inheritanceType != \Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_NONE) { + // Evaluate DiscriminatorColumn annotation + if (isset($classAnnotations['Doctrine\ORM\Mapping\DiscriminatorColumn'])) { + $discrColumnAnnot = $classAnnotations['Doctrine\ORM\Mapping\DiscriminatorColumn']; + $metadata->setDiscriminatorColumn(array( + 'name' => $discrColumnAnnot->name, + 'type' => $discrColumnAnnot->type, + 'length' => $discrColumnAnnot->length + )); + } else { + $metadata->setDiscriminatorColumn(array('name' => 'dtype', 'type' => 'string', 'length' => 255)); + } + + // Evaluate DiscriminatorMap annotation + if (isset($classAnnotations['Doctrine\ORM\Mapping\DiscriminatorMap'])) { + $discrMapAnnot = $classAnnotations['Doctrine\ORM\Mapping\DiscriminatorMap']; + $metadata->setDiscriminatorMap($discrMapAnnot->value); + } + } + } + + + // Evaluate DoctrineChangeTrackingPolicy annotation + if (isset($classAnnotations['Doctrine\ORM\Mapping\ChangeTrackingPolicy'])) { + $changeTrackingAnnot = $classAnnotations['Doctrine\ORM\Mapping\ChangeTrackingPolicy']; + $metadata->setChangeTrackingPolicy(constant('Doctrine\ORM\Mapping\ClassMetadata::CHANGETRACKING_' . $changeTrackingAnnot->value)); + } + + // Evaluate annotations on properties/fields + foreach ($class->getProperties() as $property) { + if ($metadata->isMappedSuperclass && ! $property->isPrivate() + || + $metadata->isInheritedField($property->name) + || + $metadata->isInheritedAssociation($property->name)) { + continue; + } + + $mapping = array(); + $mapping['fieldName'] = $property->getName(); + + // Check for JoinColummn/JoinColumns annotations + $joinColumns = array(); + + if ($joinColumnAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumn')) { + $joinColumns[] = array( + 'name' => $joinColumnAnnot->name, + 'referencedColumnName' => $joinColumnAnnot->referencedColumnName, + 'unique' => $joinColumnAnnot->unique, + 'nullable' => $joinColumnAnnot->nullable, + 'onDelete' => $joinColumnAnnot->onDelete, + 'columnDefinition' => $joinColumnAnnot->columnDefinition, + ); + } else if ($joinColumnsAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumns')) { + foreach ($joinColumnsAnnot->value as $joinColumn) { + $joinColumns[] = array( + 'name' => $joinColumn->name, + 'referencedColumnName' => $joinColumn->referencedColumnName, + 'unique' => $joinColumn->unique, + 'nullable' => $joinColumn->nullable, + 'onDelete' => $joinColumn->onDelete, + 'columnDefinition' => $joinColumn->columnDefinition, + ); + } + } + + // Field can only be annotated with one of: + // @Column, @OneToOne, @OneToMany, @ManyToOne, @ManyToMany + if ($columnAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Column')) { + if ($columnAnnot->type == null) { + throw MappingException::propertyTypeIsRequired($className, $property->getName()); + } + + $mapping['type'] = $columnAnnot->type; + $mapping['length'] = $columnAnnot->length; + $mapping['precision'] = $columnAnnot->precision; + $mapping['scale'] = $columnAnnot->scale; + $mapping['nullable'] = $columnAnnot->nullable; + $mapping['unique'] = $columnAnnot->unique; + if ($columnAnnot->options) { + $mapping['options'] = $columnAnnot->options; + } + + if (isset($columnAnnot->name)) { + $mapping['columnName'] = $columnAnnot->name; + } + + if (isset($columnAnnot->columnDefinition)) { + $mapping['columnDefinition'] = $columnAnnot->columnDefinition; + } + + if ($idAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) { + $mapping['id'] = true; + } + + if ($generatedValueAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\GeneratedValue')) { + $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' . $generatedValueAnnot->strategy)); + } + + if ($versionAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Version')) { + $metadata->setVersionMapping($mapping); + } + + $metadata->mapField($mapping); + + // Check for SequenceGenerator/TableGenerator definition + if ($seqGeneratorAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\SequenceGenerator')) { + $metadata->setSequenceGeneratorDefinition(array( + 'sequenceName' => $seqGeneratorAnnot->sequenceName, + 'allocationSize' => $seqGeneratorAnnot->allocationSize, + 'initialValue' => $seqGeneratorAnnot->initialValue + )); + } else if ($tblGeneratorAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\TableGenerator')) { + throw MappingException::tableIdGeneratorNotImplemented($className); + } + } else if ($oneToOneAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OneToOne')) { + if ($idAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) { + $mapping['id'] = true; + } + + $mapping['targetEntity'] = $oneToOneAnnot->targetEntity; + $mapping['joinColumns'] = $joinColumns; + $mapping['mappedBy'] = $oneToOneAnnot->mappedBy; + $mapping['inversedBy'] = $oneToOneAnnot->inversedBy; + $mapping['cascade'] = $oneToOneAnnot->cascade; + $mapping['orphanRemoval'] = $oneToOneAnnot->orphanRemoval; + $mapping['fetch'] = $this->getFetchMode($className, $oneToOneAnnot->fetch); + $metadata->mapOneToOne($mapping); + } else if ($oneToManyAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OneToMany')) { + $mapping['mappedBy'] = $oneToManyAnnot->mappedBy; + $mapping['targetEntity'] = $oneToManyAnnot->targetEntity; + $mapping['cascade'] = $oneToManyAnnot->cascade; + $mapping['indexBy'] = $oneToManyAnnot->indexBy; + $mapping['orphanRemoval'] = $oneToManyAnnot->orphanRemoval; + $mapping['fetch'] = $this->getFetchMode($className, $oneToManyAnnot->fetch); + + if ($orderByAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OrderBy')) { + $mapping['orderBy'] = $orderByAnnot->value; + } + + $metadata->mapOneToMany($mapping); + } else if ($manyToOneAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToOne')) { + if ($idAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) { + $mapping['id'] = true; + } + + $mapping['joinColumns'] = $joinColumns; + $mapping['cascade'] = $manyToOneAnnot->cascade; + $mapping['inversedBy'] = $manyToOneAnnot->inversedBy; + $mapping['targetEntity'] = $manyToOneAnnot->targetEntity; + $mapping['fetch'] = $this->getFetchMode($className, $manyToOneAnnot->fetch); + $metadata->mapManyToOne($mapping); + } else if ($manyToManyAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToMany')) { + $joinTable = array(); + + if ($joinTableAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinTable')) { + $joinTable = array( + 'name' => $joinTableAnnot->name, + 'schema' => $joinTableAnnot->schema + ); + + foreach ($joinTableAnnot->joinColumns as $joinColumn) { + $joinTable['joinColumns'][] = array( + 'name' => $joinColumn->name, + 'referencedColumnName' => $joinColumn->referencedColumnName, + 'unique' => $joinColumn->unique, + 'nullable' => $joinColumn->nullable, + 'onDelete' => $joinColumn->onDelete, + 'columnDefinition' => $joinColumn->columnDefinition, + ); + } + + foreach ($joinTableAnnot->inverseJoinColumns as $joinColumn) { + $joinTable['inverseJoinColumns'][] = array( + 'name' => $joinColumn->name, + 'referencedColumnName' => $joinColumn->referencedColumnName, + 'unique' => $joinColumn->unique, + 'nullable' => $joinColumn->nullable, + 'onDelete' => $joinColumn->onDelete, + 'columnDefinition' => $joinColumn->columnDefinition, + ); + } + } + + $mapping['joinTable'] = $joinTable; + $mapping['targetEntity'] = $manyToManyAnnot->targetEntity; + $mapping['mappedBy'] = $manyToManyAnnot->mappedBy; + $mapping['inversedBy'] = $manyToManyAnnot->inversedBy; + $mapping['cascade'] = $manyToManyAnnot->cascade; + $mapping['indexBy'] = $manyToManyAnnot->indexBy; + $mapping['orphanRemoval'] = $manyToManyAnnot->orphanRemoval; + $mapping['fetch'] = $this->getFetchMode($className, $manyToManyAnnot->fetch); + + if ($orderByAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OrderBy')) { + $mapping['orderBy'] = $orderByAnnot->value; + } + + $metadata->mapManyToMany($mapping); + } + } + + // Evaluate @HasLifecycleCallbacks annotation + if (isset($classAnnotations['Doctrine\ORM\Mapping\HasLifecycleCallbacks'])) { + foreach ($class->getMethods() as $method) { + // filter for the declaring class only, callbacks from parents will already be registered. + if ($method->isPublic() && $method->getDeclaringClass()->getName() == $class->name) { + $annotations = $this->_reader->getMethodAnnotations($method); + + if ($annotations && is_numeric(key($annotations))) { + foreach ($annotations as $annot) { + $annotations[get_class($annot)] = $annot; + } + } + + if (isset($annotations['Doctrine\ORM\Mapping\PrePersist'])) { + $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::prePersist); + } + + if (isset($annotations['Doctrine\ORM\Mapping\PostPersist'])) { + $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postPersist); + } + + if (isset($annotations['Doctrine\ORM\Mapping\PreUpdate'])) { + $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preUpdate); + } + + if (isset($annotations['Doctrine\ORM\Mapping\PostUpdate'])) { + $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postUpdate); + } + + if (isset($annotations['Doctrine\ORM\Mapping\PreRemove'])) { + $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preRemove); + } + + if (isset($annotations['Doctrine\ORM\Mapping\PostRemove'])) { + $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postRemove); + } + + if (isset($annotations['Doctrine\ORM\Mapping\PostLoad'])) { + $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postLoad); + } + + if (isset($annotations['Doctrine\ORM\Mapping\PreFlush'])) { + $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preFlush); + } + } + } + } + } + + /** + * Whether the class with the specified name is transient. Only non-transient + * classes, that is entities and mapped superclasses, should have their metadata loaded. + * A class is non-transient if it is annotated with either @Entity or + * @MappedSuperclass in the class doc block. + * + * @param string $className + * @return boolean + */ + public function isTransient($className) + { + $classAnnotations = $this->_reader->getClassAnnotations(new \ReflectionClass($className)); + + if ($classAnnotations && is_numeric(key($classAnnotations))) { + foreach ($classAnnotations as $annot) { + if ($annot instanceof \Doctrine\ORM\Mapping\Entity) { + return false; + } + if ($annot instanceof \Doctrine\ORM\Mapping\MappedSuperclass) { + return false; + } + } + + return true; + } + + return ! isset($classAnnotations['Doctrine\ORM\Mapping\Entity']) && + ! isset($classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass']); + } + + /** + * {@inheritDoc} + */ + public function getAllClassNames() + { + if ($this->_classNames !== null) { + return $this->_classNames; + } + + if (!$this->_paths) { + throw MappingException::pathRequired(); + } + + $classes = array(); + $includedFiles = array(); + + foreach ($this->_paths as $path) { + if ( ! is_dir($path)) { + throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path); + } + + $iterator = new \RegexIterator( + new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS), + \RecursiveIteratorIterator::LEAVES_ONLY + ), + '/^.+' . str_replace('.', '\.', $this->_fileExtension) . '$/i', + \RecursiveRegexIterator::GET_MATCH + ); + + foreach ($iterator as $file) { + $sourceFile = realpath($file[0]); + + require_once $sourceFile; + + $includedFiles[] = $sourceFile; + } + } + + $declared = get_declared_classes(); + + foreach ($declared as $className) { + $rc = new \ReflectionClass($className); + $sourceFile = $rc->getFileName(); + if (in_array($sourceFile, $includedFiles) && ! $this->isTransient($className)) { + $classes[] = $className; + } + } + + $this->_classNames = $classes; + + return $classes; + } + + /** + * Attempts to resolve the fetch mode. + * + * @param string $className The class name + * @param string $fetchMode The fetch mode + * @return integer The fetch mode as defined in ClassMetadata + * @throws MappingException If the fetch mode is not valid + */ + private function getFetchMode($className, $fetchMode) + { + if(!defined('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $fetchMode)) { + throw MappingException::invalidFetchMode($className, $fetchMode); + } + + return constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $fetchMode); + } + /** + * Factory method for the Annotation Driver + * + * @param array|string $paths + * @param AnnotationReader $reader + * @return AnnotationDriver + */ + static public function create($paths = array(), AnnotationReader $reader = null) + { + if ($reader == null) { + $reader = new AnnotationReader(); + $reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\'); + } + return new self($reader, $paths); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php new file mode 100644 index 0000000..bcbdbd5 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php @@ -0,0 +1,417 @@ +. + */ + +namespace Doctrine\ORM\Mapping\Driver; + +use Doctrine\Common\Cache\ArrayCache, + Doctrine\Common\Annotations\AnnotationReader, + Doctrine\DBAL\Schema\AbstractSchemaManager, + Doctrine\DBAL\Schema\SchemaException, + Doctrine\ORM\Mapping\ClassMetadataInfo, + Doctrine\ORM\Mapping\MappingException, + Doctrine\Common\Util\Inflector; + +/** + * The DatabaseDriver reverse engineers the mapping metadata from a database. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Benjamin Eberlei + */ +class DatabaseDriver implements Driver +{ + /** + * @var AbstractSchemaManager + */ + private $_sm; + + /** + * @var array + */ + private $tables = null; + + private $classToTableNames = array(); + + /** + * @var array + */ + private $manyToManyTables = array(); + + /** + * @var array + */ + private $classNamesForTables = array(); + + /** + * @var array + */ + private $fieldNamesForColumns = array(); + + /** + * The namespace for the generated entities. + * + * @var string + */ + private $namespace; + + /** + * Initializes a new AnnotationDriver that uses the given AnnotationReader for reading + * docblock annotations. + * + * @param AnnotationReader $reader The AnnotationReader to use. + */ + public function __construct(AbstractSchemaManager $schemaManager) + { + $this->_sm = $schemaManager; + } + + /** + * Set tables manually instead of relying on the reverse engeneering capabilities of SchemaManager. + * + * @param array $entityTables + * @param array $manyToManyTables + * @return void + */ + public function setTables($entityTables, $manyToManyTables) + { + $this->tables = $this->manyToManyTables = $this->classToTableNames = array(); + foreach ($entityTables AS $table) { + $className = $this->getClassNameForTable($table->getName()); + $this->classToTableNames[$className] = $table->getName(); + $this->tables[$table->getName()] = $table; + } + foreach ($manyToManyTables AS $table) { + $this->manyToManyTables[$table->getName()] = $table; + } + } + + private function reverseEngineerMappingFromDatabase() + { + if ($this->tables !== null) { + return; + } + + $tables = array(); + + foreach ($this->_sm->listTableNames() as $tableName) { + $tables[$tableName] = $this->_sm->listTableDetails($tableName); + } + + $this->tables = $this->manyToManyTables = $this->classToTableNames = array(); + foreach ($tables AS $tableName => $table) { + /* @var $table Table */ + if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) { + $foreignKeys = $table->getForeignKeys(); + } else { + $foreignKeys = array(); + } + + $allForeignKeyColumns = array(); + foreach ($foreignKeys AS $foreignKey) { + $allForeignKeyColumns = array_merge($allForeignKeyColumns, $foreignKey->getLocalColumns()); + } + + if ( ! $table->hasPrimaryKey()) { + throw new MappingException( + "Table " . $table->getName() . " has no primary key. Doctrine does not ". + "support reverse engineering from tables that don't have a primary key." + ); + } + + $pkColumns = $table->getPrimaryKey()->getColumns(); + sort($pkColumns); + sort($allForeignKeyColumns); + + if ($pkColumns == $allForeignKeyColumns && count($foreignKeys) == 2) { + $this->manyToManyTables[$tableName] = $table; + } else { + // lower-casing is necessary because of Oracle Uppercase Tablenames, + // assumption is lower-case + underscore separated. + $className = $this->getClassNameForTable($tableName); + $this->tables[$tableName] = $table; + $this->classToTableNames[$className] = $tableName; + } + } + } + + /** + * {@inheritdoc} + */ + public function loadMetadataForClass($className, ClassMetadataInfo $metadata) + { + $this->reverseEngineerMappingFromDatabase(); + + if (!isset($this->classToTableNames[$className])) { + throw new \InvalidArgumentException("Unknown class " . $className); + } + + $tableName = $this->classToTableNames[$className]; + + $metadata->name = $className; + $metadata->table['name'] = $tableName; + + $columns = $this->tables[$tableName]->getColumns(); + $indexes = $this->tables[$tableName]->getIndexes(); + try { + $primaryKeyColumns = $this->tables[$tableName]->getPrimaryKey()->getColumns(); + } catch(SchemaException $e) { + $primaryKeyColumns = array(); + } + + if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) { + $foreignKeys = $this->tables[$tableName]->getForeignKeys(); + } else { + $foreignKeys = array(); + } + + $allForeignKeyColumns = array(); + foreach ($foreignKeys AS $foreignKey) { + $allForeignKeyColumns = array_merge($allForeignKeyColumns, $foreignKey->getLocalColumns()); + } + + $ids = array(); + $fieldMappings = array(); + foreach ($columns as $column) { + $fieldMapping = array(); + + if (in_array($column->getName(), $allForeignKeyColumns)) { + continue; + } else if ($primaryKeyColumns && in_array($column->getName(), $primaryKeyColumns)) { + $fieldMapping['id'] = true; + } + + $fieldMapping['fieldName'] = $this->getFieldNameForColumn($tableName, $column->getName(), false); + $fieldMapping['columnName'] = $column->getName(); + $fieldMapping['type'] = strtolower((string) $column->getType()); + + if ($column->getType() instanceof \Doctrine\DBAL\Types\StringType) { + $fieldMapping['length'] = $column->getLength(); + $fieldMapping['fixed'] = $column->getFixed(); + } else if ($column->getType() instanceof \Doctrine\DBAL\Types\IntegerType) { + $fieldMapping['unsigned'] = $column->getUnsigned(); + } + $fieldMapping['nullable'] = $column->getNotNull() ? false : true; + + if (isset($fieldMapping['id'])) { + $ids[] = $fieldMapping; + } else { + $fieldMappings[] = $fieldMapping; + } + } + + if ($ids) { + if (count($ids) == 1) { + $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO); + } + + foreach ($ids as $id) { + $metadata->mapField($id); + } + } + + foreach ($fieldMappings as $fieldMapping) { + $metadata->mapField($fieldMapping); + } + + foreach ($this->manyToManyTables AS $manyTable) { + foreach ($manyTable->getForeignKeys() AS $foreignKey) { + // foreign key maps to the table of the current entity, many to many association probably exists + if (strtolower($tableName) == strtolower($foreignKey->getForeignTableName())) { + $myFk = $foreignKey; + $otherFk = null; + foreach ($manyTable->getForeignKeys() AS $foreignKey) { + if ($foreignKey != $myFk) { + $otherFk = $foreignKey; + break; + } + } + + if (!$otherFk) { + // the definition of this many to many table does not contain + // enough foreign key information to continue reverse engeneering. + continue; + } + + $localColumn = current($myFk->getColumns()); + $associationMapping = array(); + $associationMapping['fieldName'] = $this->getFieldNameForColumn($manyTable->getName(), current($otherFk->getColumns()), true); + $associationMapping['targetEntity'] = $this->getClassNameForTable($otherFk->getForeignTableName()); + if (current($manyTable->getColumns())->getName() == $localColumn) { + $associationMapping['inversedBy'] = $this->getFieldNameForColumn($manyTable->getName(), current($myFk->getColumns()), true); + $associationMapping['joinTable'] = array( + 'name' => strtolower($manyTable->getName()), + 'joinColumns' => array(), + 'inverseJoinColumns' => array(), + ); + + $fkCols = $myFk->getForeignColumns(); + $cols = $myFk->getColumns(); + for ($i = 0; $i < count($cols); $i++) { + $associationMapping['joinTable']['joinColumns'][] = array( + 'name' => $cols[$i], + 'referencedColumnName' => $fkCols[$i], + ); + } + + $fkCols = $otherFk->getForeignColumns(); + $cols = $otherFk->getColumns(); + for ($i = 0; $i < count($cols); $i++) { + $associationMapping['joinTable']['inverseJoinColumns'][] = array( + 'name' => $cols[$i], + 'referencedColumnName' => $fkCols[$i], + ); + } + } else { + $associationMapping['mappedBy'] = $this->getFieldNameForColumn($manyTable->getName(), current($myFk->getColumns()), true); + } + $metadata->mapManyToMany($associationMapping); + break; + } + } + } + + foreach ($foreignKeys as $foreignKey) { + $foreignTable = $foreignKey->getForeignTableName(); + $cols = $foreignKey->getColumns(); + $fkCols = $foreignKey->getForeignColumns(); + + $localColumn = current($cols); + $associationMapping = array(); + $associationMapping['fieldName'] = $this->getFieldNameForColumn($tableName, $localColumn, true); + $associationMapping['targetEntity'] = $this->getClassNameForTable($foreignTable); + + if ($primaryKeyColumns && in_array($localColumn, $primaryKeyColumns)) { + $associationMapping['id'] = true; + } + + for ($i = 0; $i < count($cols); $i++) { + $associationMapping['joinColumns'][] = array( + 'name' => $cols[$i], + 'referencedColumnName' => $fkCols[$i], + ); + } + + //Here we need to check if $cols are the same as $primaryKeyColums + if (!array_diff($cols,$primaryKeyColumns)) { + $metadata->mapOneToOne($associationMapping); + } else { + $metadata->mapManyToOne($associationMapping); + } + } + } + + /** + * {@inheritdoc} + */ + public function isTransient($className) + { + return true; + } + + /** + * Return all the class names supported by this driver. + * + * IMPORTANT: This method must return an array of class not tables names. + * + * @return array + */ + public function getAllClassNames() + { + $this->reverseEngineerMappingFromDatabase(); + + return array_keys($this->classToTableNames); + } + + /** + * Set class name for a table. + * + * @param string $tableName + * @param string $className + * @return void + */ + public function setClassNameForTable($tableName, $className) + { + $this->classNamesForTables[$tableName] = $className; + } + + /** + * Set field name for a column on a specific table. + * + * @param string $tableName + * @param string $columnName + * @param string $fieldName + * @return void + */ + public function setFieldNameForColumn($tableName, $columnName, $fieldName) + { + $this->fieldNamesForColumns[$tableName][$columnName] = $fieldName; + } + + /** + * Return the mapped class name for a table if it exists. Otherwise return "classified" version. + * + * @param string $tableName + * @return string + */ + private function getClassNameForTable($tableName) + { + if (isset($this->classNamesForTables[$tableName])) { + return $this->namespace . $this->classNamesForTables[$tableName]; + } + + return $this->namespace . Inflector::classify(strtolower($tableName)); + } + + /** + * Return the mapped field name for a column, if it exists. Otherwise return camelized version. + * + * @param string $tableName + * @param string $columnName + * @param boolean $fk Whether the column is a foreignkey or not. + * @return string + */ + private function getFieldNameForColumn($tableName, $columnName, $fk = false) + { + if (isset($this->fieldNamesForColumns[$tableName]) && isset($this->fieldNamesForColumns[$tableName][$columnName])) { + return $this->fieldNamesForColumns[$tableName][$columnName]; + } + + $columnName = strtolower($columnName); + + // Replace _id if it is a foreignkey column + if ($fk) { + $columnName = str_replace('_id', '', $columnName); + } + return Inflector::camelize($columnName); + } + + /** + * Set the namespace for the generated entities. + * + * @param string $namespace + * @return void + */ + public function setNamespace($namespace) + { + $this->namespace = $namespace; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php new file mode 100644 index 0000000..290fc65 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php @@ -0,0 +1,54 @@ +. + */ + +require_once __DIR__.'/../Annotation.php'; +require_once __DIR__.'/../Entity.php'; +require_once __DIR__.'/../MappedSuperclass.php'; +require_once __DIR__.'/../InheritanceType.php'; +require_once __DIR__.'/../DiscriminatorColumn.php'; +require_once __DIR__.'/../DiscriminatorMap.php'; +require_once __DIR__.'/../Id.php'; +require_once __DIR__.'/../GeneratedValue.php'; +require_once __DIR__.'/../Version.php'; +require_once __DIR__.'/../JoinColumn.php'; +require_once __DIR__.'/../JoinColumns.php'; +require_once __DIR__.'/../Column.php'; +require_once __DIR__.'/../OneToOne.php'; +require_once __DIR__.'/../OneToMany.php'; +require_once __DIR__.'/../ManyToOne.php'; +require_once __DIR__.'/../ManyToMany.php'; +require_once __DIR__.'/../ElementCollection.php'; +require_once __DIR__.'/../Table.php'; +require_once __DIR__.'/../UniqueConstraint.php'; +require_once __DIR__.'/../Index.php'; +require_once __DIR__.'/../JoinTable.php'; +require_once __DIR__.'/../SequenceGenerator.php'; +require_once __DIR__.'/../ChangeTrackingPolicy.php'; +require_once __DIR__.'/../OrderBy.php'; +require_once __DIR__.'/../NamedQueries.php'; +require_once __DIR__.'/../NamedQuery.php'; +require_once __DIR__.'/../HasLifecycleCallbacks.php'; +require_once __DIR__.'/../PrePersist.php'; +require_once __DIR__.'/../PostPersist.php'; +require_once __DIR__.'/../PreUpdate.php'; +require_once __DIR__.'/../PostUpdate.php'; +require_once __DIR__.'/../PreRemove.php'; +require_once __DIR__.'/../PostRemove.php'; +require_once __DIR__.'/../PostLoad.php'; +require_once __DIR__.'/../PreFlush.php'; diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/Driver.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/Driver.php new file mode 100644 index 0000000..28654a8 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/Driver.php @@ -0,0 +1,59 @@ +. + */ + +namespace Doctrine\ORM\Mapping\Driver; + +use Doctrine\ORM\Mapping\ClassMetadataInfo; + +/** + * Contract for metadata drivers. + * + * @since 2.0 + * @author Jonathan H. Wage + * @todo Rename: MetadataDriver or MappingDriver + */ +interface Driver +{ + /** + * Loads the metadata for the specified class into the provided container. + * + * @param string $className + * @param ClassMetadataInfo $metadata + */ + function loadMetadataForClass($className, ClassMetadataInfo $metadata); + + /** + * Gets the names of all mapped classes known to this driver. + * + * @return array The names of all mapped classes known to this driver. + */ + function getAllClassNames(); + + /** + * Whether the class with the specified name should have its metadata loaded. + * This is only the case if it is either mapped as an Entity or a + * MappedSuperclass. + * + * @param string $className + * @return boolean + */ + function isTransient($className); +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DriverChain.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DriverChain.php new file mode 100644 index 0000000..321962d --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DriverChain.php @@ -0,0 +1,126 @@ +. + */ + +namespace Doctrine\ORM\Mapping\Driver; + +use Doctrine\ORM\Mapping\Driver\Driver, + Doctrine\ORM\Mapping\ClassMetadataInfo, + Doctrine\ORM\Mapping\MappingException; + +/** + * The DriverChain allows you to add multiple other mapping drivers for + * certain namespaces + * + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan H. Wage + * @author Roman Borschel + * @todo Rename: MappingDriverChain or MetadataDriverChain + */ +class DriverChain implements Driver +{ + /** + * @var array + */ + private $_drivers = array(); + + /** + * Add a nested driver. + * + * @param Driver $nestedDriver + * @param string $namespace + */ + public function addDriver(Driver $nestedDriver, $namespace) + { + $this->_drivers[$namespace] = $nestedDriver; + } + + /** + * Get the array of nested drivers. + * + * @return array $drivers + */ + public function getDrivers() + { + return $this->_drivers; + } + + /** + * Loads the metadata for the specified class into the provided container. + * + * @param string $className + * @param ClassMetadataInfo $metadata + */ + public function loadMetadataForClass($className, ClassMetadataInfo $metadata) + { + foreach ($this->_drivers as $namespace => $driver) { + if (strpos($className, $namespace) === 0) { + $driver->loadMetadataForClass($className, $metadata); + return; + } + } + + throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className); + } + + /** + * Gets the names of all mapped classes known to this driver. + * + * @return array The names of all mapped classes known to this driver. + */ + public function getAllClassNames() + { + $classNames = array(); + $driverClasses = array(); + foreach ($this->_drivers AS $namespace => $driver) { + $oid = spl_object_hash($driver); + if (!isset($driverClasses[$oid])) { + $driverClasses[$oid] = $driver->getAllClassNames(); + } + + foreach ($driverClasses[$oid] AS $className) { + if (strpos($className, $namespace) === 0) { + $classNames[$className] = true; + } + } + } + return array_keys($classNames); + } + + /** + * Whether the class with the specified name should have its metadata loaded. + * + * This is only the case for non-transient classes either mapped as an Entity or MappedSuperclass. + * + * @param string $className + * @return boolean + */ + public function isTransient($className) + { + foreach ($this->_drivers AS $namespace => $driver) { + if (strpos($className, $namespace) === 0) { + return $driver->isTransient($className); + } + } + + // class isTransient, i.e. not an entity or mapped superclass + return true; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/PHPDriver.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/PHPDriver.php new file mode 100644 index 0000000..ff86597 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/PHPDriver.php @@ -0,0 +1,69 @@ +. + */ + +namespace Doctrine\ORM\Mapping\Driver; + +use Doctrine\Common\Cache\ArrayCache, + Doctrine\Common\Annotations\AnnotationReader, + Doctrine\DBAL\Schema\AbstractSchemaManager, + Doctrine\ORM\Mapping\ClassMetadataInfo, + Doctrine\ORM\Mapping\MappingException, + Doctrine\Common\Util\Inflector, + Doctrine\ORM\Mapping\Driver\AbstractFileDriver; + +/** + * The PHPDriver includes php files which just populate ClassMetadataInfo + * instances with plain php code + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan H. Wage + * @author Roman Borschel + * @todo Rename: PHPDriver + */ +class PHPDriver extends AbstractFileDriver +{ + /** + * {@inheritdoc} + */ + protected $_fileExtension = '.php'; + protected $_metadata; + + /** + * {@inheritdoc} + */ + public function loadMetadataForClass($className, ClassMetadataInfo $metadata) + { + $this->_metadata = $metadata; + $this->_loadMappingFile($this->_findMappingFile($className)); + } + + /** + * {@inheritdoc} + */ + protected function _loadMappingFile($file) + { + $metadata = $this->_metadata; + include $file; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/SimplifiedXmlDriver.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/SimplifiedXmlDriver.php new file mode 100644 index 0000000..e60eab7 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/SimplifiedXmlDriver.php @@ -0,0 +1,176 @@ +. +*/ + +namespace Doctrine\ORM\Mapping\Driver; + +use Doctrine\ORM\Mapping\MappingException; + +/** + * XmlDriver that additionally looks for mapping information in a global file. + * + * @author Fabien Potencier + * @author Benjamin Eberlei + * @license MIT + */ +class SimplifiedXmlDriver extends XmlDriver +{ + protected $_prefixes = array(); + protected $_globalBasename; + protected $_classCache; + protected $_fileExtension = '.orm.xml'; + + public function __construct($prefixes) + { + $this->addNamespacePrefixes($prefixes); + } + + public function setGlobalBasename($file) + { + $this->_globalBasename = $file; + } + + public function getGlobalBasename() + { + return $this->_globalBasename; + } + + public function addNamespacePrefixes($prefixes) + { + $this->_prefixes = array_merge($this->_prefixes, $prefixes); + $this->addPaths(array_flip($prefixes)); + } + + public function getNamespacePrefixes() + { + return $this->_prefixes; + } + + public function isTransient($className) + { + if (null === $this->_classCache) { + $this->initialize(); + } + + // The mapping is defined in the global mapping file + if (isset($this->_classCache[$className])) { + return false; + } + + try { + $this->_findMappingFile($className); + + return false; + } catch (MappingException $e) { + return true; + } + } + + public function getAllClassNames() + { + if (null === $this->_classCache) { + $this->initialize(); + } + + $classes = array(); + + if ($this->_paths) { + foreach ((array) $this->_paths as $path) { + if (!is_dir($path)) { + throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path); + } + + $iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($path), + \RecursiveIteratorIterator::LEAVES_ONLY + ); + + foreach ($iterator as $file) { + $fileName = $file->getBasename($this->_fileExtension); + + if ($fileName == $file->getBasename() || $fileName == $this->_globalBasename) { + continue; + } + + // NOTE: All files found here means classes are not transient! + if (isset($this->_prefixes[$path])) { + $classes[] = $this->_prefixes[$path].'\\'.str_replace('.', '\\', $fileName); + } else { + $classes[] = str_replace('.', '\\', $fileName); + } + } + } + } + + return array_merge($classes, array_keys($this->_classCache)); + } + + public function getElement($className) + { + if (null === $this->_classCache) { + $this->initialize(); + } + + if (!isset($this->_classCache[$className])) { + $this->_classCache[$className] = parent::getElement($className); + } + + return $this->_classCache[$className]; + } + + protected function initialize() + { + $this->_classCache = array(); + if (null !== $this->_globalBasename) { + foreach ($this->_paths as $path) { + if (is_file($file = $path.'/'.$this->_globalBasename.$this->_fileExtension)) { + $this->_classCache = array_merge($this->_classCache, $this->_loadMappingFile($file)); + } + } + } + } + + protected function _findMappingFile($className) + { + $defaultFileName = str_replace('\\', '.', $className).$this->_fileExtension; + foreach ($this->_paths as $path) { + if (!isset($this->_prefixes[$path])) { + if (is_file($path.DIRECTORY_SEPARATOR.$defaultFileName)) { + return $path.DIRECTORY_SEPARATOR.$defaultFileName; + } + + continue; + } + + $prefix = $this->_prefixes[$path]; + + if (0 !== strpos($className, $prefix.'\\')) { + continue; + } + + $filename = $path.'/'.strtr(substr($className, strlen($prefix)+1), '\\', '.').$this->_fileExtension; + if (is_file($filename)) { + return $filename; + } + + throw MappingException::mappingFileNotFound($className, $filename); + } + + throw MappingException::mappingFileNotFound($className, substr($className, strrpos($className, '\\') + 1).$this->_fileExtension); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/SimplifiedYamlDriver.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/SimplifiedYamlDriver.php new file mode 100644 index 0000000..b88a769 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/SimplifiedYamlDriver.php @@ -0,0 +1,181 @@ +. +*/ + +namespace Doctrine\ORM\Mapping\Driver; + +use Doctrine\ORM\Mapping\MappingException; + +/** + * YamlDriver that additionally looks for mapping information in a global file. + * + * @author Fabien Potencier + * @author Benjamin Eberlei + * @license MIT + */ +class SimplifiedYamlDriver extends YamlDriver +{ + protected $_prefixes = array(); + protected $_globalBasename; + protected $_classCache; + protected $_fileExtension = '.orm.yml'; + + public function __construct($prefixes) + { + $this->addNamespacePrefixes($prefixes); + } + + public function setGlobalBasename($file) + { + $this->_globalBasename = $file; + } + + public function getGlobalBasename() + { + return $this->_globalBasename; + } + + public function addNamespacePrefixes($prefixes) + { + $this->_prefixes = array_merge($this->_prefixes, $prefixes); + $this->addPaths(array_flip($prefixes)); + } + + public function addNamespacePrefix($prefix, $path) + { + $this->_prefixes[$path] = $prefix; + } + + public function getNamespacePrefixes() + { + return $this->_prefixes; + } + + public function isTransient($className) + { + if (null === $this->_classCache) { + $this->initialize(); + } + + // The mapping is defined in the global mapping file + if (isset($this->_classCache[$className])) { + return false; + } + + try { + $this->_findMappingFile($className); + + return false; + } catch (MappingException $e) { + return true; + } + } + + public function getAllClassNames() + { + if (null === $this->_classCache) { + $this->initialize(); + } + + $classes = array(); + + if ($this->_paths) { + foreach ((array) $this->_paths as $path) { + if (!is_dir($path)) { + throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path); + } + + $iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($path), + \RecursiveIteratorIterator::LEAVES_ONLY + ); + + foreach ($iterator as $file) { + $fileName = $file->getBasename($this->_fileExtension); + + if ($fileName == $file->getBasename() || $fileName == $this->_globalBasename) { + continue; + } + + // NOTE: All files found here means classes are not transient! + if (isset($this->_prefixes[$path])) { + $classes[] = $this->_prefixes[$path].'\\'.str_replace('.', '\\', $fileName); + } else { + $classes[] = str_replace('.', '\\', $fileName); + } + } + } + } + + return array_merge($classes, array_keys($this->_classCache)); + } + + public function getElement($className) + { + if (null === $this->_classCache) { + $this->initialize(); + } + + if (!isset($this->_classCache[$className])) { + $this->_classCache[$className] = parent::getElement($className); + } + + return $this->_classCache[$className]; + } + + protected function initialize() + { + $this->_classCache = array(); + if (null !== $this->_globalBasename) { + foreach ($this->_paths as $path) { + if (is_file($file = $path.'/'.$this->_globalBasename.$this->_fileExtension)) { + $this->_classCache = array_merge($this->_classCache, $this->_loadMappingFile($file)); + } + } + } + } + + protected function _findMappingFile($className) + { + $defaultFileName = str_replace('\\', '.', $className).$this->_fileExtension; + foreach ($this->_paths as $path) { + if (!isset($this->_prefixes[$path])) { + if (is_file($path.DIRECTORY_SEPARATOR.$defaultFileName)) { + return $path.DIRECTORY_SEPARATOR.$defaultFileName; + } + + continue; + } + + $prefix = $this->_prefixes[$path]; + + if (0 !== strpos($className, $prefix.'\\')) { + continue; + } + + $filename = $path.'/'.strtr(substr($className, strlen($prefix)+1), '\\', '.').$this->_fileExtension; + if (is_file($filename)) { + return $filename; + } + + throw MappingException::mappingFileNotFound($className, $filename); + } + + throw MappingException::mappingFileNotFound($className, substr($className, strrpos($className, '\\') + 1).$this->_fileExtension); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/StaticPHPDriver.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/StaticPHPDriver.php new file mode 100644 index 0000000..4e593ea --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/StaticPHPDriver.php @@ -0,0 +1,138 @@ +. + */ + +namespace Doctrine\ORM\Mapping\Driver; + +use Doctrine\ORM\Mapping\ClassMetadataInfo, + Doctrine\ORM\Mapping\MappingException; + +/** + * The StaticPHPDriver calls a static loadMetadata() method on your entity + * classes where you can manually populate the ClassMetadata instance. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan H. Wage + * @author Roman Borschel + */ +class StaticPHPDriver implements Driver +{ + /** + * Paths of entity directories. + * + * @var array + */ + private $_paths = array(); + + /** + * Map of all class names. + * + * @var array + */ + private $_classNames; + + /** + * The file extension of mapping documents. + * + * @var string + */ + private $_fileExtension = '.php'; + + public function __construct($paths) + { + $this->addPaths((array) $paths); + } + + public function addPaths(array $paths) + { + $this->_paths = array_unique(array_merge($this->_paths, $paths)); + } + + /** + * {@inheritdoc} + */ + public function loadMetadataForClass($className, ClassMetadataInfo $metadata) + { + call_user_func_array(array($className, 'loadMetadata'), array($metadata)); + } + + /** + * {@inheritDoc} + * @todo Same code exists in AnnotationDriver, should we re-use it somehow or not worry about it? + */ + public function getAllClassNames() + { + if ($this->_classNames !== null) { + return $this->_classNames; + } + + if (!$this->_paths) { + throw MappingException::pathRequired(); + } + + $classes = array(); + $includedFiles = array(); + + foreach ($this->_paths as $path) { + if (!is_dir($path)) { + throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path); + } + + $iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($path), + \RecursiveIteratorIterator::LEAVES_ONLY + ); + + foreach ($iterator as $file) { + if (($fileName = $file->getBasename($this->_fileExtension)) == $file->getBasename()) { + continue; + } + + $sourceFile = realpath($file->getPathName()); + require_once $sourceFile; + $includedFiles[] = $sourceFile; + } + } + + $declared = get_declared_classes(); + + foreach ($declared as $className) { + $rc = new \ReflectionClass($className); + $sourceFile = $rc->getFileName(); + if (in_array($sourceFile, $includedFiles) && !$this->isTransient($className)) { + $classes[] = $className; + } + } + + $this->_classNames = $classes; + + return $classes; + } + + /** + * {@inheritdoc} + */ + public function isTransient($className) + { + return method_exists($className, 'loadMetadata') ? false : true; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php new file mode 100644 index 0000000..31f3191 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php @@ -0,0 +1,536 @@ +. + */ + +namespace Doctrine\ORM\Mapping\Driver; + +use SimpleXMLElement, + Doctrine\ORM\Mapping\ClassMetadataInfo, + Doctrine\ORM\Mapping\MappingException; + +/** + * XmlDriver is a metadata driver that enables mapping through XML files. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan H. Wage + * @author Roman Borschel + */ +class XmlDriver extends AbstractFileDriver +{ + /** + * {@inheritdoc} + */ + protected $_fileExtension = '.dcm.xml'; + + /** + * {@inheritdoc} + */ + public function loadMetadataForClass($className, ClassMetadataInfo $metadata) + { + $xmlRoot = $this->getElement($className); + + if ($xmlRoot->getName() == 'entity') { + if (isset($xmlRoot['repository-class'])) { + $metadata->setCustomRepositoryClass((string)$xmlRoot['repository-class']); + } + if (isset($xmlRoot['read-only']) && $xmlRoot['read-only'] == "true") { + $metadata->markReadOnly(); + } + } else if ($xmlRoot->getName() == 'mapped-superclass') { + $metadata->setCustomRepositoryClass( + isset($xmlRoot['repository-class']) ? (string)$xmlRoot['repository-class'] : null + ); + $metadata->isMappedSuperclass = true; + } else { + throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className); + } + + // Evaluate attributes + $table = array(); + if (isset($xmlRoot['table'])) { + $table['name'] = (string)$xmlRoot['table']; + } + + $metadata->setPrimaryTable($table); + + // Evaluate named queries + if (isset($xmlRoot['named-queries'])) { + foreach ($xmlRoot->{'named-queries'}->{'named-query'} as $namedQueryElement) { + $metadata->addNamedQuery(array( + 'name' => (string)$namedQueryElement['name'], + 'query' => (string)$namedQueryElement['query'] + )); + } + } + + /* not implemented specially anyway. use table = schema.table + if (isset($xmlRoot['schema'])) { + $metadata->table['schema'] = (string)$xmlRoot['schema']; + }*/ + + if (isset($xmlRoot['inheritance-type'])) { + $inheritanceType = (string)$xmlRoot['inheritance-type']; + $metadata->setInheritanceType(constant('Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . $inheritanceType)); + + if ($metadata->inheritanceType != \Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_NONE) { + // Evaluate + if (isset($xmlRoot->{'discriminator-column'})) { + $discrColumn = $xmlRoot->{'discriminator-column'}; + $metadata->setDiscriminatorColumn(array( + 'name' => (string)$discrColumn['name'], + 'type' => (string)$discrColumn['type'], + 'length' => (string)$discrColumn['length'] + )); + } else { + $metadata->setDiscriminatorColumn(array('name' => 'dtype', 'type' => 'string', 'length' => 255)); + } + + // Evaluate + if (isset($xmlRoot->{'discriminator-map'})) { + $map = array(); + foreach ($xmlRoot->{'discriminator-map'}->{'discriminator-mapping'} AS $discrMapElement) { + $map[(string)$discrMapElement['value']] = (string)$discrMapElement['class']; + } + $metadata->setDiscriminatorMap($map); + } + } + } + + + // Evaluate + if (isset($xmlRoot['change-tracking-policy'])) { + $metadata->setChangeTrackingPolicy(constant('Doctrine\ORM\Mapping\ClassMetadata::CHANGETRACKING_' + . strtoupper((string)$xmlRoot['change-tracking-policy']))); + } + + // Evaluate + if (isset($xmlRoot->indexes)) { + $metadata->table['indexes'] = array(); + foreach ($xmlRoot->indexes->index as $index) { + $columns = explode(',', (string)$index['columns']); + + if (isset($index['name'])) { + $metadata->table['indexes'][(string)$index['name']] = array( + 'columns' => $columns + ); + } else { + $metadata->table['indexes'][] = array( + 'columns' => $columns + ); + } + } + } + + // Evaluate + if (isset($xmlRoot->{'unique-constraints'})) { + $metadata->table['uniqueConstraints'] = array(); + foreach ($xmlRoot->{'unique-constraints'}->{'unique-constraint'} as $unique) { + $columns = explode(',', (string)$unique['columns']); + + if (isset($unique['name'])) { + $metadata->table['uniqueConstraints'][(string)$unique['name']] = array( + 'columns' => $columns + ); + } else { + $metadata->table['uniqueConstraints'][] = array( + 'columns' => $columns + ); + } + } + } + + // Evaluate mappings + if (isset($xmlRoot->field)) { + foreach ($xmlRoot->field as $fieldMapping) { + $mapping = array( + 'fieldName' => (string)$fieldMapping['name'], + ); + + if (isset($fieldMapping['type'])) { + $mapping['type'] = (string)$fieldMapping['type']; + } + + if (isset($fieldMapping['column'])) { + $mapping['columnName'] = (string)$fieldMapping['column']; + } + + if (isset($fieldMapping['length'])) { + $mapping['length'] = (int)$fieldMapping['length']; + } + + if (isset($fieldMapping['precision'])) { + $mapping['precision'] = (int)$fieldMapping['precision']; + } + + if (isset($fieldMapping['scale'])) { + $mapping['scale'] = (int)$fieldMapping['scale']; + } + + if (isset($fieldMapping['unique'])) { + $mapping['unique'] = ((string)$fieldMapping['unique'] == "false") ? false : true; + } + + if (isset($fieldMapping['options'])) { + $mapping['options'] = (array)$fieldMapping['options']; + } + + if (isset($fieldMapping['nullable'])) { + $mapping['nullable'] = ((string)$fieldMapping['nullable'] == "false") ? false : true; + } + + if (isset($fieldMapping['version']) && $fieldMapping['version']) { + $metadata->setVersionMapping($mapping); + } + + if (isset($fieldMapping['column-definition'])) { + $mapping['columnDefinition'] = (string)$fieldMapping['column-definition']; + } + + $metadata->mapField($mapping); + } + } + + // Evaluate mappings + $associationIds = array(); + foreach ($xmlRoot->id as $idElement) { + if ((bool)$idElement['association-key'] == true) { + $associationIds[(string)$idElement['name']] = true; + continue; + } + + $mapping = array( + 'id' => true, + 'fieldName' => (string)$idElement['name'] + ); + + if (isset($idElement['type'])) { + $mapping['type'] = (string)$idElement['type']; + } + + if (isset($idElement['column'])) { + $mapping['columnName'] = (string)$idElement['column']; + } + + if (isset($idElement['column-definition'])) { + $mapping['columnDefinition'] = (string)$idElement['column-definition']; + } + + $metadata->mapField($mapping); + + if (isset($idElement->generator)) { + $strategy = isset($idElement->generator['strategy']) ? + (string)$idElement->generator['strategy'] : 'AUTO'; + $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' + . $strategy)); + } + + // Check for SequenceGenerator/TableGenerator definition + if (isset($idElement->{'sequence-generator'})) { + $seqGenerator = $idElement->{'sequence-generator'}; + $metadata->setSequenceGeneratorDefinition(array( + 'sequenceName' => (string)$seqGenerator['sequence-name'], + 'allocationSize' => (string)$seqGenerator['allocation-size'], + 'initialValue' => (string)$seqGenerator['initial-value'] + )); + } else if (isset($idElement->{'table-generator'})) { + throw MappingException::tableIdGeneratorNotImplemented($className); + } + } + + // Evaluate mappings + if (isset($xmlRoot->{'one-to-one'})) { + foreach ($xmlRoot->{'one-to-one'} as $oneToOneElement) { + $mapping = array( + 'fieldName' => (string)$oneToOneElement['field'], + 'targetEntity' => (string)$oneToOneElement['target-entity'] + ); + + if (isset($associationIds[$mapping['fieldName']])) { + $mapping['id'] = true; + } + + if (isset($oneToOneElement['fetch'])) { + $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . (string)$oneToOneElement['fetch']); + } + + if (isset($oneToOneElement['mapped-by'])) { + $mapping['mappedBy'] = (string)$oneToOneElement['mapped-by']; + } else { + if (isset($oneToOneElement['inversed-by'])) { + $mapping['inversedBy'] = (string)$oneToOneElement['inversed-by']; + } + $joinColumns = array(); + + if (isset($oneToOneElement->{'join-column'})) { + $joinColumns[] = $this->_getJoinColumnMapping($oneToOneElement->{'join-column'}); + } else if (isset($oneToOneElement->{'join-columns'})) { + foreach ($oneToOneElement->{'join-columns'}->{'join-column'} as $joinColumnElement) { + $joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement); + } + } + + $mapping['joinColumns'] = $joinColumns; + } + + if (isset($oneToOneElement->cascade)) { + $mapping['cascade'] = $this->_getCascadeMappings($oneToOneElement->cascade); + } + + if (isset($oneToOneElement['orphan-removal'])) { + $mapping['orphanRemoval'] = (bool)$oneToOneElement['orphan-removal']; + } + + $metadata->mapOneToOne($mapping); + } + } + + // Evaluate mappings + if (isset($xmlRoot->{'one-to-many'})) { + foreach ($xmlRoot->{'one-to-many'} as $oneToManyElement) { + $mapping = array( + 'fieldName' => (string)$oneToManyElement['field'], + 'targetEntity' => (string)$oneToManyElement['target-entity'], + 'mappedBy' => (string)$oneToManyElement['mapped-by'] + ); + + if (isset($oneToManyElement['fetch'])) { + $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . (string)$oneToManyElement['fetch']); + } + + if (isset($oneToManyElement->cascade)) { + $mapping['cascade'] = $this->_getCascadeMappings($oneToManyElement->cascade); + } + + if (isset($oneToManyElement['orphan-removal'])) { + $mapping['orphanRemoval'] = (bool)$oneToManyElement['orphan-removal']; + } + + if (isset($oneToManyElement->{'order-by'})) { + $orderBy = array(); + foreach ($oneToManyElement->{'order-by'}->{'order-by-field'} AS $orderByField) { + $orderBy[(string)$orderByField['name']] = (string)$orderByField['direction']; + } + $mapping['orderBy'] = $orderBy; + } + + if (isset($oneToManyElement['index-by'])) { + $mapping['indexBy'] = (string)$oneToManyElement['index-by']; + } else if (isset($oneToManyElement->{'index-by'})) { + throw new \InvalidArgumentException(" is not a valid tag"); + } + + $metadata->mapOneToMany($mapping); + } + } + + // Evaluate mappings + if (isset($xmlRoot->{'many-to-one'})) { + foreach ($xmlRoot->{'many-to-one'} as $manyToOneElement) { + $mapping = array( + 'fieldName' => (string)$manyToOneElement['field'], + 'targetEntity' => (string)$manyToOneElement['target-entity'] + ); + + if (isset($associationIds[$mapping['fieldName']])) { + $mapping['id'] = true; + } + + if (isset($manyToOneElement['fetch'])) { + $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . (string)$manyToOneElement['fetch']); + } + + if (isset($manyToOneElement['inversed-by'])) { + $mapping['inversedBy'] = (string)$manyToOneElement['inversed-by']; + } + + $joinColumns = array(); + + if (isset($manyToOneElement->{'join-column'})) { + $joinColumns[] = $this->_getJoinColumnMapping($manyToOneElement->{'join-column'}); + } else if (isset($manyToOneElement->{'join-columns'})) { + foreach ($manyToOneElement->{'join-columns'}->{'join-column'} as $joinColumnElement) { + $joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement); + } + } + + $mapping['joinColumns'] = $joinColumns; + + if (isset($manyToOneElement->cascade)) { + $mapping['cascade'] = $this->_getCascadeMappings($manyToOneElement->cascade); + } + + $metadata->mapManyToOne($mapping); + } + } + + // Evaluate mappings + if (isset($xmlRoot->{'many-to-many'})) { + foreach ($xmlRoot->{'many-to-many'} as $manyToManyElement) { + $mapping = array( + 'fieldName' => (string)$manyToManyElement['field'], + 'targetEntity' => (string)$manyToManyElement['target-entity'] + ); + + if (isset($manyToManyElement['fetch'])) { + $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . (string)$manyToManyElement['fetch']); + } + + if (isset($manyToManyElement['orphan-removal'])) { + $mapping['orphanRemoval'] = (bool)$manyToManyElement['orphan-removal']; + } + + if (isset($manyToManyElement['mapped-by'])) { + $mapping['mappedBy'] = (string)$manyToManyElement['mapped-by']; + } else if (isset($manyToManyElement->{'join-table'})) { + if (isset($manyToManyElement['inversed-by'])) { + $mapping['inversedBy'] = (string)$manyToManyElement['inversed-by']; + } + + $joinTableElement = $manyToManyElement->{'join-table'}; + $joinTable = array( + 'name' => (string)$joinTableElement['name'] + ); + + if (isset($joinTableElement['schema'])) { + $joinTable['schema'] = (string)$joinTableElement['schema']; + } + + foreach ($joinTableElement->{'join-columns'}->{'join-column'} as $joinColumnElement) { + $joinTable['joinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement); + } + + foreach ($joinTableElement->{'inverse-join-columns'}->{'join-column'} as $joinColumnElement) { + $joinTable['inverseJoinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement); + } + + $mapping['joinTable'] = $joinTable; + } + + if (isset($manyToManyElement->cascade)) { + $mapping['cascade'] = $this->_getCascadeMappings($manyToManyElement->cascade); + } + + if (isset($manyToManyElement->{'order-by'})) { + $orderBy = array(); + foreach ($manyToManyElement->{'order-by'}->{'order-by-field'} AS $orderByField) { + $orderBy[(string)$orderByField['name']] = (string)$orderByField['direction']; + } + $mapping['orderBy'] = $orderBy; + } + + if (isset($manyToManyElement['index-by'])) { + $mapping['indexBy'] = (string)$manyToManyElement['index-by']; + } else if (isset($manyToManyElement->{'index-by'})) { + throw new \InvalidArgumentException(" is not a valid tag"); + } + + $metadata->mapManyToMany($mapping); + } + } + + // Evaluate + if (isset($xmlRoot->{'lifecycle-callbacks'})) { + foreach ($xmlRoot->{'lifecycle-callbacks'}->{'lifecycle-callback'} as $lifecycleCallback) { + $metadata->addLifecycleCallback((string)$lifecycleCallback['method'], constant('Doctrine\ORM\Events::' . (string)$lifecycleCallback['type'])); + } + } + } + + /** + * Constructs a joinColumn mapping array based on the information + * found in the given SimpleXMLElement. + * + * @param $joinColumnElement The XML element. + * @return array The mapping array. + */ + private function _getJoinColumnMapping(SimpleXMLElement $joinColumnElement) + { + $joinColumn = array( + 'name' => (string)$joinColumnElement['name'], + 'referencedColumnName' => (string)$joinColumnElement['referenced-column-name'] + ); + + if (isset($joinColumnElement['unique'])) { + $joinColumn['unique'] = ((string)$joinColumnElement['unique'] == "false") ? false : true; + } + + if (isset($joinColumnElement['nullable'])) { + $joinColumn['nullable'] = ((string)$joinColumnElement['nullable'] == "false") ? false : true; + } + + if (isset($joinColumnElement['on-delete'])) { + $joinColumn['onDelete'] = (string)$joinColumnElement['on-delete']; + } + + if (isset($joinColumnElement['column-definition'])) { + $joinColumn['columnDefinition'] = (string)$joinColumnElement['column-definition']; + } + + return $joinColumn; + } + + /** + * Gathers a list of cascade options found in the given cascade element. + * + * @param $cascadeElement The cascade element. + * @return array The list of cascade options. + */ + private function _getCascadeMappings($cascadeElement) + { + $cascades = array(); + foreach ($cascadeElement->children() as $action) { + // According to the JPA specifications, XML uses "cascade-persist" + // instead of "persist". Here, both variations + // are supported because both YAML and Annotation use "persist" + // and we want to make sure that this driver doesn't need to know + // anything about the supported cascading actions + $cascades[] = str_replace('cascade-', '', $action->getName()); + } + return $cascades; + } + + /** + * {@inheritdoc} + */ + protected function _loadMappingFile($file) + { + $result = array(); + $xmlElement = simplexml_load_file($file); + + if (isset($xmlElement->entity)) { + foreach ($xmlElement->entity as $entityElement) { + $entityName = (string)$entityElement['name']; + $result[$entityName] = $entityElement; + } + } else if (isset($xmlElement->{'mapped-superclass'})) { + foreach ($xmlElement->{'mapped-superclass'} as $mappedSuperClass) { + $className = (string)$mappedSuperClass['name']; + $result[$className] = $mappedSuperClass; + } + } + + return $result; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php new file mode 100644 index 0000000..c8baa2f --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php @@ -0,0 +1,512 @@ +. + */ + +namespace Doctrine\ORM\Mapping\Driver; + +use Doctrine\ORM\Mapping\ClassMetadataInfo, + Doctrine\ORM\Mapping\MappingException; + +/** + * The YamlDriver reads the mapping metadata from yaml schema files. + * + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan H. Wage + * @author Roman Borschel + */ +class YamlDriver extends AbstractFileDriver +{ + /** + * {@inheritdoc} + */ + protected $_fileExtension = '.dcm.yml'; + + /** + * {@inheritdoc} + */ + public function loadMetadataForClass($className, ClassMetadataInfo $metadata) + { + $element = $this->getElement($className); + + if ($element['type'] == 'entity') { + if (isset($element['repositoryClass'])) { + $metadata->setCustomRepositoryClass($element['repositoryClass']); + } + if (isset($element['readOnly']) && $element['readOnly'] == true) { + $metadata->markReadOnly(); + } + } else if ($element['type'] == 'mappedSuperclass') { + $metadata->setCustomRepositoryClass( + isset($element['repositoryClass']) ? $element['repositoryClass'] : null + ); + $metadata->isMappedSuperclass = true; + } else { + throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className); + } + + // Evaluate root level properties + $table = array(); + if (isset($element['table'])) { + $table['name'] = $element['table']; + } + $metadata->setPrimaryTable($table); + + // Evaluate named queries + if (isset($element['namedQueries'])) { + foreach ($element['namedQueries'] as $name => $queryMapping) { + if (is_string($queryMapping)) { + $queryMapping = array('query' => $queryMapping); + } + + if ( ! isset($queryMapping['name'])) { + $queryMapping['name'] = $name; + } + + $metadata->addNamedQuery($queryMapping); + } + } + + /* not implemented specially anyway. use table = schema.table + if (isset($element['schema'])) { + $metadata->table['schema'] = $element['schema']; + }*/ + + if (isset($element['inheritanceType'])) { + $metadata->setInheritanceType(constant('Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . strtoupper($element['inheritanceType']))); + + if ($metadata->inheritanceType != \Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_NONE) { + // Evaluate discriminatorColumn + if (isset($element['discriminatorColumn'])) { + $discrColumn = $element['discriminatorColumn']; + $metadata->setDiscriminatorColumn(array( + 'name' => $discrColumn['name'], + 'type' => $discrColumn['type'], + 'length' => $discrColumn['length'] + )); + } else { + $metadata->setDiscriminatorColumn(array('name' => 'dtype', 'type' => 'string', 'length' => 255)); + } + + // Evaluate discriminatorMap + if (isset($element['discriminatorMap'])) { + $metadata->setDiscriminatorMap($element['discriminatorMap']); + } + } + } + + + // Evaluate changeTrackingPolicy + if (isset($element['changeTrackingPolicy'])) { + $metadata->setChangeTrackingPolicy(constant('Doctrine\ORM\Mapping\ClassMetadata::CHANGETRACKING_' + . strtoupper($element['changeTrackingPolicy']))); + } + + // Evaluate indexes + if (isset($element['indexes'])) { + foreach ($element['indexes'] as $name => $index) { + if ( ! isset($index['name'])) { + $index['name'] = $name; + } + + if (is_string($index['columns'])) { + $columns = explode(',', $index['columns']); + } else { + $columns = $index['columns']; + } + + $metadata->table['indexes'][$index['name']] = array( + 'columns' => $columns + ); + } + } + + // Evaluate uniqueConstraints + if (isset($element['uniqueConstraints'])) { + foreach ($element['uniqueConstraints'] as $name => $unique) { + if ( ! isset($unique['name'])) { + $unique['name'] = $name; + } + + if (is_string($unique['columns'])) { + $columns = explode(',', $unique['columns']); + } else { + $columns = $unique['columns']; + } + + $metadata->table['uniqueConstraints'][$unique['name']] = array( + 'columns' => $columns + ); + } + } + + $associationIds = array(); + if (isset($element['id'])) { + // Evaluate identifier settings + foreach ($element['id'] as $name => $idElement) { + if (isset($idElement['associationKey']) && $idElement['associationKey'] == true) { + $associationIds[$name] = true; + continue; + } + + $mapping = array( + 'id' => true, + 'fieldName' => $name + ); + + if (isset($idElement['type'])) { + $mapping['type'] = $idElement['type']; + } + + if (isset($idElement['column'])) { + $mapping['columnName'] = $idElement['column']; + } + + if (isset($idElement['length'])) { + $mapping['length'] = $idElement['length']; + } + + if (isset($idElement['columnDefinition'])) { + $mapping['columnDefinition'] = $idElement['columnDefinition']; + } + + $metadata->mapField($mapping); + + if (isset($idElement['generator'])) { + $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' + . strtoupper($idElement['generator']['strategy']))); + } + // Check for SequenceGenerator/TableGenerator definition + if (isset($idElement['sequenceGenerator'])) { + $metadata->setSequenceGeneratorDefinition($idElement['sequenceGenerator']); + } else if (isset($idElement['tableGenerator'])) { + throw MappingException::tableIdGeneratorNotImplemented($className); + } + } + } + + // Evaluate fields + if (isset($element['fields'])) { + foreach ($element['fields'] as $name => $fieldMapping) { + + $mapping = array( + 'fieldName' => $name + ); + + if (isset($fieldMapping['type'])) { + $e = explode('(', $fieldMapping['type']); + $fieldMapping['type'] = $e[0]; + $mapping['type'] = $fieldMapping['type']; + + if (isset($e[1])) { + $fieldMapping['length'] = substr($e[1], 0, strlen($e[1]) - 1); + } + } + + if (isset($fieldMapping['id'])) { + $mapping['id'] = true; + if (isset($fieldMapping['generator']['strategy'])) { + $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' + . strtoupper($fieldMapping['generator']['strategy']))); + } + } + if (isset($fieldMapping['column'])) { + $mapping['columnName'] = $fieldMapping['column']; + } + if (isset($fieldMapping['length'])) { + $mapping['length'] = $fieldMapping['length']; + } + if (isset($fieldMapping['precision'])) { + $mapping['precision'] = $fieldMapping['precision']; + } + if (isset($fieldMapping['scale'])) { + $mapping['scale'] = $fieldMapping['scale']; + } + if (isset($fieldMapping['unique'])) { + $mapping['unique'] = (bool)$fieldMapping['unique']; + } + if (isset($fieldMapping['options'])) { + $mapping['options'] = $fieldMapping['options']; + } + if (isset($fieldMapping['nullable'])) { + $mapping['nullable'] = $fieldMapping['nullable']; + } + if (isset($fieldMapping['version']) && $fieldMapping['version']) { + $metadata->setVersionMapping($mapping); + } + if (isset($fieldMapping['columnDefinition'])) { + $mapping['columnDefinition'] = $fieldMapping['columnDefinition']; + } + + $metadata->mapField($mapping); + } + } + + // Evaluate oneToOne relationships + if (isset($element['oneToOne'])) { + foreach ($element['oneToOne'] as $name => $oneToOneElement) { + $mapping = array( + 'fieldName' => $name, + 'targetEntity' => $oneToOneElement['targetEntity'] + ); + + if (isset($associationIds[$mapping['fieldName']])) { + $mapping['id'] = true; + } + + if (isset($oneToOneElement['fetch'])) { + $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToOneElement['fetch']); + } + + if (isset($oneToOneElement['mappedBy'])) { + $mapping['mappedBy'] = $oneToOneElement['mappedBy']; + } else { + if (isset($oneToOneElement['inversedBy'])) { + $mapping['inversedBy'] = $oneToOneElement['inversedBy']; + } + + $joinColumns = array(); + + if (isset($oneToOneElement['joinColumn'])) { + $joinColumns[] = $this->_getJoinColumnMapping($oneToOneElement['joinColumn']); + } else if (isset($oneToOneElement['joinColumns'])) { + foreach ($oneToOneElement['joinColumns'] as $name => $joinColumnElement) { + if (!isset($joinColumnElement['name'])) { + $joinColumnElement['name'] = $name; + } + + $joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement); + } + } + + $mapping['joinColumns'] = $joinColumns; + } + + if (isset($oneToOneElement['cascade'])) { + $mapping['cascade'] = $oneToOneElement['cascade']; + } + + if (isset($oneToOneElement['orphanRemoval'])) { + $mapping['orphanRemoval'] = (bool)$oneToOneElement['orphanRemoval']; + } + + $metadata->mapOneToOne($mapping); + } + } + + // Evaluate oneToMany relationships + if (isset($element['oneToMany'])) { + foreach ($element['oneToMany'] as $name => $oneToManyElement) { + $mapping = array( + 'fieldName' => $name, + 'targetEntity' => $oneToManyElement['targetEntity'], + 'mappedBy' => $oneToManyElement['mappedBy'] + ); + + if (isset($oneToManyElement['fetch'])) { + $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToManyElement['fetch']); + } + + if (isset($oneToManyElement['cascade'])) { + $mapping['cascade'] = $oneToManyElement['cascade']; + } + + if (isset($oneToManyElement['orphanRemoval'])) { + $mapping['orphanRemoval'] = (bool)$oneToManyElement['orphanRemoval']; + } + + if (isset($oneToManyElement['orderBy'])) { + $mapping['orderBy'] = $oneToManyElement['orderBy']; + } + + if (isset($oneToManyElement['indexBy'])) { + $mapping['indexBy'] = $oneToManyElement['indexBy']; + } + + $metadata->mapOneToMany($mapping); + } + } + + // Evaluate manyToOne relationships + if (isset($element['manyToOne'])) { + foreach ($element['manyToOne'] as $name => $manyToOneElement) { + $mapping = array( + 'fieldName' => $name, + 'targetEntity' => $manyToOneElement['targetEntity'] + ); + + if (isset($associationIds[$mapping['fieldName']])) { + $mapping['id'] = true; + } + + if (isset($manyToOneElement['fetch'])) { + $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToOneElement['fetch']); + } + + if (isset($manyToOneElement['inversedBy'])) { + $mapping['inversedBy'] = $manyToOneElement['inversedBy']; + } + + $joinColumns = array(); + + if (isset($manyToOneElement['joinColumn'])) { + $joinColumns[] = $this->_getJoinColumnMapping($manyToOneElement['joinColumn']); + } else if (isset($manyToOneElement['joinColumns'])) { + foreach ($manyToOneElement['joinColumns'] as $name => $joinColumnElement) { + if (!isset($joinColumnElement['name'])) { + $joinColumnElement['name'] = $name; + } + + $joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement); + } + } + + $mapping['joinColumns'] = $joinColumns; + + if (isset($manyToOneElement['cascade'])) { + $mapping['cascade'] = $manyToOneElement['cascade']; + } + + $metadata->mapManyToOne($mapping); + } + } + + // Evaluate manyToMany relationships + if (isset($element['manyToMany'])) { + foreach ($element['manyToMany'] as $name => $manyToManyElement) { + $mapping = array( + 'fieldName' => $name, + 'targetEntity' => $manyToManyElement['targetEntity'] + ); + + if (isset($manyToManyElement['fetch'])) { + $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToManyElement['fetch']); + } + + if (isset($manyToManyElement['mappedBy'])) { + $mapping['mappedBy'] = $manyToManyElement['mappedBy']; + } else if (isset($manyToManyElement['joinTable'])) { + + $joinTableElement = $manyToManyElement['joinTable']; + $joinTable = array( + 'name' => $joinTableElement['name'] + ); + + if (isset($joinTableElement['schema'])) { + $joinTable['schema'] = $joinTableElement['schema']; + } + + foreach ($joinTableElement['joinColumns'] as $name => $joinColumnElement) { + if (!isset($joinColumnElement['name'])) { + $joinColumnElement['name'] = $name; + } + + $joinTable['joinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement); + } + + foreach ($joinTableElement['inverseJoinColumns'] as $name => $joinColumnElement) { + if (!isset($joinColumnElement['name'])) { + $joinColumnElement['name'] = $name; + } + + $joinTable['inverseJoinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement); + } + + $mapping['joinTable'] = $joinTable; + } + + if (isset($manyToManyElement['inversedBy'])) { + $mapping['inversedBy'] = $manyToManyElement['inversedBy']; + } + + if (isset($manyToManyElement['cascade'])) { + $mapping['cascade'] = $manyToManyElement['cascade']; + } + + if (isset($manyToManyElement['orderBy'])) { + $mapping['orderBy'] = $manyToManyElement['orderBy']; + } + + if (isset($manyToManyElement['indexBy'])) { + $mapping['indexBy'] = $manyToManyElement['indexBy']; + } + + if (isset($manyToManyElement['orphanRemoval'])) { + $mapping['orphanRemoval'] = (bool)$manyToManyElement['orphanRemoval']; + } + + $metadata->mapManyToMany($mapping); + } + } + + // Evaluate lifeCycleCallbacks + if (isset($element['lifecycleCallbacks'])) { + foreach ($element['lifecycleCallbacks'] as $type => $methods) { + foreach ($methods as $method) { + $metadata->addLifecycleCallback($method, constant('Doctrine\ORM\Events::' . $type)); + } + } + } + } + + /** + * Constructs a joinColumn mapping array based on the information + * found in the given join column element. + * + * @param $joinColumnElement The array join column element + * @return array The mapping array. + */ + private function _getJoinColumnMapping($joinColumnElement) + { + $joinColumn = array( + 'name' => $joinColumnElement['name'], + 'referencedColumnName' => $joinColumnElement['referencedColumnName'] + ); + + if (isset($joinColumnElement['fieldName'])) { + $joinColumn['fieldName'] = (string) $joinColumnElement['fieldName']; + } + + if (isset($joinColumnElement['unique'])) { + $joinColumn['unique'] = (bool) $joinColumnElement['unique']; + } + + if (isset($joinColumnElement['nullable'])) { + $joinColumn['nullable'] = (bool) $joinColumnElement['nullable']; + } + + if (isset($joinColumnElement['onDelete'])) { + $joinColumn['onDelete'] = $joinColumnElement['onDelete']; + } + + if (isset($joinColumnElement['columnDefinition'])) { + $joinColumn['columnDefinition'] = $joinColumnElement['columnDefinition']; + } + + return $joinColumn; + } + + /** + * {@inheritdoc} + */ + protected function _loadMappingFile($file) + { + return \Symfony\Component\Yaml\Yaml::parse($file); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ElementCollection.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ElementCollection.php new file mode 100644 index 0000000..f127174 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ElementCollection.php @@ -0,0 +1,31 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("ALL") + * @todo check available targets + */ +final class ElementCollection implements Annotation +{ + /** @var string */ + public $tableName; +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Entity.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Entity.php new file mode 100644 index 0000000..075a5ec --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Entity.php @@ -0,0 +1,32 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("CLASS") + */ +final class Entity implements Annotation +{ + /** @var string */ + public $repositoryClass; + /** @var boolean */ + public $readOnly = false; +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/GeneratedValue.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/GeneratedValue.php new file mode 100644 index 0000000..8558d21 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/GeneratedValue.php @@ -0,0 +1,30 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("PROPERTY") + */ +final class GeneratedValue implements Annotation +{ + /** @var string */ + public $strategy = 'AUTO'; +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/HasLifecycleCallbacks.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/HasLifecycleCallbacks.php new file mode 100644 index 0000000..a65fbb5 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/HasLifecycleCallbacks.php @@ -0,0 +1,28 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("CLASS") + */ +final class HasLifecycleCallbacks implements Annotation +{ +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Id.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Id.php new file mode 100644 index 0000000..a670e3d --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Id.php @@ -0,0 +1,28 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("PROPERTY") + */ +final class Id implements Annotation +{ +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Index.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Index.php new file mode 100644 index 0000000..e0a2db3 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Index.php @@ -0,0 +1,32 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("ANNOTATION") + */ +final class Index implements Annotation +{ + /** @var string */ + public $name; + /** @var array */ + public $columns; +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/InheritanceType.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/InheritanceType.php new file mode 100644 index 0000000..009f3ab --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/InheritanceType.php @@ -0,0 +1,30 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("CLASS") + */ +final class InheritanceType implements Annotation +{ + /** @var string */ + public $value; +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/JoinColumn.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/JoinColumn.php new file mode 100644 index 0000000..bf5c51d --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/JoinColumn.php @@ -0,0 +1,42 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target({"PROPERTY","ANNOTATION"}) + */ +final class JoinColumn implements Annotation +{ + /** @var string */ + public $name; + /** @var string */ + public $referencedColumnName = 'id'; + /** @var boolean */ + public $unique = false; + /** @var boolean */ + public $nullable = true; + /** @var mixed */ + public $onDelete; + /** @var string */ + public $columnDefinition; + /** @var string */ + public $fieldName; // field name used in non-object hydration (array/scalar) +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/JoinColumns.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/JoinColumns.php new file mode 100644 index 0000000..525105f --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/JoinColumns.php @@ -0,0 +1,30 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("PROPERTY") + */ +final class JoinColumns implements Annotation +{ + /** @var array<\Doctrine\ORM\Mapping\JoinColumn> */ + public $value; +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/JoinTable.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/JoinTable.php new file mode 100644 index 0000000..9ff9d45 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/JoinTable.php @@ -0,0 +1,36 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("PROPERTY") + */ +final class JoinTable implements Annotation +{ + /** @var string */ + public $name; + /** @var string */ + public $schema; + /** @var array<\Doctrine\ORM\Mapping\JoinColumn> */ + public $joinColumns = array(); + /** @var array<\Doctrine\ORM\Mapping\JoinColumn> */ + public $inverseJoinColumns = array(); +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ManyToMany.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ManyToMany.php new file mode 100644 index 0000000..28f41aa --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ManyToMany.php @@ -0,0 +1,42 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("PROPERTY") + */ +final class ManyToMany implements Annotation +{ + /** @var string */ + public $targetEntity; + /** @var string */ + public $mappedBy; + /** @var string */ + public $inversedBy; + /** @var array */ + public $cascade; + /** @var string */ + public $fetch = 'LAZY'; + /** @var boolean */ + public $orphanRemoval = false; + /** @var string */ + public $indexBy; +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ManyToOne.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ManyToOne.php new file mode 100644 index 0000000..1bc8376 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ManyToOne.php @@ -0,0 +1,36 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("PROPERTY") + */ +final class ManyToOne implements Annotation +{ + /** @var string */ + public $targetEntity; + /** @var array */ + public $cascade; + /** @var string */ + public $fetch = 'LAZY'; + /** @var string */ + public $inversedBy; +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/MappedSuperclass.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/MappedSuperclass.php new file mode 100644 index 0000000..639d216 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/MappedSuperclass.php @@ -0,0 +1,30 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("CLASS") + */ +final class MappedSuperclass implements Annotation +{ + /** @var string */ + public $repositoryClass; +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/MappingException.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/MappingException.php new file mode 100644 index 0000000..c71c2e9 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/MappingException.php @@ -0,0 +1,332 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * A MappingException indicates that something is wrong with the mapping setup. + * + * @since 2.0 + */ +class MappingException extends \Doctrine\ORM\ORMException +{ + public static function pathRequired() + { + return new self("Specifying the paths to your entities is required ". + "in the AnnotationDriver to retrieve all class names."); + } + + public static function identifierRequired($entityName) + { + return new self("No identifier/primary key specified for Entity '$entityName'." + . " Every Entity must have an identifier/primary key."); + } + + public static function invalidInheritanceType($entityName, $type) + { + return new self("The inheritance type '$type' specified for '$entityName' does not exist."); + } + + public static function generatorNotAllowedWithCompositeId() + { + return new self("Id generators can't be used with a composite id."); + } + + public static function missingFieldName($entity) + { + return new self("The field or association mapping misses the 'fieldName' attribute in entity '$entity'."); + } + + public static function missingTargetEntity($fieldName) + { + return new self("The association mapping '$fieldName' misses the 'targetEntity' attribute."); + } + + public static function missingSourceEntity($fieldName) + { + return new self("The association mapping '$fieldName' misses the 'sourceEntity' attribute."); + } + + public static function mappingFileNotFound($entityName, $fileName) + { + return new self("No mapping file found named '$fileName' for class '$entityName'."); + } + + public static function invalidMappingFile($entityName, $fileName) + { + return new self("Invalid mapping file '$fileName' for class '$entityName'."); + } + + public static function mappingNotFound($className, $fieldName) + { + return new self("No mapping found for field '$fieldName' on class '$className'."); + } + + public static function queryNotFound($className, $queryName) + { + return new self("No query found named '$queryName' on class '$className'."); + } + + public static function oneToManyRequiresMappedBy($fieldName) + { + return new self("OneToMany mapping on field '$fieldName' requires the 'mappedBy' attribute."); + } + + public static function joinTableRequired($fieldName) + { + return new self("The mapping of field '$fieldName' requires an the 'joinTable' attribute."); + } + + /** + * Called if a required option was not found but is required + * + * @param string $field which field cannot be processed? + * @param string $expectedOption which option is required + * @param string $hint Can optionally be used to supply a tip for common mistakes, + * e.g. "Did you think of the plural s?" + * @return MappingException + */ + static function missingRequiredOption($field, $expectedOption, $hint = '') + { + $message = "The mapping of field '{$field}' is invalid: The option '{$expectedOption}' is required."; + + if ( ! empty($hint)) { + $message .= ' (Hint: ' . $hint . ')'; + } + + return new self($message); + } + + /** + * Generic exception for invalid mappings. + * + * @param string $fieldName + */ + public static function invalidMapping($fieldName) + { + return new self("The mapping of field '$fieldName' is invalid."); + } + + /** + * Exception for reflection exceptions - adds the entity name, + * because there might be long classnames that will be shortened + * within the stacktrace + * + * @param string $entity The entity's name + * @param \ReflectionException $previousException + */ + public static function reflectionFailure($entity, \ReflectionException $previousException) + { + return new self('An error occurred in ' . $entity, 0, $previousException); + } + + public static function joinColumnMustPointToMappedField($className, $joinColumn) + { + return new self('The column ' . $joinColumn . ' must be mapped to a field in class ' + . $className . ' since it is referenced by a join column of another class.'); + } + + public static function classIsNotAValidEntityOrMappedSuperClass($className) + { + return new self('Class '.$className.' is not a valid entity or mapped super class.'); + } + + public static function propertyTypeIsRequired($className, $propertyName) + { + return new self("The attribute 'type' is required for the column description of property ".$className."::\$".$propertyName."."); + } + + public static function tableIdGeneratorNotImplemented($className) + { + return new self("TableIdGenerator is not yet implemented for use with class ".$className); + } + + /** + * + * @param string $entity The entity's name + * @param string $fieldName The name of the field that was already declared + */ + public static function duplicateFieldMapping($entity, $fieldName) { + return new self('Property "'.$fieldName.'" in "'.$entity.'" was already declared, but it must be declared only once'); + } + + public static function duplicateAssociationMapping($entity, $fieldName) { + return new self('Property "'.$fieldName.'" in "'.$entity.'" was already declared, but it must be declared only once'); + } + + public static function duplicateQueryMapping($entity, $queryName) { + return new self('Query named "'.$queryName.'" in "'.$entity.'" was already declared, but it must be declared only once'); + } + + public static function singleIdNotAllowedOnCompositePrimaryKey($entity) { + return new self('Single id is not allowed on composite primary key in entity '.$entity); + } + + public static function unsupportedOptimisticLockingType($entity, $fieldName, $unsupportedType) { + return new self('Locking type "'.$unsupportedType.'" (specified in "'.$entity.'", field "'.$fieldName.'") ' + .'is not supported by Doctrine.' + ); + } + + public static function fileMappingDriversRequireConfiguredDirectoryPath($path = null) + { + if ( ! empty($path)) { + $path = '[' . $path . ']'; + } + + return new self( + 'File mapping drivers must have a valid directory path, ' . + 'however the given path ' . $path . ' seems to be incorrect!' + ); + } + + /** + * Throws an exception that indicates that a class used in a discriminator map does not exist. + * An example would be an outdated (maybe renamed) classname. + * + * @param string $className The class that could not be found + * @param string $owningClass The class that declares the discriminator map. + * @return self + */ + public static function invalidClassInDiscriminatorMap($className, $owningClass) { + return new self( + "Entity class '$className' used in the discriminator map of class '$owningClass' ". + "does not exist." + ); + } + + public static function missingDiscriminatorMap($className) + { + return new self("Entity class '$className' is using inheritance but no discriminator map was defined."); + } + + public static function missingDiscriminatorColumn($className) + { + return new self("Entity class '$className' is using inheritance but no discriminator column was defined."); + } + + public static function invalidDiscriminatorColumnType($className, $type) + { + return new self("Discriminator column type on entity class '$className' is not allowed to be '$type'. 'string' or 'integer' type variables are suggested!"); + } + + public static function cannotVersionIdField($className, $fieldName) + { + return new self("Setting Id field '$fieldName' as versionale in entity class '$className' is not supported."); + } + + public static function sqlConversionNotAllowedForIdentifiers($className, $fieldName, $type) + { + return new self("It is not possible to set id field '$fieldName' to type '$type' in entity class '$className'. The type '$type' requires conversion SQL which is not allowed for identifiers."); + } + + /** + * @param string $className + * @param string $columnName + * @return self + */ + public static function duplicateColumnName($className, $columnName) + { + return new self("Duplicate definition of column '".$columnName."' on entity '".$className."' in a field or discriminator column mapping."); + } + + public static function illegalToManyAssocationOnMappedSuperclass($className, $field) + { + return new self("It is illegal to put an inverse side one-to-many or many-to-many association on mapped superclass '".$className."#".$field."'."); + } + + /** + * @param string $className + * @param string $targetEntity + * @param string $targetField + * @return self + */ + public static function cannotMapCompositePrimaryKeyEntitiesAsForeignId($className, $targetEntity, $targetField) + { + return new self("It is not possible to map entity '".$className."' with a composite primary key ". + "as part of the primary key of another entity '".$targetEntity."#".$targetField."'."); + } + + public static function noSingleAssociationJoinColumnFound($className, $field) + { + return new self("'$className#$field' is not an association with a single join column."); + } + + public static function noFieldNameFoundForColumn($className, $column) + { + return new self("Cannot find a field on '$className' that is mapped to column '$column'. Either the ". + "field does not exist or an association exists but it has multiple join columns."); + } + + public static function illegalOrphanRemovalOnIdentifierAssociation($className, $field) + { + return new self("The orphan removal option is not allowed on an association that is ". + "part of the identifier in '$className#$field'."); + } + + public static function illegalOrphanRemoval($className, $field) + { + return new self("Orphan removal is only allowed on one-to-one and one-to-many ". + "associations, but " . $className."#" .$field . " is not."); + } + + public static function illegalInverseIdentifierAssocation($className, $field) + { + return new self("An inverse association is not allowed to be identifier in '$className#$field'."); + } + + public static function illegalToManyIdentifierAssoaction($className, $field) + { + return new self("Many-to-many or one-to-many associations are not allowed to be identifier in '$className#$field'."); + } + + public static function noInheritanceOnMappedSuperClass($className) + { + return new self("Its not supported to define inheritance information on a mapped superclass '" . $className . "'."); + } + + public static function mappedClassNotPartOfDiscriminatorMap($className, $rootClassName) + { + return new self( + "Entity '" . $className . "' has to be part of the discriminator map of '" . $rootClassName . "' " . + "to be properly mapped in the inheritance hierachy. Alternatively you can make '".$className."' an abstract class " . + "to avoid this exception from occuring." + ); + } + + public static function lifecycleCallbackMethodNotFound($className, $methodName) + { + return new self("Entity '" . $className . "' has no method '" . $methodName . "' to be registered as lifecycle callback."); + } + + public static function invalidFetchMode($className, $annotation) + { + return new self("Entity '" . $className . "' has a mapping with invalid fetch mode '" . $annotation . "'"); + } + + public static function compositeKeyAssignedIdGeneratorRequired($className) + { + return new self("Entity '". $className . "' has a composite identifier but uses an ID generator other than manually assigning (Identity, Sequence). This is not supported."); + } + + public static function invalidTargetEntityClass($targetEntity, $sourceEntity, $associationName) + { + return new self("The target-entity " . $targetEntity . " cannot be found in '" . $sourceEntity."#".$associationName."'."); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/NamedQueries.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/NamedQueries.php new file mode 100644 index 0000000..1ab2bf2 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/NamedQueries.php @@ -0,0 +1,30 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("CLASS") + */ +final class NamedQueries implements Annotation +{ + /** @var array<\Doctrine\ORM\Mapping\NamedQuery> */ + public $value; +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/NamedQuery.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/NamedQuery.php new file mode 100644 index 0000000..656a4ea --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/NamedQuery.php @@ -0,0 +1,32 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("ANNOTATION") + */ +final class NamedQuery implements Annotation +{ + /** @var string */ + public $name; + /** @var string */ + public $query; +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/OneToMany.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/OneToMany.php new file mode 100644 index 0000000..b4d8ad3 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/OneToMany.php @@ -0,0 +1,40 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("PROPERTY") + */ +final class OneToMany implements Annotation +{ + /** @var string */ + public $mappedBy; + /** @var string */ + public $targetEntity; + /** @var array */ + public $cascade; + /** @var string */ + public $fetch = 'LAZY'; + /** @var boolean */ + public $orphanRemoval = false; + /** @var string */ + public $indexBy; +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/OneToOne.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/OneToOne.php new file mode 100644 index 0000000..4baa121 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/OneToOne.php @@ -0,0 +1,40 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("PROPERTY") + */ +final class OneToOne implements Annotation +{ + /** @var string */ + public $targetEntity; + /** @var string */ + public $mappedBy; + /** @var string */ + public $inversedBy; + /** @var array */ + public $cascade; + /** @var string */ + public $fetch = 'LAZY'; + /** @var boolean */ + public $orphanRemoval = false; +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/OrderBy.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/OrderBy.php new file mode 100644 index 0000000..c28f110 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/OrderBy.php @@ -0,0 +1,30 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("PROPERTY") + */ +final class OrderBy implements Annotation +{ + /** @var array */ + public $value; +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PostLoad.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PostLoad.php new file mode 100644 index 0000000..169bb49 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PostLoad.php @@ -0,0 +1,28 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("METHOD") + */ +final class PostLoad implements Annotation +{ +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PostPersist.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PostPersist.php new file mode 100644 index 0000000..5b5baed --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PostPersist.php @@ -0,0 +1,28 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("METHOD") + */ +final class PostPersist implements Annotation +{ +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PostRemove.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PostRemove.php new file mode 100644 index 0000000..4798e26 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PostRemove.php @@ -0,0 +1,28 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("METHOD") + */ +final class PostRemove implements Annotation +{ +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PostUpdate.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PostUpdate.php new file mode 100644 index 0000000..f7e7539 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PostUpdate.php @@ -0,0 +1,28 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("METHOD") + */ +final class PostUpdate implements Annotation +{ +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PreFlush.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PreFlush.php new file mode 100644 index 0000000..f5eb086 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PreFlush.php @@ -0,0 +1,28 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("METHOD") + */ +final class PreFlush implements Annotation +{ +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PrePersist.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PrePersist.php new file mode 100644 index 0000000..c382700 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PrePersist.php @@ -0,0 +1,28 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("METHOD") + */ +final class PrePersist implements Annotation +{ +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PreRemove.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PreRemove.php new file mode 100644 index 0000000..adcb837 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PreRemove.php @@ -0,0 +1,28 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("METHOD") + */ +final class PreRemove implements Annotation +{ +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PreUpdate.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PreUpdate.php new file mode 100644 index 0000000..2afd381 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/PreUpdate.php @@ -0,0 +1,28 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("METHOD") + */ +final class PreUpdate implements Annotation +{ +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/SequenceGenerator.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/SequenceGenerator.php new file mode 100644 index 0000000..be3d700 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/SequenceGenerator.php @@ -0,0 +1,34 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("PROPERTY") + */ +final class SequenceGenerator implements Annotation +{ + /** @var string */ + public $sequenceName; + /** @var integer */ + public $allocationSize = 1; + /** @var integer */ + public $initialValue = 1; +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Table.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Table.php new file mode 100644 index 0000000..41db294 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Table.php @@ -0,0 +1,36 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("CLASS") + */ +final class Table implements Annotation +{ + /** @var string */ + public $name; + /** @var string */ + public $schema; + /** @var array<\Doctrine\ORM\Mapping\Index> */ + public $indexes; + /** @var array<\Doctrine\ORM\Mapping\UniqueConstraint> */ + public $uniqueConstraints; +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/UniqueConstraint.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/UniqueConstraint.php new file mode 100644 index 0000000..db9f8fd --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/UniqueConstraint.php @@ -0,0 +1,32 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("ANNOTATION") + */ +final class UniqueConstraint implements Annotation +{ + /** @var string */ + public $name; + /** @var array */ + public $columns; +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Version.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Version.php new file mode 100644 index 0000000..313e751 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Version.php @@ -0,0 +1,28 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @Annotation + * @Target("PROPERTY") + */ +final class Version implements Annotation +{ +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/NativeQuery.php b/vendor/doctrine/orm/lib/Doctrine/ORM/NativeQuery.php new file mode 100644 index 0000000..2ab8744 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/NativeQuery.php @@ -0,0 +1,76 @@ +. + */ + +namespace Doctrine\ORM; + +/** + * Represents a native SQL query. + * + * @author Roman Borschel + * @since 2.0 + */ +final class NativeQuery extends AbstractQuery +{ + private $_sql; + + /** + * Sets the SQL of the query. + * + * @param string $sql + * @return NativeQuery This query instance. + */ + public function setSQL($sql) + { + $this->_sql = $sql; + + return $this; + } + + /** + * Gets the SQL query. + * + * @return mixed The built SQL query or an array of all SQL queries. + * @override + */ + public function getSQL() + { + return $this->_sql; + } + + /** + * {@inheritdoc} + */ + protected function _doExecute() + { + $params = $this->_params; + $types = $this->_paramTypes; + + if ($params && is_int(key($params))) { + ksort($params); + ksort($types); + + $params = array_values($params); + $types = array_values($types); + } + + return $this->_em->getConnection()->executeQuery( + $this->_sql, $params, $types, $this->_queryCacheProfile + ); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/NoResultException.php b/vendor/doctrine/orm/lib/Doctrine/ORM/NoResultException.php new file mode 100644 index 0000000..eb31f7c --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/NoResultException.php @@ -0,0 +1,34 @@ +. + */ + +namespace Doctrine\ORM; + +/** + * Exception thrown when an ORM query unexpectedly does not return any results. + * + * @author robo + * @since 2.0 + */ +class NoResultException extends ORMException +{ + public function __construct() + { + parent::__construct('No result was found for query although at least one row was expected.'); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/NonUniqueResultException.php b/vendor/doctrine/orm/lib/Doctrine/ORM/NonUniqueResultException.php new file mode 100644 index 0000000..1a3a8b7 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/NonUniqueResultException.php @@ -0,0 +1,28 @@ +. + */ + +namespace Doctrine\ORM; + +/** + * Exception thrown when an ORM query unexpectedly returns more than one result. + * + * @author robo + * @since 2.0 + */ +class NonUniqueResultException extends ORMException {} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/ORMException.php b/vendor/doctrine/orm/lib/Doctrine/ORM/ORMException.php new file mode 100644 index 0000000..bd16839 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/ORMException.php @@ -0,0 +1,152 @@ +. + */ + +namespace Doctrine\ORM; + +use Exception; + +/** + * Base exception class for all ORM exceptions. + * + * @author Roman Borschel + * @since 2.0 + */ +class ORMException extends Exception +{ + public static function missingMappingDriverImpl() + { + return new self("It's a requirement to specify a Metadata Driver and pass it ". + "to Doctrine\ORM\Configuration::setMetadataDriverImpl()."); + } + + public static function entityMissingForeignAssignedId($entity, $relatedEntity) + { + return new self( + "Entity of type " . get_class($entity) . " has identity through a foreign entity " . get_class($relatedEntity) . ", " . + "however this entity has no identity itself. You have to call EntityManager#persist() on the related entity " . + "and make sure that an identifier was generated before trying to persist '" . get_class($entity) . "'. In case " . + "of Post Insert ID Generation (such as MySQL Auto-Increment or PostgreSQL SERIAL) this means you have to call " . + "EntityManager#flush() between both persist operations." + ); + } + + public static function entityMissingAssignedIdForField($entity, $field) + { + return new self("Entity of type " . get_class($entity) . " is missing an assigned ID for field '" . $field . "'. " . + "The identifier generation strategy for this entity requires the ID field to be populated before ". + "EntityManager#persist() is called. If you want automatically generated identifiers instead " . + "you need to adjust the metadata mapping accordingly." + ); + } + public static function unrecognizedField($field) + { + return new self("Unrecognized field: $field"); + } + + /** + * @param string $className + * @param string $field + */ + public static function invalidOrientation($className, $field) + { + return new self("Invalid order by orientation specified for " . $className . "#" . $field); + } + + public static function invalidFlushMode($mode) + { + return new self("'$mode' is an invalid flush mode."); + } + + public static function entityManagerClosed() + { + return new self("The EntityManager is closed."); + } + + public static function invalidHydrationMode($mode) + { + return new self("'$mode' is an invalid hydration mode."); + } + + public static function mismatchedEventManager() + { + return new self("Cannot use different EventManager instances for EntityManager and Connection."); + } + + public static function findByRequiresParameter($methodName) + { + return new self("You need to pass a parameter to '".$methodName."'"); + } + + public static function invalidFindByCall($entityName, $fieldName, $method) + { + return new self( + "Entity '".$entityName."' has no field '".$fieldName."'. ". + "You can therefore not call '".$method."' on the entities' repository" + ); + } + + public static function invalidFindByInverseAssociation($entityName, $associationFieldName) + { + return new self( + "You cannot search for the association field '".$entityName."#".$associationFieldName."', ". + "because it is the inverse side of an association. Find methods only work on owning side associations." + ); + } + + public static function invalidResultCacheDriver() { + return new self("Invalid result cache driver; it must implement \Doctrine\Common\Cache\Cache."); + } + + public static function notSupported() { + return new self("This behaviour is (currently) not supported by Doctrine 2"); + } + + public static function queryCacheNotConfigured() + { + return new self('Query Cache is not configured.'); + } + + public static function metadataCacheNotConfigured() + { + return new self('Class Metadata Cache is not configured.'); + } + + public static function proxyClassesAlwaysRegenerating() + { + return new self('Proxy Classes are always regenerating.'); + } + + public static function unknownEntityNamespace($entityNamespaceAlias) + { + return new self( + "Unknown Entity namespace alias '$entityNamespaceAlias'." + ); + } + + public static function invalidEntityRepository($className) + { + return new self("Invalid repository class '".$className."'. ". + "it must be a Doctrine\ORM\EntityRepository."); + } + + public static function missingIdentifierField($className, $fieldName) + { + return new self("The identifier $fieldName is missing for a query of " . $className); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/ORMInvalidArgumentException.php b/vendor/doctrine/orm/lib/Doctrine/ORM/ORMInvalidArgumentException.php new file mode 100644 index 0000000..878ee4b --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/ORMInvalidArgumentException.php @@ -0,0 +1,107 @@ +. + */ + +namespace Doctrine\ORM; + +/** + * Contains exception messages for all invalid lifecycle state exceptions inside UnitOfWork + * + * @author Benjamin Eberlei + */ +class ORMInvalidArgumentException extends \InvalidArgumentException +{ + static public function scheduleInsertForManagedEntity($entity) + { + return new self("A managed+dirty entity " . self::objToStr($entity) . " can not be scheduled for insertion."); + } + + static public function scheduleInsertForRemovedEntity($entity) + { + return new self("Removed entity " . self::objToStr($entity) . " can not be scheduled for insertion."); + } + + static public function scheduleInsertTwice($entity) + { + return new self("Entity " . self::objToStr($entity) . " can not be scheduled for insertion twice."); + } + + static public function entityWithoutIdentity($className, $entity) + { + throw new self( + "The given entity of type '" . $className . "' (".self::objToStr($entity).") has no identity/no " . + "id values set. It cannot be added to the identity map." + ); + } + + static public function readOnlyRequiresManagedEntity($entity) + { + return new self("Only managed entities can be marked or checked as read only. But " . self::objToStr($entity) . " is not"); + } + + static public function newEntityFoundThroughRelationship(array $assoc, $entry) + { + return new self("A new entity was found through the relationship '" + . $assoc['sourceEntity'] . "#" . $assoc['fieldName'] . "' that was not" + . " configured to cascade persist operations for entity: " . self::objToStr($entry) . "." + . " To solve this issue: Either explicitly call EntityManager#persist()" + . " on this unknown entity or configure cascade persist " + . " this association in the mapping for example @ManyToOne(..,cascade={\"persist\"}). " + . " If you cannot find out which entity causes the problem" + . " implement '" . $assoc['targetEntity'] . "#__toString()' to get a clue."); + } + + static public function detachedEntityFoundThroughRelationship(array $assoc, $entry) + { + throw new self("A detached entity of type " . $assoc['targetEntity'] . " (" . self::objToStr($entry) . ") " + . " was found through the relationship '" . $assoc['sourceEntity'] . "#" . $assoc['fieldName'] . "' " + . "during cascading a persist operation."); + } + + static public function entityNotManaged($entity) + { + throw new self("Entity " . self::objToStr($entity) . " is not managed. An entity is managed if its fetched " . + "from the database or registered as new through EntityManager#persist"); + } + + static public function entityHasNoIdentity($entity, $operation) + { + throw new self("Entity has no identity, therefore " . $operation ." cannot be performed. " . self::objToStr($entity)); + } + + static public function entityIsRemoved($entity, $operation) + { + throw new self("Entity is removed, therefore " . $operation ." cannot be performed. " . self::objToStr($entity)); + } + + static public function detachedEntityCannot($entity, $operation) + { + throw new self("A detached entity was found during " . $operation . " " . self::objToStr($entity)); + } + + /** + * Helper method to show an object as string. + * + * @param object $obj + * @return string + */ + private static function objToStr($obj) + { + return method_exists($obj, '__toString') ? (string)$obj : get_class($obj).'@'.spl_object_hash($obj); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/OptimisticLockException.php b/vendor/doctrine/orm/lib/Doctrine/ORM/OptimisticLockException.php new file mode 100644 index 0000000..9b5147a --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/OptimisticLockException.php @@ -0,0 +1,64 @@ +. + */ + +namespace Doctrine\ORM; + +/** + * An OptimisticLockException is thrown when a version check on an object + * that uses optimistic locking through a version field fails. + * + * @author Roman Borschel + * @author Benjamin Eberlei + * @since 2.0 + */ +class OptimisticLockException extends ORMException +{ + private $entity; + + public function __construct($msg, $entity) + { + parent::__construct($msg); + $this->entity = $entity; + } + + /** + * Gets the entity that caused the exception. + * + * @return object + */ + public function getEntity() + { + return $this->entity; + } + + public static function lockFailed($entity) + { + return new self("The optimistic lock on an entity failed.", $entity); + } + + public static function lockFailedVersionMissmatch($entity, $expectedLockVersion, $actualLockVersion) + { + return new self("The optimistic lock failed, version " . $expectedLockVersion . " was expected, but is actually ".$actualLockVersion, $entity); + } + + public static function notVersioned($entityName) + { + return new self("Cannot obtain optimistic lock on unversioned entity " . $entityName, null); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/PersistentCollection.php b/vendor/doctrine/orm/lib/Doctrine/ORM/PersistentCollection.php new file mode 100644 index 0000000..4c42c29 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/PersistentCollection.php @@ -0,0 +1,792 @@ +. + */ + +namespace Doctrine\ORM; + +use Doctrine\ORM\Mapping\ClassMetadata, + Doctrine\Common\Collections\Collection, + Doctrine\Common\Collections\ArrayCollection, + Closure; + +/** + * A PersistentCollection represents a collection of elements that have persistent state. + * + * Collections of entities represent only the associations (links) to those entities. + * That means, if the collection is part of a many-many mapping and you remove + * entities from the collection, only the links in the relation table are removed (on flush). + * Similarly, if you remove entities from a collection that is part of a one-many + * mapping this will only result in the nulling out of the foreign keys on flush. + * + * @since 2.0 + * @author Konsta Vesterinen + * @author Roman Borschel + * @author Giorgio Sironi + * @todo Design for inheritance to allow custom implementations? + */ +final class PersistentCollection implements Collection +{ + /** + * A snapshot of the collection at the moment it was fetched from the database. + * This is used to create a diff of the collection at commit time. + * + * @var array + */ + private $snapshot = array(); + + /** + * The entity that owns this collection. + * + * @var object + */ + private $owner; + + /** + * The association mapping the collection belongs to. + * This is currently either a OneToManyMapping or a ManyToManyMapping. + * + * @var array + */ + private $association; + + /** + * The EntityManager that manages the persistence of the collection. + * + * @var \Doctrine\ORM\EntityManager + */ + private $em; + + /** + * The name of the field on the target entities that points to the owner + * of the collection. This is only set if the association is bi-directional. + * + * @var string + */ + private $backRefFieldName; + + /** + * The class descriptor of the collection's entity type. + */ + private $typeClass; + + /** + * Whether the collection is dirty and needs to be synchronized with the database + * when the UnitOfWork that manages its persistent state commits. + * + * @var boolean + */ + private $isDirty = false; + + /** + * Whether the collection has already been initialized. + * + * @var boolean + */ + private $initialized = true; + + /** + * The wrapped Collection instance. + * + * @var Collection + */ + private $coll; + + /** + * Creates a new persistent collection. + * + * @param EntityManager $em The EntityManager the collection will be associated with. + * @param ClassMetadata $class The class descriptor of the entity type of this collection. + * @param array The collection elements. + */ + public function __construct(EntityManager $em, $class, $coll) + { + $this->coll = $coll; + $this->em = $em; + $this->typeClass = $class; + } + + /** + * INTERNAL: + * Sets the collection's owning entity together with the AssociationMapping that + * describes the association between the owner and the elements of the collection. + * + * @param object $entity + * @param AssociationMapping $assoc + */ + public function setOwner($entity, array $assoc) + { + $this->owner = $entity; + $this->association = $assoc; + $this->backRefFieldName = $assoc['inversedBy'] ?: $assoc['mappedBy']; + } + + /** + * INTERNAL: + * Gets the collection owner. + * + * @return object + */ + public function getOwner() + { + return $this->owner; + } + + public function getTypeClass() + { + return $this->typeClass; + } + + /** + * INTERNAL: + * Adds an element to a collection during hydration. This will automatically + * complete bidirectional associations in the case of a one-to-many association. + * + * @param mixed $element The element to add. + */ + public function hydrateAdd($element) + { + $this->coll->add($element); + + // If _backRefFieldName is set and its a one-to-many association, + // we need to set the back reference. + if ($this->backRefFieldName && $this->association['type'] === ClassMetadata::ONE_TO_MANY) { + // Set back reference to owner + $this->typeClass->reflFields[$this->backRefFieldName]->setValue( + $element, $this->owner + ); + + $this->em->getUnitOfWork()->setOriginalEntityProperty( + spl_object_hash($element), $this->backRefFieldName, $this->owner + ); + } + } + + /** + * INTERNAL: + * Sets a keyed element in the collection during hydration. + * + * @param mixed $key The key to set. + * $param mixed $value The element to set. + */ + public function hydrateSet($key, $element) + { + $this->coll->set($key, $element); + + // If _backRefFieldName is set, then the association is bidirectional + // and we need to set the back reference. + if ($this->backRefFieldName && $this->association['type'] === ClassMetadata::ONE_TO_MANY) { + // Set back reference to owner + $this->typeClass->reflFields[$this->backRefFieldName]->setValue( + $element, $this->owner + ); + } + } + + /** + * Initializes the collection by loading its contents from the database + * if the collection is not yet initialized. + */ + public function initialize() + { + if ($this->initialized || ! $this->association) { + return; + } + + // Has NEW objects added through add(). Remember them. + $newObjects = array(); + + if ($this->isDirty) { + $newObjects = $this->coll->toArray(); + } + + $this->coll->clear(); + $this->em->getUnitOfWork()->loadCollection($this); + $this->takeSnapshot(); + + // Reattach NEW objects added through add(), if any. + if ($newObjects) { + foreach ($newObjects as $obj) { + $this->coll->add($obj); + } + + $this->isDirty = true; + } + + $this->initialized = true; + } + + /** + * INTERNAL: + * Tells this collection to take a snapshot of its current state. + */ + public function takeSnapshot() + { + $this->snapshot = $this->coll->toArray(); + $this->isDirty = false; + } + + /** + * INTERNAL: + * Returns the last snapshot of the elements in the collection. + * + * @return array The last snapshot of the elements. + */ + public function getSnapshot() + { + return $this->snapshot; + } + + /** + * INTERNAL: + * getDeleteDiff + * + * @return array + */ + public function getDeleteDiff() + { + return array_udiff_assoc( + $this->snapshot, + $this->coll->toArray(), + function($a, $b) { return $a === $b ? 0 : 1; } + ); + } + + /** + * INTERNAL: + * getInsertDiff + * + * @return array + */ + public function getInsertDiff() + { + return array_udiff_assoc( + $this->coll->toArray(), + $this->snapshot, + function($a, $b) { return $a === $b ? 0 : 1; } + ); + } + + /** + * INTERNAL: Gets the association mapping of the collection. + * + * @return \Doctrine\ORM\Mapping\AssociationMapping + */ + public function getMapping() + { + return $this->association; + } + + /** + * Marks this collection as changed/dirty. + */ + private function changed() + { + if ($this->isDirty) { + return; + } + + $this->isDirty = true; + + if ($this->association !== null && + $this->association['isOwningSide'] && + $this->association['type'] === ClassMetadata::MANY_TO_MANY && + $this->owner && + $this->em->getClassMetadata(get_class($this->owner))->isChangeTrackingNotify()) { + $this->em->getUnitOfWork()->scheduleForDirtyCheck($this->owner); + } + } + + /** + * Gets a boolean flag indicating whether this collection is dirty which means + * its state needs to be synchronized with the database. + * + * @return boolean TRUE if the collection is dirty, FALSE otherwise. + */ + public function isDirty() + { + return $this->isDirty; + } + + /** + * Sets a boolean flag, indicating whether this collection is dirty. + * + * @param boolean $dirty Whether the collection should be marked dirty or not. + */ + public function setDirty($dirty) + { + $this->isDirty = $dirty; + } + + /** + * Sets the initialized flag of the collection, forcing it into that state. + * + * @param boolean $bool + */ + public function setInitialized($bool) + { + $this->initialized = $bool; + } + + /** + * Checks whether this collection has been initialized. + * + * @return boolean + */ + public function isInitialized() + { + return $this->initialized; + } + + /** {@inheritdoc} */ + public function first() + { + $this->initialize(); + + return $this->coll->first(); + } + + /** {@inheritdoc} */ + public function last() + { + $this->initialize(); + + return $this->coll->last(); + } + + /** + * {@inheritdoc} + */ + public function remove($key) + { + // TODO: If the keys are persistent as well (not yet implemented) + // and the collection is not initialized and orphanRemoval is + // not used we can issue a straight SQL delete/update on the + // association (table). Without initializing the collection. + $this->initialize(); + + $removed = $this->coll->remove($key); + + if ( ! $removed) { + return $removed; + } + + $this->changed(); + + if ($this->association !== null && + $this->association['type'] & ClassMetadata::TO_MANY && + $this->owner && + $this->association['orphanRemoval']) { + $this->em->getUnitOfWork()->scheduleOrphanRemoval($removed); + } + + return $removed; + } + + /** + * {@inheritdoc} + */ + public function removeElement($element) + { + if ( ! $this->initialized && $this->association['fetch'] === Mapping\ClassMetadataInfo::FETCH_EXTRA_LAZY) { + if ($this->coll->contains($element)) { + return $this->coll->removeElement($element); + } + + $persister = $this->em->getUnitOfWork()->getCollectionPersister($this->association); + + if ($persister->removeElement($this, $element)) { + return $element; + } + + return null; + } + + $this->initialize(); + + $removed = $this->coll->removeElement($element); + + if ( ! $removed) { + return $removed; + } + + $this->changed(); + + if ($this->association !== null && + $this->association['type'] & ClassMetadata::TO_MANY && + $this->owner && + $this->association['orphanRemoval']) { + $this->em->getUnitOfWork()->scheduleOrphanRemoval($element); + } + + return $removed; + } + + /** + * {@inheritdoc} + */ + public function containsKey($key) + { + $this->initialize(); + + return $this->coll->containsKey($key); + } + + /** + * {@inheritdoc} + */ + public function contains($element) + { + if ( ! $this->initialized && $this->association['fetch'] === Mapping\ClassMetadataInfo::FETCH_EXTRA_LAZY) { + $persister = $this->em->getUnitOfWork()->getCollectionPersister($this->association); + + return $this->coll->contains($element) || $persister->contains($this, $element); + } + + $this->initialize(); + + return $this->coll->contains($element); + } + + /** + * {@inheritdoc} + */ + public function exists(Closure $p) + { + $this->initialize(); + + return $this->coll->exists($p); + } + + /** + * {@inheritdoc} + */ + public function indexOf($element) + { + $this->initialize(); + + return $this->coll->indexOf($element); + } + + /** + * {@inheritdoc} + */ + public function get($key) + { + $this->initialize(); + + return $this->coll->get($key); + } + + /** + * {@inheritdoc} + */ + public function getKeys() + { + $this->initialize(); + + return $this->coll->getKeys(); + } + + /** + * {@inheritdoc} + */ + public function getValues() + { + $this->initialize(); + + return $this->coll->getValues(); + } + + /** + * {@inheritdoc} + */ + public function count() + { + if ( ! $this->initialized && $this->association['fetch'] === Mapping\ClassMetadataInfo::FETCH_EXTRA_LAZY) { + $persister = $this->em->getUnitOfWork()->getCollectionPersister($this->association); + + return $persister->count($this) + ($this->isDirty ? $this->coll->count() : 0); + } + + $this->initialize(); + + return $this->coll->count(); + } + + /** + * {@inheritdoc} + */ + public function set($key, $value) + { + $this->initialize(); + + $this->coll->set($key, $value); + + $this->changed(); + } + + /** + * {@inheritdoc} + */ + public function add($value) + { + $this->coll->add($value); + + $this->changed(); + + return true; + } + + /** + * {@inheritdoc} + */ + public function isEmpty() + { + $this->initialize(); + + return $this->coll->isEmpty(); + } + + /** + * {@inheritdoc} + */ + public function getIterator() + { + $this->initialize(); + + return $this->coll->getIterator(); + } + + /** + * {@inheritdoc} + */ + public function map(Closure $func) + { + $this->initialize(); + + return $this->coll->map($func); + } + + /** + * {@inheritdoc} + */ + public function filter(Closure $p) + { + $this->initialize(); + + return $this->coll->filter($p); + } + + /** + * {@inheritdoc} + */ + public function forAll(Closure $p) + { + $this->initialize(); + + return $this->coll->forAll($p); + } + + /** + * {@inheritdoc} + */ + public function partition(Closure $p) + { + $this->initialize(); + + return $this->coll->partition($p); + } + + /** + * {@inheritdoc} + */ + public function toArray() + { + $this->initialize(); + + return $this->coll->toArray(); + } + + /** + * {@inheritdoc} + */ + public function clear() + { + if ($this->initialized && $this->isEmpty()) { + return; + } + + $uow = $this->em->getUnitOfWork(); + + if ($this->association['type'] & ClassMetadata::TO_MANY && + $this->association['orphanRemoval'] && + $this->owner) { + // we need to initialize here, as orphan removal acts like implicit cascadeRemove, + // hence for event listeners we need the objects in memory. + $this->initialize(); + + foreach ($this->coll as $element) { + $uow->scheduleOrphanRemoval($element); + } + } + + $this->coll->clear(); + + $this->initialized = true; // direct call, {@link initialize()} is too expensive + + if ($this->association['isOwningSide']) { + $this->changed(); + + $uow->scheduleCollectionDeletion($this); + + $this->takeSnapshot(); + } + } + + /** + * Called by PHP when this collection is serialized. Ensures that only the + * elements are properly serialized. + * + * @internal Tried to implement Serializable first but that did not work well + * with circular references. This solution seems simpler and works well. + */ + public function __sleep() + { + return array('coll', 'initialized'); + } + + /* ArrayAccess implementation */ + + /** + * @see containsKey() + */ + public function offsetExists($offset) + { + return $this->containsKey($offset); + } + + /** + * @see get() + */ + public function offsetGet($offset) + { + return $this->get($offset); + } + + /** + * @see add() + * @see set() + */ + public function offsetSet($offset, $value) + { + if ( ! isset($offset)) { + return $this->add($value); + } + + return $this->set($offset, $value); + } + + /** + * @see remove() + */ + public function offsetUnset($offset) + { + return $this->remove($offset); + } + + public function key() + { + return $this->coll->key(); + } + + /** + * Gets the element of the collection at the current iterator position. + */ + public function current() + { + return $this->coll->current(); + } + + /** + * Moves the internal iterator position to the next element. + */ + public function next() + { + return $this->coll->next(); + } + + /** + * Retrieves the wrapped Collection instance. + * + * @return \Doctrine\Common\Collections\Collection + */ + public function unwrap() + { + return $this->coll; + } + + /** + * Extract a slice of $length elements starting at position $offset from the Collection. + * + * If $length is null it returns all elements from $offset to the end of the Collection. + * Keys have to be preserved by this method. Calling this method will only return the + * selected slice and NOT change the elements contained in the collection slice is called on. + * + * @param int $offset + * @param int $length + * + * @return array + */ + public function slice($offset, $length = null) + { + if ( ! $this->initialized && ! $this->isDirty && $this->association['fetch'] === Mapping\ClassMetadataInfo::FETCH_EXTRA_LAZY) { + $persister = $this->em->getUnitOfWork()->getCollectionPersister($this->association); + + return $persister->slice($this, $offset, $length); + } + + $this->initialize(); + + return $this->coll->slice($offset, $length); + } + + /** + * Cleanup internal state of cloned persistent collection. + * + * The following problems have to be prevented: + * 1. Added entities are added to old PC + * 2. New collection is not dirty, if reused on other entity nothing + * changes. + * 3. Snapshot leads to invalid diffs being generated. + * 4. Lazy loading grabs entities from old owner object. + * 5. New collection is connected to old owner and leads to duplicate keys. + */ + public function __clone() + { + if (is_object($this->coll)) { + $this->coll = clone $this->coll; + } + + $this->initialize(); + $this->owner = null; + + $this->snapshot = array(); + + $this->changed(); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/AbstractCollectionPersister.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/AbstractCollectionPersister.php new file mode 100644 index 0000000..8c12948 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/AbstractCollectionPersister.php @@ -0,0 +1,207 @@ +. + */ + +namespace Doctrine\ORM\Persisters; + +use Doctrine\ORM\EntityManager, + Doctrine\ORM\PersistentCollection; + +/** + * Base class for all collection persisters. + * + * @since 2.0 + * @author Roman Borschel + */ +abstract class AbstractCollectionPersister +{ + /** + * @var EntityManager + */ + protected $_em; + + /** + * @var \Doctrine\DBAL\Connection + */ + protected $_conn; + + /** + * @var \Doctrine\ORM\UnitOfWork + */ + protected $_uow; + + /** + * Initializes a new instance of a class derived from AbstractCollectionPersister. + * + * @param \Doctrine\ORM\EntityManager $em + */ + public function __construct(EntityManager $em) + { + $this->_em = $em; + $this->_uow = $em->getUnitOfWork(); + $this->_conn = $em->getConnection(); + } + + /** + * Deletes the persistent state represented by the given collection. + * + * @param PersistentCollection $coll + */ + public function delete(PersistentCollection $coll) + { + $mapping = $coll->getMapping(); + + if ( ! $mapping['isOwningSide']) { + return; // ignore inverse side + } + + $sql = $this->_getDeleteSQL($coll); + $this->_conn->executeUpdate($sql, $this->_getDeleteSQLParameters($coll)); + } + + /** + * Gets the SQL statement for deleting the given collection. + * + * @param PersistentCollection $coll + */ + abstract protected function _getDeleteSQL(PersistentCollection $coll); + + /** + * Gets the SQL parameters for the corresponding SQL statement to delete + * the given collection. + * + * @param PersistentCollection $coll + */ + abstract protected function _getDeleteSQLParameters(PersistentCollection $coll); + + /** + * Updates the given collection, synchronizing it's state with the database + * by inserting, updating and deleting individual elements. + * + * @param PersistentCollection $coll + */ + public function update(PersistentCollection $coll) + { + $mapping = $coll->getMapping(); + + if ( ! $mapping['isOwningSide']) { + return; // ignore inverse side + } + + $this->deleteRows($coll); + //$this->updateRows($coll); + $this->insertRows($coll); + } + + public function deleteRows(PersistentCollection $coll) + { + $deleteDiff = $coll->getDeleteDiff(); + $sql = $this->_getDeleteRowSQL($coll); + + foreach ($deleteDiff as $element) { + $this->_conn->executeUpdate($sql, $this->_getDeleteRowSQLParameters($coll, $element)); + } + } + + //public function updateRows(PersistentCollection $coll) + //{} + + public function insertRows(PersistentCollection $coll) + { + $insertDiff = $coll->getInsertDiff(); + $sql = $this->_getInsertRowSQL($coll); + + foreach ($insertDiff as $element) { + $this->_conn->executeUpdate($sql, $this->_getInsertRowSQLParameters($coll, $element)); + } + } + + public function count(PersistentCollection $coll) + { + throw new \BadMethodCallException("Counting the size of this persistent collection is not supported by this CollectionPersister."); + } + + public function slice(PersistentCollection $coll, $offset, $length = null) + { + throw new \BadMethodCallException("Slicing elements is not supported by this CollectionPersister."); + } + + public function contains(PersistentCollection $coll, $element) + { + throw new \BadMethodCallException("Checking for existance of an element is not supported by this CollectionPersister."); + } + + public function containsKey(PersistentCollection $coll, $key) + { + throw new \BadMethodCallException("Checking for existance of a key is not supported by this CollectionPersister."); + } + + public function removeElement(PersistentCollection $coll, $element) + { + throw new \BadMethodCallException("Removing an element is not supported by this CollectionPersister."); + } + + public function removeKey(PersistentCollection $coll, $key) + { + throw new \BadMethodCallException("Removing a key is not supported by this CollectionPersister."); + } + + public function get(PersistentCollection $coll, $index) + { + throw new \BadMethodCallException("Selecting a collection by index is not supported by this CollectionPersister."); + } + + /** + * Gets the SQL statement used for deleting a row from the collection. + * + * @param PersistentCollection $coll + */ + abstract protected function _getDeleteRowSQL(PersistentCollection $coll); + + /** + * Gets the SQL parameters for the corresponding SQL statement to delete the given + * element from the given collection. + * + * @param PersistentCollection $coll + * @param mixed $element + */ + abstract protected function _getDeleteRowSQLParameters(PersistentCollection $coll, $element); + + /** + * Gets the SQL statement used for updating a row in the collection. + * + * @param PersistentCollection $coll + */ + abstract protected function _getUpdateRowSQL(PersistentCollection $coll); + + /** + * Gets the SQL statement used for inserting a row in the collection. + * + * @param PersistentCollection $coll + */ + abstract protected function _getInsertRowSQL(PersistentCollection $coll); + + /** + * Gets the SQL parameters for the corresponding SQL statement to insert the given + * element of the given collection into the database. + * + * @param PersistentCollection $coll + * @param mixed $element + */ + abstract protected function _getInsertRowSQLParameters(PersistentCollection $coll, $element); +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/AbstractEntityInheritancePersister.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/AbstractEntityInheritancePersister.php new file mode 100644 index 0000000..191c077 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/AbstractEntityInheritancePersister.php @@ -0,0 +1,83 @@ +. + */ + +namespace Doctrine\ORM\Persisters; + +use Doctrine\ORM\Mapping\ClassMetadata, + Doctrine\DBAL\Types\Type; + +/** + * Base class for entity persisters that implement a certain inheritance mapping strategy. + * All these persisters are assumed to use a discriminator column to discriminate entity + * types in the hierarchy. + * + * @author Roman Borschel + * @author Benjamin Eberlei + * @since 2.0 + */ +abstract class AbstractEntityInheritancePersister extends BasicEntityPersister +{ + /** + * {@inheritdoc} + */ + protected function _prepareInsertData($entity) + { + $data = parent::_prepareInsertData($entity); + + // Populate the discriminator column + $discColumn = $this->_class->discriminatorColumn; + $this->_columnTypes[$discColumn['name']] = $discColumn['type']; + $data[$this->_getDiscriminatorColumnTableName()][$discColumn['name']] = $this->_class->discriminatorValue; + + return $data; + } + + /** + * Gets the name of the table that contains the discriminator column. + * + * @return string The table name. + */ + abstract protected function _getDiscriminatorColumnTableName(); + + /** + * {@inheritdoc} + */ + protected function _getSelectColumnSQL($field, ClassMetadata $class, $alias = 'r') + { + $columnName = $class->columnNames[$field]; + $sql = $this->_getSQLTableAlias($class->name, $alias == 'r' ? '' : $alias) . '.' . $class->getQuotedColumnName($field, $this->_platform); + $columnAlias = $this->getSQLColumnAlias($columnName); + $this->_rsm->addFieldResult($alias, $columnAlias, $field, $class->name); + + if (isset($class->fieldMappings[$field]['requireSQLConversion'])) { + $type = Type::getType($class->getTypeOfField($field)); + $sql = $type->convertToPHPValueSQL($sql, $this->_platform); + } + + return $sql . ' AS ' . $columnAlias; + } + + protected function getSelectJoinColumnSQL($tableAlias, $joinColumnName, $className) + { + $columnAlias = $this->getSQLColumnAlias($joinColumnName); + $this->_rsm->addMetaResult('r', $columnAlias, $joinColumnName); + + return $tableAlias . '.' . $joinColumnName . ' AS ' . $columnAlias; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php new file mode 100644 index 0000000..d3b8fce --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php @@ -0,0 +1,1605 @@ +. + */ + +namespace Doctrine\ORM\Persisters; + +use PDO, + Doctrine\DBAL\LockMode, + Doctrine\DBAL\Types\Type, + Doctrine\DBAL\Connection, + Doctrine\ORM\ORMException, + Doctrine\ORM\OptimisticLockException, + Doctrine\ORM\EntityManager, + Doctrine\ORM\UnitOfWork, + Doctrine\ORM\Query, + Doctrine\ORM\PersistentCollection, + Doctrine\ORM\Mapping\MappingException, + Doctrine\ORM\Mapping\ClassMetadata, + Doctrine\ORM\Events, + Doctrine\ORM\Event\LifecycleEventArgs; + +/** + * A BasicEntityPersiter maps an entity to a single table in a relational database. + * + * A persister is always responsible for a single entity type. + * + * EntityPersisters are used during a UnitOfWork to apply any changes to the persistent + * state of entities onto a relational database when the UnitOfWork is committed, + * as well as for basic querying of entities and their associations (not DQL). + * + * The persisting operations that are invoked during a commit of a UnitOfWork to + * persist the persistent entity state are: + * + * - {@link addInsert} : To schedule an entity for insertion. + * - {@link executeInserts} : To execute all scheduled insertions. + * - {@link update} : To update the persistent state of an entity. + * - {@link delete} : To delete the persistent state of an entity. + * + * As can be seen from the above list, insertions are batched and executed all at once + * for increased efficiency. + * + * The querying operations invoked during a UnitOfWork, either through direct find + * requests or lazy-loading, are the following: + * + * - {@link load} : Loads (the state of) a single, managed entity. + * - {@link loadAll} : Loads multiple, managed entities. + * - {@link loadOneToOneEntity} : Loads a one/many-to-one entity association (lazy-loading). + * - {@link loadOneToManyCollection} : Loads a one-to-many entity association (lazy-loading). + * - {@link loadManyToManyCollection} : Loads a many-to-many entity association (lazy-loading). + * + * The BasicEntityPersister implementation provides the default behavior for + * persisting and querying entities that are mapped to a single database table. + * + * Subclasses can be created to provide custom persisting and querying strategies, + * i.e. spanning multiple tables. + * + * @author Roman Borschel + * @author Giorgio Sironi + * @author Benjamin Eberlei + * @author Alexander + * @since 2.0 + */ +class BasicEntityPersister +{ + /** + * Metadata object that describes the mapping of the mapped entity class. + * + * @var \Doctrine\ORM\Mapping\ClassMetadata + */ + protected $_class; + + /** + * The underlying DBAL Connection of the used EntityManager. + * + * @var \Doctrine\DBAL\Connection $conn + */ + protected $_conn; + + /** + * The database platform. + * + * @var \Doctrine\DBAL\Platforms\AbstractPlatform + */ + protected $_platform; + + /** + * The EntityManager instance. + * + * @var \Doctrine\ORM\EntityManager + */ + protected $_em; + + /** + * Queued inserts. + * + * @var array + */ + protected $_queuedInserts = array(); + + /** + * ResultSetMapping that is used for all queries. Is generated lazily once per request. + * + * TODO: Evaluate Caching in combination with the other cached SQL snippets. + * + * @var Query\ResultSetMapping + */ + protected $_rsm; + + /** + * The map of column names to DBAL mapping types of all prepared columns used + * when INSERTing or UPDATEing an entity. + * + * @var array + * @see _prepareInsertData($entity) + * @see _prepareUpdateData($entity) + */ + protected $_columnTypes = array(); + + /** + * The INSERT SQL statement used for entities handled by this persister. + * This SQL is only generated once per request, if at all. + * + * @var string + */ + private $_insertSql; + + /** + * The SELECT column list SQL fragment used for querying entities by this persister. + * This SQL fragment is only generated once per request, if at all. + * + * @var string + */ + protected $_selectColumnListSql; + + /** + * The JOIN SQL fragement used to eagerly load all many-to-one and one-to-one + * associations configured as FETCH_EAGER, aswell as all inverse one-to-one associations. + * + * @var string + */ + protected $_selectJoinSql; + + /** + * Counter for creating unique SQL table and column aliases. + * + * @var integer + */ + protected $_sqlAliasCounter = 0; + + /** + * Map from class names (FQCN) to the corresponding generated SQL table aliases. + * + * @var array + */ + protected $_sqlTableAliases = array(); + + /** + * Initializes a new BasicEntityPersister that uses the given EntityManager + * and persists instances of the class described by the given ClassMetadata descriptor. + * + * @param \Doctrine\ORM\EntityManager $em + * @param \Doctrine\ORM\Mapping\ClassMetadata $class + */ + public function __construct(EntityManager $em, ClassMetadata $class) + { + $this->_em = $em; + $this->_class = $class; + $this->_conn = $em->getConnection(); + $this->_platform = $this->_conn->getDatabasePlatform(); + } + + /** + * @return \Doctrine\ORM\Mapping\ClassMetadata + */ + public function getClassMetadata() + { + return $this->_class; + } + + /** + * Adds an entity to the queued insertions. + * The entity remains queued until {@link executeInserts} is invoked. + * + * @param object $entity The entity to queue for insertion. + */ + public function addInsert($entity) + { + $this->_queuedInserts[spl_object_hash($entity)] = $entity; + } + + /** + * Executes all queued entity insertions and returns any generated post-insert + * identifiers that were created as a result of the insertions. + * + * If no inserts are queued, invoking this method is a NOOP. + * + * @return array An array of any generated post-insert IDs. This will be an empty array + * if the entity class does not use the IDENTITY generation strategy. + */ + public function executeInserts() + { + if ( ! $this->_queuedInserts) { + return; + } + + $postInsertIds = array(); + $idGen = $this->_class->idGenerator; + $isPostInsertId = $idGen->isPostInsertGenerator(); + + $stmt = $this->_conn->prepare($this->_getInsertSQL()); + $tableName = $this->_class->getTableName(); + + foreach ($this->_queuedInserts as $entity) { + $insertData = $this->_prepareInsertData($entity); + + if (isset($insertData[$tableName])) { + $paramIndex = 1; + + foreach ($insertData[$tableName] as $column => $value) { + $stmt->bindValue($paramIndex++, $value, $this->_columnTypes[$column]); + } + } + + $stmt->execute(); + + if ($isPostInsertId) { + $id = $idGen->generate($this->_em, $entity); + $postInsertIds[$id] = $entity; + } else { + $id = $this->_class->getIdentifierValues($entity); + } + + if ($this->_class->isVersioned) { + $this->assignDefaultVersionValue($entity, $id); + } + } + + $stmt->closeCursor(); + $this->_queuedInserts = array(); + + return $postInsertIds; + } + + /** + * Retrieves the default version value which was created + * by the preceding INSERT statement and assigns it back in to the + * entities version field. + * + * @param object $entity + * @param mixed $id + */ + protected function assignDefaultVersionValue($entity, $id) + { + $value = $this->fetchVersionValue($this->_class, $id); + $this->_class->setFieldValue($entity, $this->_class->versionField, $value); + } + + /** + * Fetch the current version value of a versioned entity. + * + * @param \Doctrine\ORM\Mapping\ClassMetadata $versionedClass + * @param mixed $id + * @return mixed + */ + protected function fetchVersionValue($versionedClass, $id) + { + $versionField = $versionedClass->versionField; + $identifier = $versionedClass->getIdentifierColumnNames(); + + $versionFieldColumnName = $versionedClass->getQuotedColumnName($versionField, $this->_platform); + + //FIXME: Order with composite keys might not be correct + $sql = 'SELECT ' . $versionFieldColumnName + . ' FROM ' . $versionedClass->getQuotedTableName($this->_platform) + . ' WHERE ' . implode(' = ? AND ', $identifier) . ' = ?'; + $value = $this->_conn->fetchColumn($sql, array_values((array)$id)); + + return Type::getType($versionedClass->fieldMappings[$versionField]['type'])->convertToPHPValue($value, $this->_platform); + } + + /** + * Updates a managed entity. The entity is updated according to its current changeset + * in the running UnitOfWork. If there is no changeset, nothing is updated. + * + * The data to update is retrieved through {@link _prepareUpdateData}. + * Subclasses that override this method are supposed to obtain the update data + * in the same way, through {@link _prepareUpdateData}. + * + * Subclasses are also supposed to take care of versioning when overriding this method, + * if necessary. The {@link _updateTable} method can be used to apply the data retrieved + * from {@_prepareUpdateData} on the target tables, thereby optionally applying versioning. + * + * @param object $entity The entity to update. + */ + public function update($entity) + { + $updateData = $this->_prepareUpdateData($entity); + $tableName = $this->_class->getTableName(); + + if (isset($updateData[$tableName]) && $updateData[$tableName]) { + $this->_updateTable( + $entity, $this->_class->getQuotedTableName($this->_platform), + $updateData[$tableName], $this->_class->isVersioned + ); + + if ($this->_class->isVersioned) { + $id = $this->_em->getUnitOfWork()->getEntityIdentifier($entity); + $this->assignDefaultVersionValue($entity, $id); + } + } + } + + /** + * Performs an UPDATE statement for an entity on a specific table. + * The UPDATE can optionally be versioned, which requires the entity to have a version field. + * + * @param object $entity The entity object being updated. + * @param string $quotedTableName The quoted name of the table to apply the UPDATE on. + * @param array $updateData The map of columns to update (column => value). + * @param boolean $versioned Whether the UPDATE should be versioned. + */ + protected final function _updateTable($entity, $quotedTableName, array $updateData, $versioned = false) + { + $set = $params = $types = array(); + + foreach ($updateData as $columnName => $value) { + $column = $columnName; + $placeholder = '?'; + + if (isset($this->_class->fieldNames[$columnName])) { + $column = $this->_class->getQuotedColumnName($this->_class->fieldNames[$columnName], $this->_platform); + + if (isset($this->_class->fieldMappings[$this->_class->fieldNames[$columnName]]['requireSQLConversion'])) { + $type = Type::getType($this->_columnTypes[$columnName]); + $placeholder = $type->convertToDatabaseValueSQL('?', $this->_platform); + } + } + + $set[] = $column . ' = ' . $placeholder; + $params[] = $value; + $types[] = $this->_columnTypes[$columnName]; + } + + $where = array(); + $id = $this->_em->getUnitOfWork()->getEntityIdentifier($entity); + + foreach ($this->_class->identifier as $idField) { + if (isset($this->_class->associationMappings[$idField])) { + $targetMapping = $this->_em->getClassMetadata($this->_class->associationMappings[$idField]['targetEntity']); + $where[] = $this->_class->associationMappings[$idField]['joinColumns'][0]['name']; + $params[] = $id[$idField]; + $types[] = $targetMapping->fieldMappings[$targetMapping->identifier[0]]['type']; + } else { + $where[] = $this->_class->getQuotedColumnName($idField, $this->_platform); + $params[] = $id[$idField]; + $types[] = $this->_class->fieldMappings[$idField]['type']; + } + } + + if ($versioned) { + $versionField = $this->_class->versionField; + $versionFieldType = $this->_class->fieldMappings[$versionField]['type']; + $versionColumn = $this->_class->getQuotedColumnName($versionField, $this->_platform); + + if ($versionFieldType == Type::INTEGER) { + $set[] = $versionColumn . ' = ' . $versionColumn . ' + 1'; + } else if ($versionFieldType == Type::DATETIME) { + $set[] = $versionColumn . ' = CURRENT_TIMESTAMP'; + } + + $where[] = $versionColumn; + $params[] = $this->_class->reflFields[$versionField]->getValue($entity); + $types[] = $this->_class->fieldMappings[$versionField]['type']; + } + + $sql = 'UPDATE ' . $quotedTableName + . ' SET ' . implode(', ', $set) + . ' WHERE ' . implode(' = ? AND ', $where) . ' = ?'; + + $result = $this->_conn->executeUpdate($sql, $params, $types); + + if ($versioned && ! $result) { + throw OptimisticLockException::lockFailed($entity); + } + } + + /** + * @todo Add check for platform if it supports foreign keys/cascading. + * @param array $identifier + * @return void + */ + protected function deleteJoinTableRecords($identifier) + { + foreach ($this->_class->associationMappings as $mapping) { + if ($mapping['type'] == ClassMetadata::MANY_TO_MANY) { + // @Todo this only covers scenarios with no inheritance or of the same level. Is there something + // like self-referential relationship between different levels of an inheritance hierachy? I hope not! + $selfReferential = ($mapping['targetEntity'] == $mapping['sourceEntity']); + + if ( ! $mapping['isOwningSide']) { + $relatedClass = $this->_em->getClassMetadata($mapping['targetEntity']); + $mapping = $relatedClass->associationMappings[$mapping['mappedBy']]; + $keys = array_keys($mapping['relationToTargetKeyColumns']); + + if ($selfReferential) { + $otherKeys = array_keys($mapping['relationToSourceKeyColumns']); + } + } else { + $keys = array_keys($mapping['relationToSourceKeyColumns']); + + if ($selfReferential) { + $otherKeys = array_keys($mapping['relationToTargetKeyColumns']); + } + } + + if ( ! isset($mapping['isOnDeleteCascade'])) { + $this->_conn->delete( + $this->_class->getQuotedJoinTableName($mapping, $this->_platform), + array_combine($keys, $identifier) + ); + + if ($selfReferential) { + $this->_conn->delete( + $this->_class->getQuotedJoinTableName($mapping, $this->_platform), + array_combine($otherKeys, $identifier) + ); + } + } + } + } + } + + /** + * Deletes a managed entity. + * + * The entity to delete must be managed and have a persistent identifier. + * The deletion happens instantaneously. + * + * Subclasses may override this method to customize the semantics of entity deletion. + * + * @param object $entity The entity to delete. + */ + public function delete($entity) + { + $identifier = $this->_em->getUnitOfWork()->getEntityIdentifier($entity); + $this->deleteJoinTableRecords($identifier); + + $id = array_combine($this->_class->getIdentifierColumnNames(), $identifier); + $this->_conn->delete($this->_class->getQuotedTableName($this->_platform), $id); + } + + /** + * Prepares the changeset of an entity for database insertion (UPDATE). + * + * The changeset is obtained from the currently running UnitOfWork. + * + * During this preparation the array that is passed as the second parameter is filled with + * => pairs, grouped by table name. + * + * Example: + * + * array( + * 'foo_table' => array('column1' => 'value1', 'column2' => 'value2', ...), + * 'bar_table' => array('columnX' => 'valueX', 'columnY' => 'valueY', ...), + * ... + * ) + * + * + * @param object $entity The entity for which to prepare the data. + * @return array The prepared data. + */ + protected function _prepareUpdateData($entity) + { + $result = array(); + $uow = $this->_em->getUnitOfWork(); + + if (($versioned = $this->_class->isVersioned) != false) { + $versionField = $this->_class->versionField; + } + + foreach ($uow->getEntityChangeSet($entity) as $field => $change) { + if ($versioned && $versionField == $field) { + continue; + } + + $oldVal = $change[0]; + $newVal = $change[1]; + + if (isset($this->_class->associationMappings[$field])) { + $assoc = $this->_class->associationMappings[$field]; + + // Only owning side of x-1 associations can have a FK column. + if ( ! $assoc['isOwningSide'] || ! ($assoc['type'] & ClassMetadata::TO_ONE)) { + continue; + } + + if ($newVal !== null) { + $oid = spl_object_hash($newVal); + + if (isset($this->_queuedInserts[$oid]) || $uow->isScheduledForInsert($newVal)) { + // The associated entity $newVal is not yet persisted, so we must + // set $newVal = null, in order to insert a null value and schedule an + // extra update on the UnitOfWork. + $uow->scheduleExtraUpdate($entity, array( + $field => array(null, $newVal) + )); + $newVal = null; + } + } + + if ($newVal !== null) { + $newValId = $uow->getEntityIdentifier($newVal); + } + + $targetClass = $this->_em->getClassMetadata($assoc['targetEntity']); + $owningTable = $this->getOwningTable($field); + + foreach ($assoc['sourceToTargetKeyColumns'] as $sourceColumn => $targetColumn) { + if ($newVal === null) { + $result[$owningTable][$sourceColumn] = null; + } else if ($targetClass->containsForeignIdentifier) { + $result[$owningTable][$sourceColumn] = $newValId[$targetClass->getFieldForColumn($targetColumn)]; + } else { + $result[$owningTable][$sourceColumn] = $newValId[$targetClass->fieldNames[$targetColumn]]; + } + + $this->_columnTypes[$sourceColumn] = $targetClass->getTypeOfColumn($targetColumn); + } + } else { + $columnName = $this->_class->columnNames[$field]; + $this->_columnTypes[$columnName] = $this->_class->fieldMappings[$field]['type']; + $result[$this->getOwningTable($field)][$columnName] = $newVal; + } + } + + return $result; + } + + /** + * Prepares the data changeset of a managed entity for database insertion (initial INSERT). + * The changeset of the entity is obtained from the currently running UnitOfWork. + * + * The default insert data preparation is the same as for updates. + * + * @param object $entity The entity for which to prepare the data. + * @return array The prepared data for the tables to update. + * @see _prepareUpdateData + */ + protected function _prepareInsertData($entity) + { + return $this->_prepareUpdateData($entity); + } + + /** + * Gets the name of the table that owns the column the given field is mapped to. + * + * The default implementation in BasicEntityPersister always returns the name + * of the table the entity type of this persister is mapped to, since an entity + * is always persisted to a single table with a BasicEntityPersister. + * + * @param string $fieldName The field name. + * @return string The table name. + */ + public function getOwningTable($fieldName) + { + return $this->_class->getTableName(); + } + + /** + * Loads an entity by a list of field criteria. + * + * @param array $criteria The criteria by which to load the entity. + * @param object $entity The entity to load the data into. If not specified, + * a new entity is created. + * @param $assoc The association that connects the entity to load to another entity, if any. + * @param array $hints Hints for entity creation. + * @param int $lockMode + * @param int $limit Limit number of results + * @return object The loaded and managed entity instance or NULL if the entity can not be found. + * @todo Check identity map? loadById method? Try to guess whether $criteria is the id? + */ + public function load(array $criteria, $entity = null, $assoc = null, array $hints = array(), $lockMode = 0, $limit = null) + { + $sql = $this->_getSelectEntitiesSQL($criteria, $assoc, $lockMode, $limit); + list($params, $types) = $this->expandParameters($criteria); + $stmt = $this->_conn->executeQuery($sql, $params, $types); + + if ($entity !== null) { + $hints[Query::HINT_REFRESH] = true; + $hints[Query::HINT_REFRESH_ENTITY] = $entity; + } + + $hydrator = $this->_em->newHydrator($this->_selectJoinSql ? Query::HYDRATE_OBJECT : Query::HYDRATE_SIMPLEOBJECT); + $entities = $hydrator->hydrateAll($stmt, $this->_rsm, $hints); + + return $entities ? $entities[0] : null; + } + + /** + * Loads an entity of this persister's mapped class as part of a single-valued + * association from another entity. + * + * @param array $assoc The association to load. + * @param object $sourceEntity The entity that owns the association (not necessarily the "owning side"). + * @param array $identifier The identifier of the entity to load. Must be provided if + * the association to load represents the owning side, otherwise + * the identifier is derived from the $sourceEntity. + * @return object The loaded and managed entity instance or NULL if the entity can not be found. + */ + public function loadOneToOneEntity(array $assoc, $sourceEntity, array $identifier = array()) + { + if (($foundEntity = $this->_em->getUnitOfWork()->tryGetById($identifier, $assoc['targetEntity'])) != false) { + return $foundEntity; + } + + $targetClass = $this->_em->getClassMetadata($assoc['targetEntity']); + + if ($assoc['isOwningSide']) { + $isInverseSingleValued = $assoc['inversedBy'] && ! $targetClass->isCollectionValuedAssociation($assoc['inversedBy']); + + // Mark inverse side as fetched in the hints, otherwise the UoW would + // try to load it in a separate query (remember: to-one inverse sides can not be lazy). + $hints = array(); + + if ($isInverseSingleValued) { + $hints['fetched']["r"][$assoc['inversedBy']] = true; + } + + /* cascade read-only status + if ($this->_em->getUnitOfWork()->isReadOnly($sourceEntity)) { + $hints[Query::HINT_READ_ONLY] = true; + } + */ + + $targetEntity = $this->load($identifier, null, $assoc, $hints); + + // Complete bidirectional association, if necessary + if ($targetEntity !== null && $isInverseSingleValued) { + $targetClass->reflFields[$assoc['inversedBy']]->setValue($targetEntity, $sourceEntity); + } + } else { + $sourceClass = $this->_em->getClassMetadata($assoc['sourceEntity']); + $owningAssoc = $targetClass->getAssociationMapping($assoc['mappedBy']); + + // TRICKY: since the association is specular source and target are flipped + foreach ($owningAssoc['targetToSourceKeyColumns'] as $sourceKeyColumn => $targetKeyColumn) { + if ( ! isset($sourceClass->fieldNames[$sourceKeyColumn])) { + throw MappingException::joinColumnMustPointToMappedField( + $sourceClass->name, $sourceKeyColumn + ); + } + + // unset the old value and set the new sql aliased value here. By definition + // unset($identifier[$targetKeyColumn] works here with how UnitOfWork::createEntity() calls this method. + $identifier[$this->_getSQLTableAlias($targetClass->name) . "." . $targetKeyColumn] = + $sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity); + + unset($identifier[$targetKeyColumn]); + } + + $targetEntity = $this->load($identifier, null, $assoc); + + if ($targetEntity !== null) { + $targetClass->setFieldValue($targetEntity, $assoc['mappedBy'], $sourceEntity); + } + } + + return $targetEntity; + } + + /** + * Refreshes a managed entity. + * + * @param array $id The identifier of the entity as an associative array from + * column or field names to values. + * @param object $entity The entity to refresh. + */ + public function refresh(array $id, $entity) + { + $sql = $this->_getSelectEntitiesSQL($id); + list($params, $types) = $this->expandParameters($id); + $stmt = $this->_conn->executeQuery($sql, $params, $types); + + $hydrator = $this->_em->newHydrator(Query::HYDRATE_OBJECT); + $hydrator->hydrateAll($stmt, $this->_rsm, array(Query::HINT_REFRESH => true)); + } + + /** + * Loads a list of entities by a list of field criteria. + * + * @param array $criteria + * @param array $orderBy + * @param int $limit + * @param int $offset + * @return array + */ + public function loadAll(array $criteria = array(), array $orderBy = null, $limit = null, $offset = null) + { + $entities = array(); + $sql = $this->_getSelectEntitiesSQL($criteria, null, 0, $limit, $offset, $orderBy); + list($params, $types) = $this->expandParameters($criteria); + $stmt = $this->_conn->executeQuery($sql, $params, $types); + + $hydrator = $this->_em->newHydrator(($this->_selectJoinSql) ? Query::HYDRATE_OBJECT : Query::HYDRATE_SIMPLEOBJECT); + + return $hydrator->hydrateAll($stmt, $this->_rsm, array('deferEagerLoads' => true)); + } + + /** + * Get (sliced or full) elements of the given collection. + * + * @param array $assoc + * @param object $sourceEntity + * @param int|null $offset + * @param int|null $limit + * @return array + */ + public function getManyToManyCollection(array $assoc, $sourceEntity, $offset = null, $limit = null) + { + $stmt = $this->getManyToManyStatement($assoc, $sourceEntity, $offset, $limit); + + return $this->loadArrayFromStatement($assoc, $stmt); + } + + /** + * Load an array of entities from a given dbal statement. + * + * @param array $assoc + * @param \Doctrine\DBAL\Statement $stmt + * + * @return array + */ + private function loadArrayFromStatement($assoc, $stmt) + { + $hints = array('deferEagerLoads' => true); + + if (isset($assoc['indexBy'])) { + $rsm = clone ($this->_rsm); // this is necessary because the "default rsm" should be changed. + $rsm->addIndexBy('r', $assoc['indexBy']); + } else { + $rsm = $this->_rsm; + } + + $hydrator = $this->_em->newHydrator(Query::HYDRATE_OBJECT); + + return $hydrator->hydrateAll($stmt, $rsm, $hints); + } + + /** + * Hydrate a collection from a given dbal statement. + * + * @param array $assoc + * @param \Doctrine\DBAL\Statement $stmt + * @param PersistentCollection $coll + * + * @return array + */ + private function loadCollectionFromStatement($assoc, $stmt, $coll) + { + $hints = array('deferEagerLoads' => true, 'collection' => $coll); + + if (isset($assoc['indexBy'])) { + $rsm = clone ($this->_rsm); // this is necessary because the "default rsm" should be changed. + $rsm->addIndexBy('r', $assoc['indexBy']); + } else { + $rsm = $this->_rsm; + } + + $hydrator = $this->_em->newHydrator(Query::HYDRATE_OBJECT); + + return $hydrator->hydrateAll($stmt, $rsm, $hints); + } + + /** + * Loads a collection of entities of a many-to-many association. + * + * @param ManyToManyMapping $assoc The association mapping of the association being loaded. + * @param object $sourceEntity The entity that owns the collection. + * @param PersistentCollection $coll The collection to fill. + * @param int|null $offset + * @param int|null $limit + * @return array + */ + public function loadManyToManyCollection(array $assoc, $sourceEntity, PersistentCollection $coll) + { + $stmt = $this->getManyToManyStatement($assoc, $sourceEntity); + + return $this->loadCollectionFromStatement($assoc, $stmt, $coll); + } + + private function getManyToManyStatement(array $assoc, $sourceEntity, $offset = null, $limit = null) + { + $criteria = array(); + $sourceClass = $this->_em->getClassMetadata($assoc['sourceEntity']); + + if ($assoc['isOwningSide']) { + $quotedJoinTable = $sourceClass->getQuotedJoinTableName($assoc, $this->_platform); + + foreach ($assoc['relationToSourceKeyColumns'] as $relationKeyColumn => $sourceKeyColumn) { + if ($sourceClass->containsForeignIdentifier) { + $field = $sourceClass->getFieldForColumn($sourceKeyColumn); + $value = $sourceClass->reflFields[$field]->getValue($sourceEntity); + + if (isset($sourceClass->associationMappings[$field])) { + $value = $this->_em->getUnitOfWork()->getEntityIdentifier($value); + $value = $value[$this->_em->getClassMetadata($sourceClass->associationMappings[$field]['targetEntity'])->identifier[0]]; + } + + $criteria[$quotedJoinTable . "." . $relationKeyColumn] = $value; + } else if (isset($sourceClass->fieldNames[$sourceKeyColumn])) { + $criteria[$quotedJoinTable . "." . $relationKeyColumn] = $sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity); + } else { + throw MappingException::joinColumnMustPointToMappedField( + $sourceClass->name, $sourceKeyColumn + ); + } + } + } else { + $owningAssoc = $this->_em->getClassMetadata($assoc['targetEntity'])->associationMappings[$assoc['mappedBy']]; + $quotedJoinTable = $sourceClass->getQuotedJoinTableName($owningAssoc, $this->_platform); + + // TRICKY: since the association is inverted source and target are flipped + foreach ($owningAssoc['relationToTargetKeyColumns'] as $relationKeyColumn => $sourceKeyColumn) { + if ($sourceClass->containsForeignIdentifier) { + $field = $sourceClass->getFieldForColumn($sourceKeyColumn); + $value = $sourceClass->reflFields[$field]->getValue($sourceEntity); + + if (isset($sourceClass->associationMappings[$field])) { + $value = $this->_em->getUnitOfWork()->getEntityIdentifier($value); + $value = $value[$this->_em->getClassMetadata($sourceClass->associationMappings[$field]['targetEntity'])->identifier[0]]; + } + + $criteria[$quotedJoinTable . "." . $relationKeyColumn] = $value; + } else if (isset($sourceClass->fieldNames[$sourceKeyColumn])) { + $criteria[$quotedJoinTable . "." . $relationKeyColumn] = $sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity); + } else { + throw MappingException::joinColumnMustPointToMappedField( + $sourceClass->name, $sourceKeyColumn + ); + } + } + } + + $sql = $this->_getSelectEntitiesSQL($criteria, $assoc, 0, $limit, $offset); + list($params, $types) = $this->expandParameters($criteria); + + return $this->_conn->executeQuery($sql, $params, $types); + } + + /** + * Gets the SELECT SQL to select one or more entities by a set of field criteria. + * + * @param array $criteria + * @param AssociationMapping $assoc + * @param string $orderBy + * @param int $lockMode + * @param int $limit + * @param int $offset + * @param array $orderBy + * @return string + * @todo Refactor: _getSelectSQL(...) + */ + protected function _getSelectEntitiesSQL(array $criteria, $assoc = null, $lockMode = 0, $limit = null, $offset = null, array $orderBy = null) + { + $joinSql = ($assoc != null && $assoc['type'] == ClassMetadata::MANY_TO_MANY) ? $this->_getSelectManyToManyJoinSQL($assoc) : ''; + $conditionSql = $this->_getSelectConditionSQL($criteria, $assoc); + + $orderBy = ($assoc !== null && isset($assoc['orderBy'])) ? $assoc['orderBy'] : $orderBy; + $orderBySql = $orderBy ? $this->_getOrderBySQL($orderBy, $this->_getSQLTableAlias($this->_class->name)) : ''; + + $lockSql = ''; + + if ($lockMode == LockMode::PESSIMISTIC_READ) { + $lockSql = ' ' . $this->_platform->getReadLockSql(); + } else if ($lockMode == LockMode::PESSIMISTIC_WRITE) { + $lockSql = ' ' . $this->_platform->getWriteLockSql(); + } + + $alias = $this->_getSQLTableAlias($this->_class->name); + + if ($filterSql = $this->generateFilterConditionSQL($this->_class, $alias)) { + if ($conditionSql) { + $conditionSql .= ' AND '; + } + + $conditionSql .= $filterSql; + } + + return $this->_platform->modifyLimitQuery('SELECT ' . $this->_getSelectColumnListSQL() + . $this->_platform->appendLockHint(' FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' ' + . $alias, $lockMode) + . $this->_selectJoinSql . $joinSql + . ($conditionSql ? ' WHERE ' . $conditionSql : '') + . $orderBySql, $limit, $offset) + . $lockSql; + } + + /** + * Gets the ORDER BY SQL snippet for ordered collections. + * + * @param array $orderBy + * @param string $baseTableAlias + * @return string + */ + protected final function _getOrderBySQL(array $orderBy, $baseTableAlias) + { + $orderBySql = ''; + + foreach ($orderBy as $fieldName => $orientation) { + if ( ! isset($this->_class->fieldMappings[$fieldName])) { + throw ORMException::unrecognizedField($fieldName); + } + + $orientation = strtoupper(trim($orientation)); + if ($orientation != 'ASC' && $orientation != 'DESC') { + throw ORMException::invalidOrientation($this->_class->name, $fieldName); + } + + $tableAlias = isset($this->_class->fieldMappings[$fieldName]['inherited']) ? + $this->_getSQLTableAlias($this->_class->fieldMappings[$fieldName]['inherited']) + : $baseTableAlias; + + $columnName = $this->_class->getQuotedColumnName($fieldName, $this->_platform); + + $orderBySql .= $orderBySql ? ', ' : ' ORDER BY '; + $orderBySql .= $tableAlias . '.' . $columnName . ' ' . $orientation; + } + + return $orderBySql; + } + + /** + * Gets the SQL fragment with the list of columns to select when querying for + * an entity in this persister. + * + * Subclasses should override this method to alter or change the select column + * list SQL fragment. Note that in the implementation of BasicEntityPersister + * the resulting SQL fragment is generated only once and cached in {@link _selectColumnListSql}. + * Subclasses may or may not do the same. + * + * @return string The SQL fragment. + * @todo Rename: _getSelectColumnsSQL() + */ + protected function _getSelectColumnListSQL() + { + if ($this->_selectColumnListSql !== null) { + return $this->_selectColumnListSql; + } + + $columnList = ''; + $this->_rsm = new Query\ResultSetMapping(); + $this->_rsm->addEntityResult($this->_class->name, 'r'); // r for root + + // Add regular columns to select list + foreach ($this->_class->fieldNames as $field) { + if ($columnList) $columnList .= ', '; + + $columnList .= $this->_getSelectColumnSQL($field, $this->_class); + } + + $this->_selectJoinSql = ''; + $eagerAliasCounter = 0; + + foreach ($this->_class->associationMappings as $assocField => $assoc) { + $assocColumnSQL = $this->_getSelectColumnAssociationSQL($assocField, $assoc, $this->_class); + + if ($assocColumnSQL) { + if ($columnList) $columnList .= ', '; + + $columnList .= $assocColumnSQL; + } + + if ($assoc['type'] & ClassMetadata::TO_ONE && ($assoc['fetch'] == ClassMetadata::FETCH_EAGER || !$assoc['isOwningSide'])) { + $eagerEntity = $this->_em->getClassMetadata($assoc['targetEntity']); + + if ($eagerEntity->inheritanceType != ClassMetadata::INHERITANCE_TYPE_NONE) { + continue; // now this is why you shouldn't use inheritance + } + + $assocAlias = 'e' . ($eagerAliasCounter++); + $this->_rsm->addJoinedEntityResult($assoc['targetEntity'], $assocAlias, 'r', $assocField); + + foreach ($eagerEntity->fieldNames AS $field) { + if ($columnList) $columnList .= ', '; + + $columnList .= $this->_getSelectColumnSQL($field, $eagerEntity, $assocAlias); + } + + foreach ($eagerEntity->associationMappings as $assoc2Field => $assoc2) { + $assoc2ColumnSQL = $this->_getSelectColumnAssociationSQL($assoc2Field, $assoc2, $eagerEntity, $assocAlias); + + if ($assoc2ColumnSQL) { + if ($columnList) $columnList .= ', '; + $columnList .= $assoc2ColumnSQL; + } + } + $first = true; + + if ($assoc['isOwningSide']) { + $this->_selectJoinSql .= ' ' . $this->getJoinSQLForJoinColumns($assoc['joinColumns']); + $this->_selectJoinSql .= ' ' . $eagerEntity->getQuotedTableName($this->_platform) . ' ' . $this->_getSQLTableAlias($eagerEntity->name, $assocAlias) .' ON '; + + $tableAlias = $this->_getSQLTableAlias($assoc['targetEntity'], $assocAlias); + foreach ($assoc['sourceToTargetKeyColumns'] AS $sourceCol => $targetCol) { + if ( ! $first) { + $this->_selectJoinSql .= ' AND '; + } + $this->_selectJoinSql .= $this->_getSQLTableAlias($assoc['sourceEntity']) . '.' . $sourceCol . ' = ' + . $tableAlias . '.' . $targetCol; + $first = false; + } + + // Add filter SQL + if ($filterSql = $this->generateFilterConditionSQL($eagerEntity, $tableAlias)) { + $this->_selectJoinSql .= ' AND ' . $filterSql; + } + } else { + $eagerEntity = $this->_em->getClassMetadata($assoc['targetEntity']); + $owningAssoc = $eagerEntity->getAssociationMapping($assoc['mappedBy']); + + $this->_selectJoinSql .= ' LEFT JOIN'; + $this->_selectJoinSql .= ' ' . $eagerEntity->getQuotedTableName($this->_platform) . ' ' + . $this->_getSQLTableAlias($eagerEntity->name, $assocAlias) . ' ON '; + + foreach ($owningAssoc['sourceToTargetKeyColumns'] AS $sourceCol => $targetCol) { + if ( ! $first) { + $this->_selectJoinSql .= ' AND '; + } + + $this->_selectJoinSql .= $this->_getSQLTableAlias($owningAssoc['sourceEntity'], $assocAlias) . '.' . $sourceCol . ' = ' + . $this->_getSQLTableAlias($owningAssoc['targetEntity']) . '.' . $targetCol; + $first = false; + } + } + } + } + + $this->_selectColumnListSql = $columnList; + + return $this->_selectColumnListSql; + } + + /** + * Gets the SQL join fragment used when selecting entities from an association. + * + * @param string $field + * @param array $assoc + * @param ClassMetadata $class + * @param string $alias + * + * @return string + */ + protected function _getSelectColumnAssociationSQL($field, $assoc, ClassMetadata $class, $alias = 'r') + { + $columnList = ''; + + if ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE) { + foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) { + if ($columnList) $columnList .= ', '; + + $resultColumnName = $this->getSQLColumnAlias($srcColumn); + $columnList .= $this->_getSQLTableAlias($class->name, ($alias == 'r' ? '' : $alias) ) + . '.' . $srcColumn . ' AS ' . $resultColumnName; + $this->_rsm->addMetaResult($alias, $resultColumnName, $srcColumn, isset($assoc['id']) && $assoc['id'] === true); + } + } + + return $columnList; + } + + /** + * Gets the SQL join fragment used when selecting entities from a + * many-to-many association. + * + * @param ManyToManyMapping $manyToMany + * @return string + */ + protected function _getSelectManyToManyJoinSQL(array $manyToMany) + { + if ($manyToMany['isOwningSide']) { + $owningAssoc = $manyToMany; + $joinClauses = $manyToMany['relationToTargetKeyColumns']; + } else { + $owningAssoc = $this->_em->getClassMetadata($manyToMany['targetEntity'])->associationMappings[$manyToMany['mappedBy']]; + $joinClauses = $owningAssoc['relationToSourceKeyColumns']; + } + + $joinTableName = $this->_class->getQuotedJoinTableName($owningAssoc, $this->_platform); + $joinSql = ''; + + foreach ($joinClauses as $joinTableColumn => $sourceColumn) { + if ($joinSql != '') $joinSql .= ' AND '; + + if ($this->_class->containsForeignIdentifier && ! isset($this->_class->fieldNames[$sourceColumn])) { + $quotedColumn = $sourceColumn; // join columns cannot be quoted + } else { + $quotedColumn = $this->_class->getQuotedColumnName($this->_class->fieldNames[$sourceColumn], $this->_platform); + } + + $joinSql .= $this->_getSQLTableAlias($this->_class->name) . '.' . $quotedColumn . ' = ' + . $joinTableName . '.' . $joinTableColumn; + } + + return ' INNER JOIN ' . $joinTableName . ' ON ' . $joinSql; + } + + /** + * Gets the INSERT SQL used by the persister to persist a new entity. + * + * @return string + */ + protected function _getInsertSQL() + { + if ($this->_insertSql === null) { + $insertSql = ''; + $columns = $this->_getInsertColumnList(); + + if (empty($columns)) { + $insertSql = $this->_platform->getEmptyIdentityInsertSQL( + $this->_class->getQuotedTableName($this->_platform), + $this->_class->getQuotedColumnName($this->_class->identifier[0], $this->_platform) + ); + } else { + $columns = array_unique($columns); + + $values = array(); + foreach ($columns AS $column) { + $placeholder = '?'; + + if (isset($this->_columnTypes[$column]) && + isset($this->_class->fieldNames[$column]) && + isset($this->_class->fieldMappings[$this->_class->fieldNames[$column]]['requireSQLConversion'])) { + $type = Type::getType($this->_columnTypes[$column]); + $placeholder = $type->convertToDatabaseValueSQL('?', $this->_platform); + } + + $values[] = $placeholder; + } + + $insertSql = 'INSERT INTO ' . $this->_class->getQuotedTableName($this->_platform) + . ' (' . implode(', ', $columns) . ') VALUES (' . implode(', ', $values) . ')'; + } + + $this->_insertSql = $insertSql; + } + + return $this->_insertSql; + } + + /** + * Gets the list of columns to put in the INSERT SQL statement. + * + * Subclasses should override this method to alter or change the list of + * columns placed in the INSERT statements used by the persister. + * + * @return array The list of columns. + */ + protected function _getInsertColumnList() + { + $columns = array(); + + foreach ($this->_class->reflFields as $name => $field) { + if ($this->_class->isVersioned && $this->_class->versionField == $name) { + continue; + } + + if (isset($this->_class->associationMappings[$name])) { + $assoc = $this->_class->associationMappings[$name]; + + if ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE) { + foreach ($assoc['targetToSourceKeyColumns'] as $sourceCol) { + $columns[] = $sourceCol; + } + } + } else if ($this->_class->generatorType != ClassMetadata::GENERATOR_TYPE_IDENTITY || $this->_class->identifier[0] != $name) { + $columns[] = $this->_class->getQuotedColumnName($name, $this->_platform); + $this->_columnTypes[$name] = $this->_class->fieldMappings[$name]['type']; + } + } + + return $columns; + } + + /** + * Gets the SQL snippet of a qualified column name for the given field name. + * + * @param string $field The field name. + * @param ClassMetadata $class The class that declares this field. The table this class is + * mapped to must own the column for the given field. + * @param string $alias + */ + protected function _getSelectColumnSQL($field, ClassMetadata $class, $alias = 'r') + { + $sql = $this->_getSQLTableAlias($class->name, $alias == 'r' ? '' : $alias) + . '.' . $class->getQuotedColumnName($field, $this->_platform); + $columnAlias = $this->getSQLColumnAlias($class->columnNames[$field]); + + $this->_rsm->addFieldResult($alias, $columnAlias, $field); + + if (isset($class->fieldMappings[$field]['requireSQLConversion'])) { + $type = Type::getType($class->getTypeOfField($field)); + $sql = $type->convertToPHPValueSQL($sql, $this->_platform); + } + + return $sql . ' AS ' . $columnAlias; + } + + /** + * Gets the SQL table alias for the given class name. + * + * @param string $className + * @return string The SQL table alias. + * @todo Reconsider. Binding table aliases to class names is not such a good idea. + */ + protected function _getSQLTableAlias($className, $assocName = '') + { + if ($assocName) { + $className .= '#' . $assocName; + } + + if (isset($this->_sqlTableAliases[$className])) { + return $this->_sqlTableAliases[$className]; + } + + $tableAlias = 't' . $this->_sqlAliasCounter++; + + $this->_sqlTableAliases[$className] = $tableAlias; + + return $tableAlias; + } + + /** + * Lock all rows of this entity matching the given criteria with the specified pessimistic lock mode + * + * @param array $criteria + * @param int $lockMode + * @return void + */ + public function lock(array $criteria, $lockMode) + { + $conditionSql = $this->_getSelectConditionSQL($criteria); + + if ($lockMode == LockMode::PESSIMISTIC_READ) { + $lockSql = $this->_platform->getReadLockSql(); + } else if ($lockMode == LockMode::PESSIMISTIC_WRITE) { + $lockSql = $this->_platform->getWriteLockSql(); + } + + $sql = 'SELECT 1 ' + . $this->_platform->appendLockHint($this->getLockTablesSql(), $lockMode) + . ($conditionSql ? ' WHERE ' . $conditionSql : '') . ' ' . $lockSql; + + list($params, $types) = $this->expandParameters($criteria); + + $stmt = $this->_conn->executeQuery($sql, $params, $types); + } + + /** + * Get the FROM and optionally JOIN conditions to lock the entity managed by this persister. + * + * @return string + */ + protected function getLockTablesSql() + { + return 'FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' ' + . $this->_getSQLTableAlias($this->_class->name); + } + + /** + * Gets the conditional SQL fragment used in the WHERE clause when selecting + * entities in this persister. + * + * Subclasses are supposed to override this method if they intend to change + * or alter the criteria by which entities are selected. + * + * @param array $criteria + * @param AssociationMapping $assoc + * @return string + */ + protected function _getSelectConditionSQL(array $criteria, $assoc = null) + { + $conditionSql = ''; + + foreach ($criteria as $field => $value) { + $conditionSql .= $conditionSql ? ' AND ' : ''; + + $placeholder = '?'; + + if (isset($this->_class->columnNames[$field])) { + $className = (isset($this->_class->fieldMappings[$field]['inherited'])) + ? $this->_class->fieldMappings[$field]['inherited'] + : $this->_class->name; + + $conditionSql .= $this->_getSQLTableAlias($className) . '.' . $this->_class->getQuotedColumnName($field, $this->_platform); + + if (isset($this->_class->fieldMappings[$field]['requireSQLConversion'])) { + $type = Type::getType($this->_class->getTypeOfField($field)); + $placeholder = $type->convertToDatabaseValueSQL($placeholder, $this->_platform); + } + } else if (isset($this->_class->associationMappings[$field])) { + if ( ! $this->_class->associationMappings[$field]['isOwningSide']) { + throw ORMException::invalidFindByInverseAssociation($this->_class->name, $field); + } + + $className = (isset($this->_class->associationMappings[$field]['inherited'])) + ? $this->_class->associationMappings[$field]['inherited'] + : $this->_class->name; + + $conditionSql .= $this->_getSQLTableAlias($className) . '.' . $this->_class->associationMappings[$field]['joinColumns'][0]['name']; + } else if ($assoc !== null && strpos($field, " ") === false && strpos($field, "(") === false) { + // very careless developers could potentially open up this normally hidden api for userland attacks, + // therefore checking for spaces and function calls which are not allowed. + + // found a join column condition, not really a "field" + $conditionSql .= $field; + } else { + throw ORMException::unrecognizedField($field); + } + + $conditionSql .= (is_array($value)) ? ' IN (?)' : (($value === null) ? ' IS NULL' : ' = ' . $placeholder); + } + return $conditionSql; + } + + /** + * Return an array with (sliced or full list) of elements in the specified collection. + * + * @param array $assoc + * @param object $sourceEntity + * @param int $offset + * @param int $limit + * @return array + */ + public function getOneToManyCollection(array $assoc, $sourceEntity, $offset = null, $limit = null) + { + $stmt = $this->getOneToManyStatement($assoc, $sourceEntity, $offset, $limit); + + return $this->loadArrayFromStatement($assoc, $stmt); + } + + /** + * Loads a collection of entities in a one-to-many association. + * + * @param array $assoc + * @param object $sourceEntity + * @param PersistentCollection $coll The collection to load/fill. + * @param int|null $offset + * @param int|null $limit + */ + public function loadOneToManyCollection(array $assoc, $sourceEntity, PersistentCollection $coll) + { + $stmt = $this->getOneToManyStatement($assoc, $sourceEntity); + + return $this->loadCollectionFromStatement($assoc, $stmt, $coll); + } + + /** + * Build criteria and execute SQL statement to fetch the one to many entities from. + * + * @param array $assoc + * @param object $sourceEntity + * @param int|null $offset + * @param int|null $limit + * @return \Doctrine\DBAL\Statement + */ + private function getOneToManyStatement(array $assoc, $sourceEntity, $offset = null, $limit = null) + { + $criteria = array(); + $owningAssoc = $this->_class->associationMappings[$assoc['mappedBy']]; + $sourceClass = $this->_em->getClassMetadata($assoc['sourceEntity']); + + $tableAlias = $this->_getSQLTableAlias(isset($owningAssoc['inherited']) ? $owningAssoc['inherited'] : $this->_class->name); + + foreach ($owningAssoc['targetToSourceKeyColumns'] as $sourceKeyColumn => $targetKeyColumn) { + if ($sourceClass->containsForeignIdentifier) { + $field = $sourceClass->getFieldForColumn($sourceKeyColumn); + $value = $sourceClass->reflFields[$field]->getValue($sourceEntity); + + if (isset($sourceClass->associationMappings[$field])) { + $value = $this->_em->getUnitOfWork()->getEntityIdentifier($value); + $value = $value[$this->_em->getClassMetadata($sourceClass->associationMappings[$field]['targetEntity'])->identifier[0]]; + } + + $criteria[$tableAlias . "." . $targetKeyColumn] = $value; + } else { + $criteria[$tableAlias . "." . $targetKeyColumn] = $sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity); + } + } + + $sql = $this->_getSelectEntitiesSQL($criteria, $assoc, 0, $limit, $offset); + list($params, $types) = $this->expandParameters($criteria); + + return $this->_conn->executeQuery($sql, $params, $types); + } + + /** + * Expand the parameters from the given criteria and use the correct binding types if found. + * + * @param array $criteria + * @return array + */ + private function expandParameters($criteria) + { + $params = $types = array(); + + foreach ($criteria AS $field => $value) { + if ($value === null) { + continue; // skip null values. + } + + $types[] = $this->getType($field, $value); + $params[] = $this->getValue($value); + } + + return array($params, $types); + } + + /** + * Infer field type to be used by parameter type casting. + * + * @param string $field + * @param mixed $value + * @return integer + */ + private function getType($field, $value) + { + switch (true) { + case (isset($this->_class->fieldMappings[$field])): + $type = $this->_class->fieldMappings[$field]['type']; + break; + + case (isset($this->_class->associationMappings[$field])): + $assoc = $this->_class->associationMappings[$field]; + + if (count($assoc['sourceToTargetKeyColumns']) > 1) { + throw Query\QueryException::associationPathCompositeKeyNotSupported(); + } + + $targetClass = $this->_em->getClassMetadata($assoc['targetEntity']); + $targetColumn = $assoc['joinColumns'][0]['referencedColumnName']; + $type = null; + + if (isset($targetClass->fieldNames[$targetColumn])) { + $type = $targetClass->fieldMappings[$targetClass->fieldNames[$targetColumn]]['type']; + } + + break; + + default: + $type = null; + } + if (is_array($value)) { + $type = Type::getType( $type )->getBindingType(); + $type += Connection::ARRAY_PARAM_OFFSET; + } + + return $type; + } + + /** + * Retrieve parameter value + * + * @param mixed $value + * @return mixed + */ + private function getValue($value) + { + if (is_array($value)) { + $newValue = array(); + + foreach ($value as $itemValue) { + $newValue[] = $this->getIndividualValue($itemValue); + } + + return $newValue; + } + + return $this->getIndividualValue($value); + } + + /** + * Retrieve an invidiual parameter value + * + * @param mixed $value + * @return mixed + */ + private function getIndividualValue($value) + { + if (is_object($value) && $this->_em->getMetadataFactory()->hasMetadataFor(get_class($value))) { + if ($this->_em->getUnitOfWork()->getEntityState($value) === UnitOfWork::STATE_MANAGED) { + $idValues = $this->_em->getUnitOfWork()->getEntityIdentifier($value); + } else { + $class = $this->_em->getClassMetadata(get_class($value)); + $idValues = $class->getIdentifierValues($value); + } + + $value = $idValues[key($idValues)]; + } + + return $value; + } + + /** + * Checks whether the given managed entity exists in the database. + * + * @param object $entity + * @return boolean TRUE if the entity exists in the database, FALSE otherwise. + */ + public function exists($entity, array $extraConditions = array()) + { + $criteria = $this->_class->getIdentifierValues($entity); + + if ( ! $criteria) { + return false; + } + + if ($extraConditions) { + $criteria = array_merge($criteria, $extraConditions); + } + + $alias = $this->_getSQLTableAlias($this->_class->name); + + $sql = 'SELECT 1 ' + . $this->getLockTablesSql() + . ' WHERE ' . $this->_getSelectConditionSQL($criteria); + + if ($filterSql = $this->generateFilterConditionSQL($this->_class, $alias)) { + $sql .= ' AND ' . $filterSql; + } + + list($params, $types) = $this->expandParameters($criteria); + + return (bool) $this->_conn->fetchColumn($sql, $params); + } + + /** + * Generates the appropriate join SQL for the given join column. + * + * @param array $joinColumns The join columns definition of an association. + * @return string LEFT JOIN if one of the columns is nullable, INNER JOIN otherwise. + */ + protected function getJoinSQLForJoinColumns($joinColumns) + { + // if one of the join columns is nullable, return left join + foreach ($joinColumns as $joinColumn) { + if (!isset($joinColumn['nullable']) || $joinColumn['nullable']) { + return 'LEFT JOIN'; + } + } + + return 'INNER JOIN'; + } + + /** + * Gets an SQL column alias for a column name. + * + * @param string $columnName + * @return string + */ + public function getSQLColumnAlias($columnName) + { + // Trim the column alias to the maximum identifier length of the platform. + // If the alias is to long, characters are cut off from the beginning. + return $this->_platform->getSQLResultCasing( + substr($columnName . $this->_sqlAliasCounter++, -$this->_platform->getMaxIdentifierLength()) + ); + } + + /** + * Generates the filter SQL for a given entity and table alias. + * + * @param ClassMetadata $targetEntity Metadata of the target entity. + * @param string $targetTableAlias The table alias of the joined/selected table. + * + * @return string The SQL query part to add to a query. + */ + protected function generateFilterConditionSQL(ClassMetadata $targetEntity, $targetTableAlias) + { + $filterClauses = array(); + + foreach ($this->_em->getFilters()->getEnabledFilters() as $filter) { + if ('' !== $filterExpr = $filter->addFilterConstraint($targetEntity, $targetTableAlias)) { + $filterClauses[] = '(' . $filterExpr . ')'; + } + } + + $sql = implode(' AND ', $filterClauses); + return $sql ? "(" . $sql . ")" : ""; // Wrap again to avoid "X or Y and FilterConditionSQL" + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/ElementCollectionPersister.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/ElementCollectionPersister.php new file mode 100644 index 0000000..688edeb --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/ElementCollectionPersister.php @@ -0,0 +1,33 @@ +. + */ + +namespace Doctrine\ORM\Persisters; + +/** + * Persister for collections of basic elements / value types. + * + * @author robo + * @todo Implementation once support for collections of basic elements (i.e. strings) is added. + */ +abstract class ElementCollectionPersister extends AbstractCollectionPersister +{ + //put your code here +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php new file mode 100644 index 0000000..350ced9 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php @@ -0,0 +1,487 @@ +. + */ + +namespace Doctrine\ORM\Persisters; + +use Doctrine\ORM\ORMException, + Doctrine\ORM\Mapping\ClassMetadata, + Doctrine\DBAL\LockMode, + Doctrine\DBAL\Types\Type, + Doctrine\ORM\Query\ResultSetMapping; + +/** + * The joined subclass persister maps a single entity instance to several tables in the + * database as it is defined by the Class Table Inheritance strategy. + * + * @author Roman Borschel + * @author Benjamin Eberlei + * @author Alexander + * @since 2.0 + * @see http://martinfowler.com/eaaCatalog/classTableInheritance.html + */ +class JoinedSubclassPersister extends AbstractEntityInheritancePersister +{ + /** + * Map that maps column names to the table names that own them. + * This is mainly a temporary cache, used during a single request. + * + * @var array + */ + private $_owningTableMap = array(); + + /** + * Map of table to quoted table names. + * + * @var array + */ + private $_quotedTableMap = array(); + + /** + * {@inheritdoc} + */ + protected function _getDiscriminatorColumnTableName() + { + $class = ($this->_class->name !== $this->_class->rootEntityName) + ? $this->_em->getClassMetadata($this->_class->rootEntityName) + : $this->_class; + + return $class->getTableName(); + } + + /** + * This function finds the ClassMetadata instance in an inheritance hierarchy + * that is responsible for enabling versioning. + * + * @return \Doctrine\ORM\Mapping\ClassMetadata + */ + private function _getVersionedClassMetadata() + { + if (isset($this->_class->fieldMappings[$this->_class->versionField]['inherited'])) { + $definingClassName = $this->_class->fieldMappings[$this->_class->versionField]['inherited']; + + return $this->_em->getClassMetadata($definingClassName); + } + + return $this->_class; + } + + /** + * Gets the name of the table that owns the column the given field is mapped to. + * + * @param string $fieldName + * @return string + * @override + */ + public function getOwningTable($fieldName) + { + if (isset($this->_owningTableMap[$fieldName])) { + return $this->_owningTableMap[$fieldName]; + } + + if (isset($this->_class->associationMappings[$fieldName]['inherited'])) { + $cm = $this->_em->getClassMetadata($this->_class->associationMappings[$fieldName]['inherited']); + } else if (isset($this->_class->fieldMappings[$fieldName]['inherited'])) { + $cm = $this->_em->getClassMetadata($this->_class->fieldMappings[$fieldName]['inherited']); + } else { + $cm = $this->_class; + } + + $tableName = $cm->getTableName(); + + $this->_owningTableMap[$fieldName] = $tableName; + $this->_quotedTableMap[$tableName] = $cm->getQuotedTableName($this->_platform); + + return $tableName; + } + + /** + * {@inheritdoc} + */ + public function executeInserts() + { + if ( ! $this->_queuedInserts) { + return; + } + + $postInsertIds = array(); + $idGen = $this->_class->idGenerator; + $isPostInsertId = $idGen->isPostInsertGenerator(); + + // Prepare statement for the root table + $rootClass = ($this->_class->name !== $this->_class->rootEntityName) ? $this->_em->getClassMetadata($this->_class->rootEntityName) : $this->_class; + $rootPersister = $this->_em->getUnitOfWork()->getEntityPersister($rootClass->name); + $rootTableName = $rootClass->getTableName(); + $rootTableStmt = $this->_conn->prepare($rootPersister->_getInsertSQL()); + + // Prepare statements for sub tables. + $subTableStmts = array(); + + if ($rootClass !== $this->_class) { + $subTableStmts[$this->_class->getTableName()] = $this->_conn->prepare($this->_getInsertSQL()); + } + + foreach ($this->_class->parentClasses as $parentClassName) { + $parentClass = $this->_em->getClassMetadata($parentClassName); + $parentTableName = $parentClass->getTableName(); + + if ($parentClass !== $rootClass) { + $parentPersister = $this->_em->getUnitOfWork()->getEntityPersister($parentClassName); + $subTableStmts[$parentTableName] = $this->_conn->prepare($parentPersister->_getInsertSQL()); + } + } + + // Execute all inserts. For each entity: + // 1) Insert on root table + // 2) Insert on sub tables + foreach ($this->_queuedInserts as $entity) { + $insertData = $this->_prepareInsertData($entity); + + // Execute insert on root table + $paramIndex = 1; + + foreach ($insertData[$rootTableName] as $columnName => $value) { + $rootTableStmt->bindValue($paramIndex++, $value, $this->_columnTypes[$columnName]); + } + + $rootTableStmt->execute(); + + if ($isPostInsertId) { + $id = $idGen->generate($this->_em, $entity); + $postInsertIds[$id] = $entity; + } else { + $id = $this->_em->getUnitOfWork()->getEntityIdentifier($entity); + } + + // Execute inserts on subtables. + // The order doesn't matter because all child tables link to the root table via FK. + foreach ($subTableStmts as $tableName => $stmt) { + $data = isset($insertData[$tableName]) ? $insertData[$tableName] : array(); + $paramIndex = 1; + + foreach ((array) $id as $idName => $idVal) { + $type = isset($this->_columnTypes[$idName]) ? $this->_columnTypes[$idName] : Type::STRING; + + $stmt->bindValue($paramIndex++, $idVal, $type); + } + + foreach ($data as $columnName => $value) { + $stmt->bindValue($paramIndex++, $value, $this->_columnTypes[$columnName]); + } + + $stmt->execute(); + } + } + + $rootTableStmt->closeCursor(); + + foreach ($subTableStmts as $stmt) { + $stmt->closeCursor(); + } + + if ($this->_class->isVersioned) { + $this->assignDefaultVersionValue($entity, $id); + } + + $this->_queuedInserts = array(); + + return $postInsertIds; + } + + /** + * {@inheritdoc} + */ + public function update($entity) + { + $updateData = $this->_prepareUpdateData($entity); + + if (($isVersioned = $this->_class->isVersioned) != false) { + $versionedClass = $this->_getVersionedClassMetadata(); + $versionedTable = $versionedClass->getTableName(); + } + + if ($updateData) { + foreach ($updateData as $tableName => $data) { + $this->_updateTable( + $entity, $this->_quotedTableMap[$tableName], $data, $isVersioned && $versionedTable == $tableName + ); + } + + // Make sure the table with the version column is updated even if no columns on that + // table were affected. + if ($isVersioned && ! isset($updateData[$versionedTable])) { + $this->_updateTable($entity, $versionedClass->getQuotedTableName($this->_platform), array(), true); + + $id = $this->_em->getUnitOfWork()->getEntityIdentifier($entity); + $this->assignDefaultVersionValue($entity, $id); + } + } + } + + /** + * {@inheritdoc} + */ + public function delete($entity) + { + $identifier = $this->_em->getUnitOfWork()->getEntityIdentifier($entity); + $this->deleteJoinTableRecords($identifier); + + $id = array_combine($this->_class->getIdentifierColumnNames(), $identifier); + + // If the database platform supports FKs, just + // delete the row from the root table. Cascades do the rest. + if ($this->_platform->supportsForeignKeyConstraints()) { + $this->_conn->delete( + $this->_em->getClassMetadata($this->_class->rootEntityName)->getQuotedTableName($this->_platform), $id + ); + } else { + // Delete from all tables individually, starting from this class' table up to the root table. + $this->_conn->delete($this->_class->getQuotedTableName($this->_platform), $id); + + foreach ($this->_class->parentClasses as $parentClass) { + $this->_conn->delete( + $this->_em->getClassMetadata($parentClass)->getQuotedTableName($this->_platform), $id + ); + } + } + } + + /** + * {@inheritdoc} + */ + protected function _getSelectEntitiesSQL(array $criteria, $assoc = null, $lockMode = 0, $limit = null, $offset = null, array $orderBy = null) + { + $idColumns = $this->_class->getIdentifierColumnNames(); + $baseTableAlias = $this->_getSQLTableAlias($this->_class->name); + + // Create the column list fragment only once + if ($this->_selectColumnListSql === null) { + + $this->_rsm = new ResultSetMapping(); + $this->_rsm->addEntityResult($this->_class->name, 'r'); + + // Add regular columns + $columnList = ''; + + foreach ($this->_class->fieldMappings as $fieldName => $mapping) { + if ($columnList != '') $columnList .= ', '; + + $columnList .= $this->_getSelectColumnSQL( + $fieldName, + isset($mapping['inherited']) ? $this->_em->getClassMetadata($mapping['inherited']) : $this->_class + ); + } + + // Add foreign key columns + foreach ($this->_class->associationMappings as $assoc2) { + if ($assoc2['isOwningSide'] && $assoc2['type'] & ClassMetadata::TO_ONE) { + $tableAlias = isset($assoc2['inherited']) ? $this->_getSQLTableAlias($assoc2['inherited']) : $baseTableAlias; + + foreach ($assoc2['targetToSourceKeyColumns'] as $srcColumn) { + if ($columnList != '') $columnList .= ', '; + + $columnList .= $this->getSelectJoinColumnSQL( + $tableAlias, + $srcColumn, + isset($assoc2['inherited']) ? $assoc2['inherited'] : $this->_class->name + ); + } + } + } + + // Add discriminator column (DO NOT ALIAS, see AbstractEntityInheritancePersister#_processSQLResult). + $discrColumn = $this->_class->discriminatorColumn['name']; + $tableAlias = ($this->_class->rootEntityName == $this->_class->name) ? $baseTableAlias : $this->_getSQLTableAlias($this->_class->rootEntityName); + $columnList .= ', ' . $tableAlias . '.' . $discrColumn; + + $resultColumnName = $this->_platform->getSQLResultCasing($discrColumn); + + $this->_rsm->setDiscriminatorColumn('r', $resultColumnName); + $this->_rsm->addMetaResult('r', $resultColumnName, $discrColumn); + } + + // INNER JOIN parent tables + $joinSql = ''; + + foreach ($this->_class->parentClasses as $parentClassName) { + $parentClass = $this->_em->getClassMetadata($parentClassName); + $tableAlias = $this->_getSQLTableAlias($parentClassName); + $joinSql .= ' INNER JOIN ' . $parentClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON '; + $first = true; + + foreach ($idColumns as $idColumn) { + if ($first) $first = false; else $joinSql .= ' AND '; + + $joinSql .= $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn; + } + } + + // OUTER JOIN sub tables + foreach ($this->_class->subClasses as $subClassName) { + $subClass = $this->_em->getClassMetadata($subClassName); + $tableAlias = $this->_getSQLTableAlias($subClassName); + + if ($this->_selectColumnListSql === null) { + // Add subclass columns + foreach ($subClass->fieldMappings as $fieldName => $mapping) { + if (isset($mapping['inherited'])) continue; + + $columnList .= ', ' . $this->_getSelectColumnSQL($fieldName, $subClass); + } + + // Add join columns (foreign keys) + foreach ($subClass->associationMappings as $assoc2) { + if ($assoc2['isOwningSide'] && $assoc2['type'] & ClassMetadata::TO_ONE && ! isset($assoc2['inherited'])) { + foreach ($assoc2['targetToSourceKeyColumns'] as $srcColumn) { + if ($columnList != '') $columnList .= ', '; + + $columnList .= $this->getSelectJoinColumnSQL( + $tableAlias, + $srcColumn, + isset($assoc2['inherited']) ? $assoc2['inherited'] : $subClass->name + ); + } + } + } + } + + // Add LEFT JOIN + $joinSql .= ' LEFT JOIN ' . $subClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON '; + $first = true; + + foreach ($idColumns as $idColumn) { + if ($first) $first = false; else $joinSql .= ' AND '; + + $joinSql .= $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn; + } + } + + $joinSql .= ($assoc != null && $assoc['type'] == ClassMetadata::MANY_TO_MANY) ? $this->_getSelectManyToManyJoinSQL($assoc) : ''; + + $conditionSql = $this->_getSelectConditionSQL($criteria, $assoc); + + // If the current class in the root entity, add the filters + if ($filterSql = $this->generateFilterConditionSQL($this->_em->getClassMetadata($this->_class->rootEntityName), $this->_getSQLTableAlias($this->_class->rootEntityName))) { + if ($conditionSql) { + $conditionSql .= ' AND '; + } + + $conditionSql .= $filterSql; + } + + $orderBy = ($assoc !== null && isset($assoc['orderBy'])) ? $assoc['orderBy'] : $orderBy; + $orderBySql = $orderBy ? $this->_getOrderBySQL($orderBy, $baseTableAlias) : ''; + + if ($this->_selectColumnListSql === null) { + $this->_selectColumnListSql = $columnList; + } + + $lockSql = ''; + + if ($lockMode == LockMode::PESSIMISTIC_READ) { + $lockSql = ' ' . $this->_platform->getReadLockSql(); + } else if ($lockMode == LockMode::PESSIMISTIC_WRITE) { + $lockSql = ' ' . $this->_platform->getWriteLockSql(); + } + + return $this->_platform->modifyLimitQuery('SELECT ' . $this->_selectColumnListSql + . ' FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' ' . $baseTableAlias + . $joinSql + . ($conditionSql != '' ? ' WHERE ' . $conditionSql : '') . $orderBySql, $limit, $offset) + . $lockSql; + } + + /** + * Get the FROM and optionally JOIN conditions to lock the entity managed by this persister. + * + * @return string + */ + public function getLockTablesSql() + { + $idColumns = $this->_class->getIdentifierColumnNames(); + $baseTableAlias = $this->_getSQLTableAlias($this->_class->name); + + // INNER JOIN parent tables + $joinSql = ''; + + foreach ($this->_class->parentClasses as $parentClassName) { + $parentClass = $this->_em->getClassMetadata($parentClassName); + $tableAlias = $this->_getSQLTableAlias($parentClassName); + $joinSql .= ' INNER JOIN ' . $parentClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON '; + $first = true; + + foreach ($idColumns as $idColumn) { + if ($first) $first = false; else $joinSql .= ' AND '; + + $joinSql .= $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn; + } + } + + return 'FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' ' . $baseTableAlias . $joinSql; + } + + /* Ensure this method is never called. This persister overrides _getSelectEntitiesSQL directly. */ + protected function _getSelectColumnListSQL() + { + throw new \BadMethodCallException("Illegal invocation of ".__METHOD__."."); + } + + /** {@inheritdoc} */ + protected function _getInsertColumnList() + { + // Identifier columns must always come first in the column list of subclasses. + $columns = $this->_class->parentClasses ? $this->_class->getIdentifierColumnNames() : array(); + + foreach ($this->_class->reflFields as $name => $field) { + if (isset($this->_class->fieldMappings[$name]['inherited']) && ! isset($this->_class->fieldMappings[$name]['id']) + || isset($this->_class->associationMappings[$name]['inherited']) + || ($this->_class->isVersioned && $this->_class->versionField == $name)) { + continue; + } + + if (isset($this->_class->associationMappings[$name])) { + $assoc = $this->_class->associationMappings[$name]; + if ($assoc['type'] & ClassMetadata::TO_ONE && $assoc['isOwningSide']) { + foreach ($assoc['targetToSourceKeyColumns'] as $sourceCol) { + $columns[] = $sourceCol; + } + } + } else if ($this->_class->name != $this->_class->rootEntityName || + ! $this->_class->isIdGeneratorIdentity() || $this->_class->identifier[0] != $name) { + $columns[] = $this->_class->getQuotedColumnName($name, $this->_platform); + } + } + + // Add discriminator column if it is the topmost class. + if ($this->_class->name == $this->_class->rootEntityName) { + $columns[] = $this->_class->discriminatorColumn['name']; + } + + return $columns; + } + + /** + * {@inheritdoc} + */ + protected function assignDefaultVersionValue($entity, $id) + { + $value = $this->fetchVersionValue($this->_getVersionedClassMetadata(), $id); + $this->_class->setFieldValue($entity, $this->_class->versionField, $value); + } + +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php new file mode 100644 index 0000000..daef037 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php @@ -0,0 +1,425 @@ +. + */ + +namespace Doctrine\ORM\Persisters; + +use Doctrine\ORM\Mapping\ClassMetadata, + Doctrine\ORM\PersistentCollection, + Doctrine\ORM\UnitOfWork; + +/** + * Persister for many-to-many collections. + * + * @author Roman Borschel + * @author Guilherme Blanco + * @author Alexander + * @since 2.0 + */ +class ManyToManyPersister extends AbstractCollectionPersister +{ + /** + * {@inheritdoc} + * + * @override + */ + protected function _getDeleteRowSQL(PersistentCollection $coll) + { + $mapping = $coll->getMapping(); + $class = $this->_em->getClassMetadata(get_class($coll->getOwner())); + + return 'DELETE FROM ' . $class->getQuotedJoinTableName($mapping, $this->_conn->getDatabasePlatform()) + . ' WHERE ' . implode(' = ? AND ', $mapping['joinTableColumns']) . ' = ?'; + } + + /** + * {@inheritdoc} + * + * @override + * @internal Order of the parameters must be the same as the order of the columns in + * _getDeleteRowSql. + */ + protected function _getDeleteRowSQLParameters(PersistentCollection $coll, $element) + { + return $this->_collectJoinTableColumnParameters($coll, $element); + } + + /** + * {@inheritdoc} + * + * @override + */ + protected function _getUpdateRowSQL(PersistentCollection $coll) + {} + + /** + * {@inheritdoc} + * + * @override + * @internal Order of the parameters must be the same as the order of the columns in + * _getInsertRowSql. + */ + protected function _getInsertRowSQL(PersistentCollection $coll) + { + $mapping = $coll->getMapping(); + $columns = $mapping['joinTableColumns']; + $class = $this->_em->getClassMetadata(get_class($coll->getOwner())); + + $joinTable = $class->getQuotedJoinTableName($mapping, $this->_conn->getDatabasePlatform()); + + return 'INSERT INTO ' . $joinTable . ' (' . implode(', ', $columns) . ')' + . ' VALUES (' . implode(', ', array_fill(0, count($columns), '?')) . ')'; + } + + /** + * {@inheritdoc} + * + * @override + * @internal Order of the parameters must be the same as the order of the columns in + * _getInsertRowSql. + */ + protected function _getInsertRowSQLParameters(PersistentCollection $coll, $element) + { + return $this->_collectJoinTableColumnParameters($coll, $element); + } + + /** + * Collects the parameters for inserting/deleting on the join table in the order + * of the join table columns as specified in ManyToManyMapping#joinTableColumns. + * + * @param $coll + * @param $element + * @return array + */ + private function _collectJoinTableColumnParameters(PersistentCollection $coll, $element) + { + $params = array(); + $mapping = $coll->getMapping(); + $isComposite = count($mapping['joinTableColumns']) > 2; + + $identifier1 = $this->_uow->getEntityIdentifier($coll->getOwner()); + $identifier2 = $this->_uow->getEntityIdentifier($element); + + if ($isComposite) { + $class1 = $this->_em->getClassMetadata(get_class($coll->getOwner())); + $class2 = $coll->getTypeClass(); + } + + foreach ($mapping['joinTableColumns'] as $joinTableColumn) { + $isRelationToSource = isset($mapping['relationToSourceKeyColumns'][$joinTableColumn]); + + if ( ! $isComposite) { + $params[] = $isRelationToSource ? array_pop($identifier1) : array_pop($identifier2); + + continue; + } + + if ($isRelationToSource) { + $params[] = $identifier1[$class1->getFieldForColumn($mapping['relationToSourceKeyColumns'][$joinTableColumn])]; + + continue; + } + + $params[] = $identifier2[$class2->getFieldForColumn($mapping['relationToTargetKeyColumns'][$joinTableColumn])]; + } + + return $params; + } + + /** + * {@inheritdoc} + * + * @override + */ + protected function _getDeleteSQL(PersistentCollection $coll) + { + $class = $this->_em->getClassMetadata(get_class($coll->getOwner())); + $mapping = $coll->getMapping(); + + return 'DELETE FROM ' . $class->getQuotedJoinTableName($mapping, $this->_conn->getDatabasePlatform()) + . ' WHERE ' . implode(' = ? AND ', array_keys($mapping['relationToSourceKeyColumns'])) . ' = ?'; + } + + /** + * {@inheritdoc} + * + * @override + * @internal Order of the parameters must be the same as the order of the columns in + * _getDeleteSql. + */ + protected function _getDeleteSQLParameters(PersistentCollection $coll) + { + $identifier = $this->_uow->getEntityIdentifier($coll->getOwner()); + $mapping = $coll->getMapping(); + $params = array(); + + // Optimization for single column identifier + if (count($mapping['relationToSourceKeyColumns']) === 1) { + $params[] = array_pop($identifier); + + return $params; + } + + // Composite identifier + $sourceClass = $this->_em->getClassMetadata(get_class($mapping->getOwner())); + + foreach ($mapping['relationToSourceKeyColumns'] as $relColumn => $srcColumn) { + $params[] = $identifier[$sourceClass->fieldNames[$srcColumn]]; + } + + return $params; + } + + /** + * {@inheritdoc} + */ + public function count(PersistentCollection $coll) + { + $mapping = $filterMapping = $coll->getMapping(); + $class = $this->_em->getClassMetadata($mapping['sourceEntity']); + $id = $this->_em->getUnitOfWork()->getEntityIdentifier($coll->getOwner()); + + if ($mapping['isOwningSide']) { + $joinColumns = $mapping['relationToSourceKeyColumns']; + } else { + $mapping = $this->_em->getClassMetadata($mapping['targetEntity'])->associationMappings[$mapping['mappedBy']]; + $joinColumns = $mapping['relationToTargetKeyColumns']; + } + + $whereClauses = array(); + $params = array(); + + foreach ($mapping['joinTableColumns'] as $joinTableColumn) { + if ( ! isset($joinColumns[$joinTableColumn])) { + continue; + } + + $whereClauses[] = $joinTableColumn . ' = ?'; + + $params[] = ($class->containsForeignIdentifier) + ? $id[$class->getFieldForColumn($joinColumns[$joinTableColumn])] + : $id[$class->fieldNames[$joinColumns[$joinTableColumn]]]; + } + + list($joinTargetEntitySQL, $filterSql) = $this->getFilterSql($filterMapping); + if ($filterSql) { + $whereClauses[] = $filterSql; + } + + $sql = 'SELECT COUNT(*)' + . ' FROM ' . $class->getQuotedJoinTableName($mapping, $this->_conn->getDatabasePlatform()) . ' t' + . $joinTargetEntitySQL + . ' WHERE ' . implode(' AND ', $whereClauses); + + return $this->_conn->fetchColumn($sql, $params); + } + + /** + * @param PersistentCollection $coll + * @param int $offset + * @param int $length + * @return array + */ + public function slice(PersistentCollection $coll, $offset, $length = null) + { + $mapping = $coll->getMapping(); + + return $this->_em->getUnitOfWork()->getEntityPersister($mapping['targetEntity'])->getManyToManyCollection($mapping, $coll->getOwner(), $offset, $length); + } + + /** + * @param PersistentCollection $coll + * @param object $element + * @return boolean + */ + public function contains(PersistentCollection $coll, $element) + { + $uow = $this->_em->getUnitOfWork(); + + // Shortcut for new entities + $entityState = $uow->getEntityState($element, UnitOfWork::STATE_NEW); + + if ($entityState === UnitOfWork::STATE_NEW) { + return false; + } + + // Entity is scheduled for inclusion + if ($entityState === UnitOfWork::STATE_MANAGED && $uow->isScheduledForInsert($element)) { + return false; + } + + list($quotedJoinTable, $whereClauses, $params) = $this->getJoinTableRestrictions($coll, $element, true); + + $sql = 'SELECT 1 FROM ' . $quotedJoinTable . ' WHERE ' . implode(' AND ', $whereClauses); + + return (bool) $this->_conn->fetchColumn($sql, $params); + } + + /** + * @param PersistentCollection $coll + * @param object $element + * @return boolean + */ + public function removeElement(PersistentCollection $coll, $element) + { + $uow = $this->_em->getUnitOfWork(); + + // shortcut for new entities + $entityState = $uow->getEntityState($element, UnitOfWork::STATE_NEW); + + if ($entityState === UnitOfWork::STATE_NEW) { + return false; + } + + // If Entity is scheduled for inclusion, it is not in this collection. + // We can assure that because it would have return true before on array check + if ($entityState === UnitOfWork::STATE_MANAGED && $uow->isScheduledForInsert($element)) { + return false; + } + + list($quotedJoinTable, $whereClauses, $params) = $this->getJoinTableRestrictions($coll, $element, false); + + $sql = 'DELETE FROM ' . $quotedJoinTable . ' WHERE ' . implode(' AND ', $whereClauses); + + return (bool) $this->_conn->executeUpdate($sql, $params); + } + + /** + * @param \Doctrine\ORM\PersistentCollection $coll + * @param object $element + * @param boolean $addFilters Whether the filter SQL should be included or not. + * @return array + */ + private function getJoinTableRestrictions(PersistentCollection $coll, $element, $addFilters) + { + $uow = $this->_em->getUnitOfWork(); + $mapping = $filterMapping = $coll->getMapping(); + + if ( ! $mapping['isOwningSide']) { + $sourceClass = $this->_em->getClassMetadata($mapping['targetEntity']); + $targetClass = $this->_em->getClassMetadata($mapping['sourceEntity']); + $sourceId = $uow->getEntityIdentifier($element); + $targetId = $uow->getEntityIdentifier($coll->getOwner()); + + $mapping = $sourceClass->associationMappings[$mapping['mappedBy']]; + } else { + $sourceClass = $this->_em->getClassMetadata($mapping['sourceEntity']); + $targetClass = $this->_em->getClassMetadata($mapping['targetEntity']); + $sourceId = $uow->getEntityIdentifier($coll->getOwner()); + $targetId = $uow->getEntityIdentifier($element); + } + + $quotedJoinTable = $sourceClass->getQuotedJoinTableName($mapping, $this->_conn->getDatabasePlatform()); + $whereClauses = array(); + $params = array(); + + foreach ($mapping['joinTableColumns'] as $joinTableColumn) { + $whereClauses[] = $joinTableColumn . ' = ?'; + + if (isset($mapping['relationToTargetKeyColumns'][$joinTableColumn])) { + $params[] = ($targetClass->containsForeignIdentifier) + ? $targetId[$targetClass->getFieldForColumn($mapping['relationToTargetKeyColumns'][$joinTableColumn])] + : $targetId[$targetClass->fieldNames[$mapping['relationToTargetKeyColumns'][$joinTableColumn]]]; + continue; + } + + // relationToSourceKeyColumns + $params[] = ($sourceClass->containsForeignIdentifier) + ? $sourceId[$sourceClass->getFieldForColumn($mapping['relationToSourceKeyColumns'][$joinTableColumn])] + : $sourceId[$sourceClass->fieldNames[$mapping['relationToSourceKeyColumns'][$joinTableColumn]]]; + } + + if ($addFilters) { + list($joinTargetEntitySQL, $filterSql) = $this->getFilterSql($filterMapping); + if ($filterSql) { + $quotedJoinTable .= ' t ' . $joinTargetEntitySQL; + $whereClauses[] = $filterSql; + } + } + + return array($quotedJoinTable, $whereClauses, $params); + } + + /** + * Generates the filter SQL for a given mapping. + * + * This method is not used for actually grabbing the related entities + * but when the extra-lazy collection methods are called on a filtered + * association. This is why besides the many to many table we also + * have to join in the actual entities table leading to additional + * JOIN. + * + * @param array $mapping Array containing mapping information. + * + * @return string The SQL query part to add to a query. + */ + public function getFilterSql($mapping) + { + $targetClass = $this->_em->getClassMetadata($mapping['targetEntity']); + + if ($mapping['isOwningSide']) { + $joinColumns = $mapping['relationToTargetKeyColumns']; + } else { + $mapping = $targetClass->associationMappings[$mapping['mappedBy']]; + $joinColumns = $mapping['relationToSourceKeyColumns']; + } + + $targetClass = $this->_em->getClassMetadata($targetClass->rootEntityName); + + // A join is needed if there is filtering on the target entity + $joinTargetEntitySQL = ''; + if ($filterSql = $this->generateFilterConditionSQL($targetClass, 'te')) { + $joinTargetEntitySQL = ' JOIN ' + . $targetClass->getQuotedTableName($this->_conn->getDatabasePlatform()) . ' te' + . ' ON'; + + $joinTargetEntitySQLClauses = array(); + foreach ($joinColumns as $joinTableColumn => $targetTableColumn) { + $joinTargetEntitySQLClauses[] = ' t.' . $joinTableColumn . ' = ' . 'te.' . $targetTableColumn; + } + + $joinTargetEntitySQL .= implode(' AND ', $joinTargetEntitySQLClauses); + } + + return array($joinTargetEntitySQL, $filterSql); + } + + /** + * Generates the filter SQL for a given entity and table alias. + * + * @param ClassMetadata $targetEntity Metadata of the target entity. + * @param string $targetTableAlias The table alias of the joined/selected table. + * + * @return string The SQL query part to add to a query. + */ + protected function generateFilterConditionSQL(ClassMetadata $targetEntity, $targetTableAlias) + { + $filterClauses = array(); + + foreach ($this->_em->getFilters()->getEnabledFilters() as $filter) { + if ($filterExpr = $filter->addFilterConstraint($targetEntity, $targetTableAlias)) { + $filterClauses[] = '(' . $filterExpr . ')'; + } + } + + $sql = implode(' AND ', $filterClauses); + return $sql ? "(" . $sql . ")" : ""; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/OneToManyPersister.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/OneToManyPersister.php new file mode 100644 index 0000000..6f477f0 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/OneToManyPersister.php @@ -0,0 +1,212 @@ +. + */ + +namespace Doctrine\ORM\Persisters; + +use Doctrine\ORM\PersistentCollection, + Doctrine\ORM\UnitOfWork; + +/** + * Persister for one-to-many collections. + * + * @author Roman Borschel + * @author Guilherme Blanco + * @author Alexander + * @since 2.0 + */ +class OneToManyPersister extends AbstractCollectionPersister +{ + /** + * Generates the SQL UPDATE that updates a particular row's foreign + * key to null. + * + * @param PersistentCollection $coll + * @return string + * @override + */ + protected function _getDeleteRowSQL(PersistentCollection $coll) + { + $mapping = $coll->getMapping(); + $class = $this->_em->getClassMetadata($mapping['targetEntity']); + + return 'DELETE FROM ' . $class->getQuotedTableName($this->_conn->getDatabasePlatform()) + . ' WHERE ' . implode('= ? AND ', $class->getIdentifierColumnNames()) . ' = ?'; + } + + /** + * {@inheritdoc} + * + */ + protected function _getDeleteRowSQLParameters(PersistentCollection $coll, $element) + { + return array_values($this->_uow->getEntityIdentifier($element)); + } + + protected function _getInsertRowSQL(PersistentCollection $coll) + { + return "UPDATE xxx SET foreign_key = yyy WHERE foreign_key = zzz"; + } + + /** + * Gets the SQL parameters for the corresponding SQL statement to insert the given + * element of the given collection into the database. + * + * @param PersistentCollection $coll + * @param mixed $element + */ + protected function _getInsertRowSQLParameters(PersistentCollection $coll, $element) + {} + + /* Not used for OneToManyPersister */ + protected function _getUpdateRowSQL(PersistentCollection $coll) + { + return; + } + + /** + * Generates the SQL UPDATE that updates all the foreign keys to null. + * + * @param PersistentCollection $coll + */ + protected function _getDeleteSQL(PersistentCollection $coll) + { + + } + + /** + * Gets the SQL parameters for the corresponding SQL statement to delete + * the given collection. + * + * @param PersistentCollection $coll + */ + protected function _getDeleteSQLParameters(PersistentCollection $coll) + {} + + /** + * {@inheritdoc} + */ + public function count(PersistentCollection $coll) + { + $mapping = $coll->getMapping(); + $targetClass = $this->_em->getClassMetadata($mapping['targetEntity']); + $sourceClass = $this->_em->getClassMetadata($mapping['sourceEntity']); + $id = $this->_em->getUnitOfWork()->getEntityIdentifier($coll->getOwner()); + + $whereClauses = array(); + $params = array(); + + foreach ($targetClass->associationMappings[$mapping['mappedBy']]['joinColumns'] AS $joinColumn) { + $whereClauses[] = $joinColumn['name'] . ' = ?'; + + $params[] = ($targetClass->containsForeignIdentifier) + ? $id[$sourceClass->getFieldForColumn($joinColumn['referencedColumnName'])] + : $id[$sourceClass->fieldNames[$joinColumn['referencedColumnName']]]; + } + + $filterTargetClass = $this->_em->getClassMetadata($targetClass->rootEntityName); + foreach ($this->_em->getFilters()->getEnabledFilters() as $filter) { + if ($filterExpr = $filter->addFilterConstraint($filterTargetClass, 't')) { + $whereClauses[] = '(' . $filterExpr . ')'; + } + } + + $sql = 'SELECT count(*)' + . ' FROM ' . $targetClass->getQuotedTableName($this->_conn->getDatabasePlatform()) . ' t' + . ' WHERE ' . implode(' AND ', $whereClauses); + + return $this->_conn->fetchColumn($sql, $params); + } + + /** + * @param PersistentCollection $coll + * @param int $offset + * @param int $length + * @return \Doctrine\Common\Collections\ArrayCollection + */ + public function slice(PersistentCollection $coll, $offset, $length = null) + { + $mapping = $coll->getMapping(); + $uow = $this->_em->getUnitOfWork(); + $persister = $uow->getEntityPersister($mapping['targetEntity']); + + return $persister->getOneToManyCollection($mapping, $coll->getOwner(), $offset, $length); + } + + /** + * @param PersistentCollection $coll + * @param object $element + * @return boolean + */ + public function contains(PersistentCollection $coll, $element) + { + $mapping = $coll->getMapping(); + $uow = $this->_em->getUnitOfWork(); + + // shortcut for new entities + $entityState = $uow->getEntityState($element, UnitOfWork::STATE_NEW); + + if ($entityState === UnitOfWork::STATE_NEW) { + return false; + } + + // Entity is scheduled for inclusion + if ($entityState === UnitOfWork::STATE_MANAGED && $uow->isScheduledForInsert($element)) { + return false; + } + + $persister = $uow->getEntityPersister($mapping['targetEntity']); + + // only works with single id identifier entities. Will throw an + // exception in Entity Persisters if that is not the case for the + // 'mappedBy' field. + $id = current( $uow->getEntityIdentifier($coll->getOwner())); + + return $persister->exists($element, array($mapping['mappedBy'] => $id)); + } + + /** + * @param PersistentCollection $coll + * @param object $element + * @return boolean + */ + public function removeElement(PersistentCollection $coll, $element) + { + $uow = $this->_em->getUnitOfWork(); + + // shortcut for new entities + $entityState = $uow->getEntityState($element, UnitOfWork::STATE_NEW); + + if ($entityState === UnitOfWork::STATE_NEW) { + return false; + } + + // If Entity is scheduled for inclusion, it is not in this collection. + // We can assure that because it would have return true before on array check + if ($entityState === UnitOfWork::STATE_MANAGED && $uow->isScheduledForInsert($element)) { + return false; + } + + $mapping = $coll->getMapping(); + $class = $this->_em->getClassMetadata($mapping['targetEntity']); + $sql = 'DELETE FROM ' . $class->getQuotedTableName($this->_conn->getDatabasePlatform()) + . ' WHERE ' . implode('= ? AND ', $class->getIdentifierColumnNames()) . ' = ?'; + + return (bool) $this->_conn->executeUpdate($sql, $this->_getDeleteRowSQLParameters($coll, $element)); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/SingleTablePersister.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/SingleTablePersister.php new file mode 100644 index 0000000..8644e1d --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/SingleTablePersister.php @@ -0,0 +1,146 @@ +. + */ + +namespace Doctrine\ORM\Persisters; + +use Doctrine\ORM\Mapping\ClassMetadata; + +/** + * Persister for entities that participate in a hierarchy mapped with the + * SINGLE_TABLE strategy. + * + * @author Roman Borschel + * @author Benjamin Eberlei + * @author Alexander + * @since 2.0 + * @link http://martinfowler.com/eaaCatalog/singleTableInheritance.html + */ +class SingleTablePersister extends AbstractEntityInheritancePersister +{ + /** {@inheritdoc} */ + protected function _getDiscriminatorColumnTableName() + { + return $this->_class->getTableName(); + } + + /** {@inheritdoc} */ + protected function _getSelectColumnListSQL() + { + if ($this->_selectColumnListSql !== null) { + return $this->_selectColumnListSql; + } + + $columnList = parent::_getSelectColumnListSQL(); + + $rootClass = $this->_em->getClassMetadata($this->_class->rootEntityName); + $tableAlias = $this->_getSQLTableAlias($rootClass->name); + + // Append discriminator column + $discrColumn = $this->_class->discriminatorColumn['name']; + $columnList .= ', ' . $tableAlias . '.' . $discrColumn; + + $resultColumnName = $this->_platform->getSQLResultCasing($discrColumn); + + $this->_rsm->setDiscriminatorColumn('r', $resultColumnName); + $this->_rsm->addMetaResult('r', $resultColumnName, $discrColumn); + + // Append subclass columns + foreach ($this->_class->subClasses as $subClassName) { + $subClass = $this->_em->getClassMetadata($subClassName); + + // Regular columns + foreach ($subClass->fieldMappings as $fieldName => $mapping) { + if ( ! isset($mapping['inherited'])) { + $columnList .= ', ' . $this->_getSelectColumnSQL($fieldName, $subClass); + } + } + + // Foreign key columns + foreach ($subClass->associationMappings as $assoc) { + if ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE && ! isset($assoc['inherited'])) { + foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) { + if ($columnList != '') $columnList .= ', '; + + $columnList .= $this->getSelectJoinColumnSQL( + $tableAlias, + $srcColumn, + isset($assoc['inherited']) ? $assoc['inherited'] : $this->_class->name + ); + } + } + } + } + + $this->_selectColumnListSql = $columnList; + return $this->_selectColumnListSql; + } + + /** {@inheritdoc} */ + protected function _getInsertColumnList() + { + $columns = parent::_getInsertColumnList(); + + // Add discriminator column to the INSERT SQL + $columns[] = $this->_class->discriminatorColumn['name']; + + return $columns; + } + + /** {@inheritdoc} */ + protected function _getSQLTableAlias($className, $assocName = '') + { + return parent::_getSQLTableAlias($this->_class->rootEntityName, $assocName); + } + + /** {@inheritdoc} */ + protected function _getSelectConditionSQL(array $criteria, $assoc = null) + { + $conditionSql = parent::_getSelectConditionSQL($criteria, $assoc); + + // Append discriminator condition + if ($conditionSql) $conditionSql .= ' AND '; + + $values = array(); + + if ($this->_class->discriminatorValue !== null) { // discriminators can be 0 + $values[] = $this->_conn->quote($this->_class->discriminatorValue); + } + + $discrValues = array_flip($this->_class->discriminatorMap); + + foreach ($this->_class->subClasses as $subclassName) { + $values[] = $this->_conn->quote($discrValues[$subclassName]); + } + + $conditionSql .= $this->_getSQLTableAlias($this->_class->name) . '.' . $this->_class->discriminatorColumn['name'] + . ' IN (' . implode(', ', $values) . ')'; + + return $conditionSql; + } + + /** {@inheritdoc} */ + protected function generateFilterConditionSQL(ClassMetadata $targetEntity, $targetTableAlias) + { + // Ensure that the filters are applied to the root entity of the inheritance tree + $targetEntity = $this->_em->getClassMetadata($targetEntity->rootEntityName); + // we dont care about the $targetTableAlias, in a STI there is only one table. + + return parent::generateFilterConditionSQL($targetEntity, $targetTableAlias); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/UnionSubclassPersister.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/UnionSubclassPersister.php new file mode 100644 index 0000000..ef844a7 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/UnionSubclassPersister.php @@ -0,0 +1,8 @@ +. +*/ + +namespace Doctrine\ORM; + +/** + * Pessimistic Lock Exception + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 1.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Roman Borschel + */ +class PessimisticLockException extends ORMException +{ + public static function lockFailed() + { + return new self("The pessimistic lock failed."); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Proxy/Autoloader.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Proxy/Autoloader.php new file mode 100644 index 0000000..876b3f2 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Proxy/Autoloader.php @@ -0,0 +1,78 @@ +. + */ + +namespace Doctrine\ORM\Proxy; + +/** + * Special Autoloader for Proxy classes because them not being PSR-0 compatible. + * + * @author Benjamin Eberlei + */ +class Autoloader +{ + /** + * Resolve proxy class name to a filename based on the following pattern. + * + * 1. Remove Proxy namespace from class name + * 2. Remove namespace seperators from remaining class name. + * 3. Return PHP filename from proxy-dir with the result from 2. + * + * @param string $proxyDir + * @param string $proxyNamespace + * @param string $className + * @return string + */ + static public function resolveFile($proxyDir, $proxyNamespace, $className) + { + if (0 !== strpos($className, $proxyNamespace)) { + throw ProxyException::notProxyClass($className, $proxyNamespace); + } + + $className = str_replace('\\', '', substr($className, strlen($proxyNamespace) +1)); + return $proxyDir . DIRECTORY_SEPARATOR . $className.'.php'; + } + + /** + * Register and return autoloader callback for the given proxy dir and + * namespace. + * + * @param string $proxyDir + * @param string $proxyNamespace + * @param Closure $notFoundCallback Invoked when the proxy file is not found. + * @return Closure + */ + static public function register($proxyDir, $proxyNamespace, \Closure $notFoundCallback = null) + { + $proxyNamespace = ltrim($proxyNamespace, "\\"); + $autoloader = function($className) use ($proxyDir, $proxyNamespace, $notFoundCallback) { + if (0 === strpos($className, $proxyNamespace)) { + $file = Autoloader::resolveFile($proxyDir, $proxyNamespace, $className); + + if ($notFoundCallback && ! file_exists($file)) { + $notFoundCallback($proxyDir, $proxyNamespace, $className); + } + + require $file; + } + }; + spl_autoload_register($autoloader); + return $autoloader; + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Proxy/Proxy.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Proxy/Proxy.php new file mode 100644 index 0000000..09e2b33 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Proxy/Proxy.php @@ -0,0 +1,30 @@ +. + */ + +namespace Doctrine\ORM\Proxy; + +use Doctrine\Common\Persistence\Proxy as BaseProxy; + +/** + * Interface for proxy classes. + * + * @author Roman Borschel + * @since 2.0 + */ +interface Proxy extends BaseProxy {} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Proxy/ProxyException.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Proxy/ProxyException.php new file mode 100644 index 0000000..2196412 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Proxy/ProxyException.php @@ -0,0 +1,51 @@ +. +*/ + +namespace Doctrine\ORM\Proxy; + +/** + * ORM Proxy Exception + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 1.0 + * @version $Revision$ + * @author Benjamin Eberlei + */ +class ProxyException extends \Doctrine\ORM\ORMException { + + public static function proxyDirectoryRequired() { + return new self("You must configure a proxy directory. See docs for details"); + } + + public static function proxyNamespaceRequired() { + return new self("You must configure a proxy namespace. See docs for details"); + } + + public static function notProxyClass($className, $proxyNamespace) + { + return new self(sprintf( + "The class %s is not part of the proxy namespace %s", + $className, $proxyNamespace + )); + } + +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Proxy/ProxyFactory.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Proxy/ProxyFactory.php new file mode 100644 index 0000000..be94c1d --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Proxy/ProxyFactory.php @@ -0,0 +1,403 @@ +. + */ + +namespace Doctrine\ORM\Proxy; + +use Doctrine\ORM\EntityManager, + Doctrine\ORM\Mapping\ClassMetadata, + Doctrine\ORM\Mapping\AssociationMapping, + Doctrine\Common\Util\ClassUtils; + +/** + * This factory is used to create proxy objects for entities at runtime. + * + * @author Roman Borschel + * @author Giorgio Sironi + * @since 2.0 + */ +class ProxyFactory +{ + /** The EntityManager this factory is bound to. */ + private $_em; + /** Whether to automatically (re)generate proxy classes. */ + private $_autoGenerate; + /** The namespace that contains all proxy classes. */ + private $_proxyNamespace; + /** The directory that contains all proxy classes. */ + private $_proxyDir; + + /** + * Used to match very simple id methods that don't need + * to be proxied since the identifier is known. + * + * @var string + */ + const PATTERN_MATCH_ID_METHOD = '((public\s)?(function\s{1,}%s\s?\(\)\s{1,})\s{0,}{\s{0,}return\s{0,}\$this->%s;\s{0,}})i'; + + /** + * Initializes a new instance of the ProxyFactory class that is + * connected to the given EntityManager. + * + * @param EntityManager $em The EntityManager the new factory works for. + * @param string $proxyDir The directory to use for the proxy classes. It must exist. + * @param string $proxyNs The namespace to use for the proxy classes. + * @param boolean $autoGenerate Whether to automatically generate proxy classes. + */ + public function __construct(EntityManager $em, $proxyDir, $proxyNs, $autoGenerate = false) + { + if ( ! $proxyDir) { + throw ProxyException::proxyDirectoryRequired(); + } + if ( ! $proxyNs) { + throw ProxyException::proxyNamespaceRequired(); + } + $this->_em = $em; + $this->_proxyDir = $proxyDir; + $this->_autoGenerate = $autoGenerate; + $this->_proxyNamespace = $proxyNs; + } + + /** + * Gets a reference proxy instance for the entity of the given type and identified by + * the given identifier. + * + * @param string $className + * @param mixed $identifier + * @return object + */ + public function getProxy($className, $identifier) + { + $fqn = ClassUtils::generateProxyClassName($className, $this->_proxyNamespace); + + if (! class_exists($fqn, false)) { + $fileName = $this->getProxyFileName($className); + if ($this->_autoGenerate) { + $this->_generateProxyClass($this->_em->getClassMetadata($className), $fileName, self::$_proxyClassTemplate); + } + require $fileName; + } + + if ( ! $this->_em->getMetadataFactory()->hasMetadataFor($fqn)) { + $this->_em->getMetadataFactory()->setMetadataFor($fqn, $this->_em->getClassMetadata($className)); + } + + $entityPersister = $this->_em->getUnitOfWork()->getEntityPersister($className); + + return new $fqn($entityPersister, $identifier); + } + + /** + * Generate the Proxy file name + * + * @param string $className + * @param string $baseDir Optional base directory for proxy file name generation. + * If not specified, the directory configured on the Configuration of the + * EntityManager will be used by this factory. + * @return string + */ + private function getProxyFileName($className, $baseDir = null) + { + $proxyDir = $baseDir ?: $this->_proxyDir; + + return $proxyDir . DIRECTORY_SEPARATOR . '__CG__' . str_replace('\\', '', $className) . '.php'; + } + + /** + * Generates proxy classes for all given classes. + * + * @param array $classes The classes (ClassMetadata instances) for which to generate proxies. + * @param string $toDir The target directory of the proxy classes. If not specified, the + * directory configured on the Configuration of the EntityManager used + * by this factory is used. + * @return int Number of generated proxies. + */ + public function generateProxyClasses(array $classes, $toDir = null) + { + $proxyDir = $toDir ?: $this->_proxyDir; + $proxyDir = rtrim($proxyDir, DIRECTORY_SEPARATOR); + $num = 0; + + foreach ($classes as $class) { + /* @var $class ClassMetadata */ + if ($class->isMappedSuperclass || $class->reflClass->isAbstract()) { + continue; + } + + $proxyFileName = $this->getProxyFileName($class->name, $proxyDir); + + $this->_generateProxyClass($class, $proxyFileName, self::$_proxyClassTemplate); + $num++; + } + + return $num; + } + + /** + * Generates a proxy class file. + * + * @param $class + * @param $proxyClassName + * @param $file The path of the file to write to. + */ + private function _generateProxyClass($class, $fileName, $file) + { + $methods = $this->_generateMethods($class); + $sleepImpl = $this->_generateSleep($class); + $cloneImpl = $class->reflClass->hasMethod('__clone') ? 'parent::__clone();' : ''; // hasMethod() checks case-insensitive + + $placeholders = array( + '', + '', '', + '', '', '' + ); + + $className = ltrim($class->name, '\\'); + $proxyClassName = ClassUtils::generateProxyClassName($class->name, $this->_proxyNamespace); + $parts = explode('\\', strrev($proxyClassName), 2); + $proxyClassNamespace = strrev($parts[1]); + $proxyClassName = strrev($parts[0]); + + $replacements = array( + $proxyClassNamespace, + $proxyClassName, + $className, + $methods, + $sleepImpl, + $cloneImpl + ); + + $file = str_replace($placeholders, $replacements, $file); + + file_put_contents($fileName, $file, LOCK_EX); + } + + /** + * Generates the methods of a proxy class. + * + * @param ClassMetadata $class + * @return string The code of the generated methods. + */ + private function _generateMethods(ClassMetadata $class) + { + $methods = ''; + + $methodNames = array(); + foreach ($class->reflClass->getMethods() as $method) { + /* @var $method ReflectionMethod */ + if ($method->isConstructor() || in_array(strtolower($method->getName()), array("__sleep", "__clone")) || isset($methodNames[$method->getName()])) { + continue; + } + $methodNames[$method->getName()] = true; + + if ($method->isPublic() && ! $method->isFinal() && ! $method->isStatic()) { + $methods .= "\n" . ' public function '; + if ($method->returnsReference()) { + $methods .= '&'; + } + $methods .= $method->getName() . '('; + $firstParam = true; + $parameterString = $argumentString = ''; + + foreach ($method->getParameters() as $param) { + if ($firstParam) { + $firstParam = false; + } else { + $parameterString .= ', '; + $argumentString .= ', '; + } + + // We need to pick the type hint class too + if (($paramClass = $param->getClass()) !== null) { + $parameterString .= '\\' . $paramClass->getName() . ' '; + } else if ($param->isArray()) { + $parameterString .= 'array '; + } + + if ($param->isPassedByReference()) { + $parameterString .= '&'; + } + + $parameterString .= '$' . $param->getName(); + $argumentString .= '$' . $param->getName(); + + if ($param->isDefaultValueAvailable()) { + $parameterString .= ' = ' . var_export($param->getDefaultValue(), true); + } + } + + $methods .= $parameterString . ')'; + $methods .= "\n" . ' {' . "\n"; + if ($this->isShortIdentifierGetter($method, $class)) { + $identifier = lcfirst(substr($method->getName(), 3)); + + $cast = in_array($class->fieldMappings[$identifier]['type'], array('integer', 'smallint')) ? '(int) ' : ''; + + $methods .= ' if ($this->__isInitialized__ === false) {' . "\n"; + $methods .= ' return ' . $cast . '$this->_identifier["' . $identifier . '"];' . "\n"; + $methods .= ' }' . "\n"; + } + $methods .= ' $this->__load();' . "\n"; + $methods .= ' return parent::' . $method->getName() . '(' . $argumentString . ');'; + $methods .= "\n" . ' }' . "\n"; + } + } + + return $methods; + } + + /** + * Check if the method is a short identifier getter. + * + * What does this mean? For proxy objects the identifier is already known, + * however accessing the getter for this identifier usually triggers the + * lazy loading, leading to a query that may not be necessary if only the + * ID is interesting for the userland code (for example in views that + * generate links to the entity, but do not display anything else). + * + * @param ReflectionMethod $method + * @param ClassMetadata $class + * @return bool + */ + private function isShortIdentifierGetter($method, $class) + { + $identifier = lcfirst(substr($method->getName(), 3)); + $cheapCheck = ( + $method->getNumberOfParameters() == 0 && + substr($method->getName(), 0, 3) == "get" && + in_array($identifier, $class->identifier, true) && + $class->hasField($identifier) && + (($method->getEndLine() - $method->getStartLine()) <= 4) + && in_array($class->fieldMappings[$identifier]['type'], array('integer', 'bigint', 'smallint', 'string')) + ); + + if ($cheapCheck) { + $code = file($method->getDeclaringClass()->getFileName()); + $code = trim(implode(" ", array_slice($code, $method->getStartLine() - 1, $method->getEndLine() - $method->getStartLine() + 1))); + + $pattern = sprintf(self::PATTERN_MATCH_ID_METHOD, $method->getName(), $identifier); + + if (preg_match($pattern, $code)) { + return true; + } + } + return false; + } + + /** + * Generates the code for the __sleep method for a proxy class. + * + * @param $class + * @return string + */ + private function _generateSleep(ClassMetadata $class) + { + $sleepImpl = ''; + + if ($class->reflClass->hasMethod('__sleep')) { + $sleepImpl .= "return array_merge(array('__isInitialized__'), parent::__sleep());"; + } else { + $sleepImpl .= "return array('__isInitialized__', "; + $first = true; + + foreach ($class->getReflectionProperties() as $name => $prop) { + if ($first) { + $first = false; + } else { + $sleepImpl .= ', '; + } + + $sleepImpl .= "'" . $name . "'"; + } + + $sleepImpl .= ');'; + } + + return $sleepImpl; + } + + /** Proxy class code template */ + private static $_proxyClassTemplate = +'; + +/** + * THIS CLASS WAS GENERATED BY THE DOCTRINE ORM. DO NOT EDIT THIS FILE. + */ +class extends \ implements \Doctrine\ORM\Proxy\Proxy +{ + private $_entityPersister; + private $_identifier; + public $__isInitialized__ = false; + public function __construct($entityPersister, $identifier) + { + $this->_entityPersister = $entityPersister; + $this->_identifier = $identifier; + } + /** @private */ + public function __load() + { + if (!$this->__isInitialized__ && $this->_entityPersister) { + $this->__isInitialized__ = true; + + if (method_exists($this, "__wakeup")) { + // call this after __isInitialized__to avoid infinite recursion + // but before loading to emulate what ClassMetadata::newInstance() + // provides. + $this->__wakeup(); + } + + if ($this->_entityPersister->load($this->_identifier, $this) === null) { + throw new \Doctrine\ORM\EntityNotFoundException(); + } + unset($this->_entityPersister, $this->_identifier); + } + } + + /** @private */ + public function __isInitialized() + { + return $this->__isInitialized__; + } + + + + public function __sleep() + { + + } + + public function __clone() + { + if (!$this->__isInitialized__ && $this->_entityPersister) { + $this->__isInitialized__ = true; + $class = $this->_entityPersister->getClassMetadata(); + $original = $this->_entityPersister->load($this->_identifier); + if ($original === null) { + throw new \Doctrine\ORM\EntityNotFoundException(); + } + foreach ($class->reflFields AS $field => $reflProperty) { + $reflProperty->setValue($this, $reflProperty->getValue($original)); + } + unset($this->_entityPersister, $this->_identifier); + } + + } +}'; +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query.php new file mode 100644 index 0000000..16c6c38 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query.php @@ -0,0 +1,614 @@ +. + */ + +namespace Doctrine\ORM; + +use Doctrine\DBAL\LockMode, + Doctrine\ORM\Query\Parser, + Doctrine\ORM\Query\QueryException; + +/** + * A Query object represents a DQL query. + * + * @since 1.0 + * @author Guilherme Blanco + * @author Konsta Vesterinen + * @author Roman Borschel + */ +final class Query extends AbstractQuery +{ + /* Query STATES */ + /** + * A query object is in CLEAN state when it has NO unparsed/unprocessed DQL parts. + */ + const STATE_CLEAN = 1; + /** + * A query object is in state DIRTY when it has DQL parts that have not yet been + * parsed/processed. This is automatically defined as DIRTY when addDqlQueryPart + * is called. + */ + const STATE_DIRTY = 2; + + /* Query HINTS */ + /** + * The refresh hint turns any query into a refresh query with the result that + * any local changes in entities are overridden with the fetched values. + * + * @var string + */ + const HINT_REFRESH = 'doctrine.refresh'; + + + /** + * Internal hint: is set to the proxy entity that is currently triggered for loading + * + * @var string + */ + const HINT_REFRESH_ENTITY = 'doctrine.refresh.entity'; + + /** + * The forcePartialLoad query hint forces a particular query to return + * partial objects. + * + * @var string + * @todo Rename: HINT_OPTIMIZE + */ + const HINT_FORCE_PARTIAL_LOAD = 'doctrine.forcePartialLoad'; + /** + * The includeMetaColumns query hint causes meta columns like foreign keys and + * discriminator columns to be selected and returned as part of the query result. + * + * This hint does only apply to non-object queries. + * + * @var string + */ + const HINT_INCLUDE_META_COLUMNS = 'doctrine.includeMetaColumns'; + + /** + * An array of class names that implement \Doctrine\ORM\Query\TreeWalker and + * are iterated and executed after the DQL has been parsed into an AST. + * + * @var string + */ + const HINT_CUSTOM_TREE_WALKERS = 'doctrine.customTreeWalkers'; + + /** + * A string with a class name that implements \Doctrine\ORM\Query\TreeWalker + * and is used for generating the target SQL from any DQL AST tree. + * + * @var string + */ + const HINT_CUSTOM_OUTPUT_WALKER = 'doctrine.customOutputWalker'; + + //const HINT_READ_ONLY = 'doctrine.readOnly'; + + /** + * @var string + */ + const HINT_INTERNAL_ITERATION = 'doctrine.internal.iteration'; + + /** + * @var string + */ + const HINT_LOCK_MODE = 'doctrine.lockMode'; + + /** + * @var integer $_state The current state of this query. + */ + private $_state = self::STATE_CLEAN; + + /** + * @var string $_dql Cached DQL query. + */ + private $_dql = null; + + /** + * @var \Doctrine\ORM\Query\ParserResult The parser result that holds DQL => SQL information. + */ + private $_parserResult; + + /** + * @var integer The first result to return (the "offset"). + */ + private $_firstResult = null; + + /** + * @var integer The maximum number of results to return (the "limit"). + */ + private $_maxResults = null; + + /** + * @var CacheDriver The cache driver used for caching queries. + */ + private $_queryCache; + + /** + * @var boolean Boolean value that indicates whether or not expire the query cache. + */ + private $_expireQueryCache = false; + + /** + * @var int Query Cache lifetime. + */ + private $_queryCacheTTL; + + /** + * @var boolean Whether to use a query cache, if available. Defaults to TRUE. + */ + private $_useQueryCache = true; + + // End of Caching Stuff + + /** + * Initializes a new Query instance. + * + * @param \Doctrine\ORM\EntityManager $entityManager + */ + /*public function __construct(EntityManager $entityManager) + { + parent::__construct($entityManager); + }*/ + + /** + * Gets the SQL query/queries that correspond to this DQL query. + * + * @return mixed The built sql query or an array of all sql queries. + * @override + */ + public function getSQL() + { + return $this->_parse()->getSQLExecutor()->getSQLStatements(); + } + + /** + * Returns the corresponding AST for this DQL query. + * + * @return \Doctrine\ORM\Query\AST\SelectStatement | + * \Doctrine\ORM\Query\AST\UpdateStatement | + * \Doctrine\ORM\Query\AST\DeleteStatement + */ + public function getAST() + { + $parser = new Parser($this); + return $parser->getAST(); + } + + /** + * Parses the DQL query, if necessary, and stores the parser result. + * + * Note: Populates $this->_parserResult as a side-effect. + * + * @return \Doctrine\ORM\Query\ParserResult + */ + private function _parse() + { + // Return previous parser result if the query and the filter collection are both clean + if ($this->_state === self::STATE_CLEAN + && $this->_em->isFiltersStateClean() + ) { + return $this->_parserResult; + } + + $this->_state = self::STATE_CLEAN; + + // Check query cache. + if ( ! ($this->_useQueryCache && ($queryCache = $this->getQueryCacheDriver()))) { + $parser = new Parser($this); + $this->_parserResult = $parser->parse(); + + return $this->_parserResult; + } + + $hash = $this->_getQueryCacheId(); + $cached = $this->_expireQueryCache ? false : $queryCache->fetch($hash); + + if ($cached !== false) { + // Cache hit. + $this->_parserResult = $cached; + + return $this->_parserResult; + } + + // Cache miss. + $parser = new Parser($this); + $this->_parserResult = $parser->parse(); + $queryCache->save($hash, $this->_parserResult, $this->_queryCacheTTL); + + return $this->_parserResult; + } + + /** + * {@inheritdoc} + */ + protected function _doExecute() + { + $executor = $this->_parse()->getSqlExecutor(); + + if ($this->_queryCacheProfile) { + $executor->setQueryCacheProfile($this->_queryCacheProfile); + } + + // Prepare parameters + $paramMappings = $this->_parserResult->getParameterMappings(); + + if (count($paramMappings) != count($this->_params)) { + throw QueryException::invalidParameterNumber(); + } + + list($sqlParams, $types) = $this->processParameterMappings($paramMappings); + + if ($this->_resultSetMapping === null) { + $this->_resultSetMapping = $this->_parserResult->getResultSetMapping(); + } + + return $executor->execute($this->_em->getConnection(), $sqlParams, $types); + } + + /** + * Processes query parameter mappings + * + * @param array $paramMappings + * @return array + */ + private function processParameterMappings($paramMappings) + { + $sqlParams = $types = array(); + + foreach ($this->_params as $key => $value) { + if ( ! isset($paramMappings[$key])) { + throw QueryException::unknownParameter($key); + } + + if (isset($this->_paramTypes[$key])) { + foreach ($paramMappings[$key] as $position) { + $types[$position] = $this->_paramTypes[$key]; + } + } + + $sqlPositions = $paramMappings[$key]; + // optimized multi value sql positions away for now, they are not allowed in DQL anyways. + $value = array($value); + $countValue = count($value); + + for ($i = 0, $l = count($sqlPositions); $i < $l; $i++) { + $sqlParams[$sqlPositions[$i]] = $value[($i % $countValue)]; + } + } + + if (count($sqlParams) != count($types)) { + throw QueryException::parameterTypeMissmatch(); + } + + if ($sqlParams) { + ksort($sqlParams); + $sqlParams = array_values($sqlParams); + + ksort($types); + $types = array_values($types); + } + + return array($sqlParams, $types); + } + + /** + * Defines a cache driver to be used for caching queries. + * + * @param Doctrine_Cache_Interface|null $driver Cache driver + * @return Query This query instance. + */ + public function setQueryCacheDriver($queryCache) + { + $this->_queryCache = $queryCache; + + return $this; + } + + /** + * Defines whether the query should make use of a query cache, if available. + * + * @param boolean $bool + * @return @return Query This query instance. + */ + public function useQueryCache($bool) + { + $this->_useQueryCache = $bool; + + return $this; + } + + /** + * Returns the cache driver used for query caching. + * + * @return CacheDriver The cache driver used for query caching or NULL, if this + * Query does not use query caching. + */ + public function getQueryCacheDriver() + { + if ($this->_queryCache) { + return $this->_queryCache; + } + + return $this->_em->getConfiguration()->getQueryCacheImpl(); + } + + /** + * Defines how long the query cache will be active before expire. + * + * @param integer $timeToLive How long the cache entry is valid + * @return Query This query instance. + */ + public function setQueryCacheLifetime($timeToLive) + { + if ($timeToLive !== null) { + $timeToLive = (int) $timeToLive; + } + + $this->_queryCacheTTL = $timeToLive; + + return $this; + } + + /** + * Retrieves the lifetime of resultset cache. + * + * @return int + */ + public function getQueryCacheLifetime() + { + return $this->_queryCacheTTL; + } + + /** + * Defines if the query cache is active or not. + * + * @param boolean $expire Whether or not to force query cache expiration. + * @return Query This query instance. + */ + public function expireQueryCache($expire = true) + { + $this->_expireQueryCache = $expire; + + return $this; + } + + /** + * Retrieves if the query cache is active or not. + * + * @return bool + */ + public function getExpireQueryCache() + { + return $this->_expireQueryCache; + } + + /** + * @override + */ + public function free() + { + parent::free(); + + $this->_dql = null; + $this->_state = self::STATE_CLEAN; + } + + /** + * Sets a DQL query string. + * + * @param string $dqlQuery DQL Query + * @return \Doctrine\ORM\AbstractQuery + */ + public function setDQL($dqlQuery) + { + if ($dqlQuery !== null) { + $this->_dql = $dqlQuery; + $this->_state = self::STATE_DIRTY; + } + + return $this; + } + + /** + * Returns the DQL query that is represented by this query object. + * + * @return string DQL query + */ + public function getDQL() + { + return $this->_dql; + } + + /** + * Returns the state of this query object + * By default the type is Doctrine_ORM_Query_Abstract::STATE_CLEAN but if it appears any unprocessed DQL + * part, it is switched to Doctrine_ORM_Query_Abstract::STATE_DIRTY. + * + * @see AbstractQuery::STATE_CLEAN + * @see AbstractQuery::STATE_DIRTY + * + * @return integer Return the query state + */ + public function getState() + { + return $this->_state; + } + + /** + * Method to check if an arbitrary piece of DQL exists + * + * @param string $dql Arbitrary piece of DQL to check for + * @return boolean + */ + public function contains($dql) + { + return stripos($this->getDQL(), $dql) === false ? false : true; + } + + /** + * Sets the position of the first result to retrieve (the "offset"). + * + * @param integer $firstResult The first result to return. + * @return Query This query object. + */ + public function setFirstResult($firstResult) + { + $this->_firstResult = $firstResult; + $this->_state = self::STATE_DIRTY; + + return $this; + } + + /** + * Gets the position of the first result the query object was set to retrieve (the "offset"). + * Returns NULL if {@link setFirstResult} was not applied to this query. + * + * @return integer The position of the first result. + */ + public function getFirstResult() + { + return $this->_firstResult; + } + + /** + * Sets the maximum number of results to retrieve (the "limit"). + * + * @param integer $maxResults + * @return Query This query object. + */ + public function setMaxResults($maxResults) + { + $this->_maxResults = $maxResults; + $this->_state = self::STATE_DIRTY; + + return $this; + } + + /** + * Gets the maximum number of results the query object was set to retrieve (the "limit"). + * Returns NULL if {@link setMaxResults} was not applied to this query. + * + * @return integer Maximum number of results. + */ + public function getMaxResults() + { + return $this->_maxResults; + } + + /** + * Executes the query and returns an IterableResult that can be used to incrementally + * iterated over the result. + * + * @param array $params The query parameters. + * @param integer $hydrationMode The hydration mode to use. + * @return \Doctrine\ORM\Internal\Hydration\IterableResult + */ + public function iterate(array $params = array(), $hydrationMode = self::HYDRATE_OBJECT) + { + $this->setHint(self::HINT_INTERNAL_ITERATION, true); + + return parent::iterate($params, $hydrationMode); + } + + /** + * {@inheritdoc} + */ + public function setHint($name, $value) + { + $this->_state = self::STATE_DIRTY; + + return parent::setHint($name, $value); + } + + /** + * {@inheritdoc} + */ + public function setHydrationMode($hydrationMode) + { + $this->_state = self::STATE_DIRTY; + + return parent::setHydrationMode($hydrationMode); + } + + /** + * Set the lock mode for this Query. + * + * @see \Doctrine\DBAL\LockMode + * @param int $lockMode + * @return Query + */ + public function setLockMode($lockMode) + { + if ($lockMode === LockMode::PESSIMISTIC_READ || $lockMode === LockMode::PESSIMISTIC_WRITE) { + if ( ! $this->_em->getConnection()->isTransactionActive()) { + throw TransactionRequiredException::transactionRequired(); + } + } + + $this->setHint(self::HINT_LOCK_MODE, $lockMode); + + return $this; + } + + /** + * Get the current lock mode for this query. + * + * @return int + */ + public function getLockMode() + { + $lockMode = $this->getHint(self::HINT_LOCK_MODE); + + if ( ! $lockMode) { + return LockMode::NONE; + } + + return $lockMode; + } + + /** + * Generate a cache id for the query cache - reusing the Result-Cache-Id generator. + * + * The query cache + * + * @return string + */ + protected function _getQueryCacheId() + { + ksort($this->_hints); + + return md5( + $this->getDql() . var_export($this->_hints, true) . + ($this->_em->hasFilters() ? $this->_em->getFilters()->getHash() : '') . + '&firstResult=' . $this->_firstResult . '&maxResult=' . $this->_maxResults . + '&hydrationMode='.$this->_hydrationMode.'DOCTRINE_QUERY_CACHE_SALT' + ); + } + + /** + * Cleanup Query resource when clone is called. + * + * @return void + */ + public function __clone() + { + parent::__clone(); + + $this->_state = self::STATE_DIRTY; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ASTException.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ASTException.php new file mode 100644 index 0000000..7472572 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ASTException.php @@ -0,0 +1,13 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * Description of AggregateExpression + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class AggregateExpression extends Node +{ + public $functionName; + public $pathExpression; + public $isDistinct = false; // Some aggregate expressions support distinct, eg COUNT + + public function __construct($functionName, $pathExpression, $isDistinct) + { + $this->functionName = $functionName; + $this->pathExpression = $pathExpression; + $this->isDistinct = $isDistinct; + } + + public function dispatch($walker) + { + return $walker->walkAggregateExpression($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ArithmeticExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ArithmeticExpression.php new file mode 100644 index 0000000..679cbcc --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ArithmeticExpression.php @@ -0,0 +1,54 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * ArithmeticExpression ::= SimpleArithmeticExpression | "(" Subselect ")" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class ArithmeticExpression extends Node +{ + public $simpleArithmeticExpression; + public $subselect; + + public function isSimpleArithmeticExpression() + { + return (bool) $this->simpleArithmeticExpression; + } + + public function isSubselect() + { + return (bool) $this->subselect; + } + + public function dispatch($walker) + { + return $walker->walkArithmeticExpression($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ArithmeticFactor.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ArithmeticFactor.php new file mode 100644 index 0000000..3ad6abf --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ArithmeticFactor.php @@ -0,0 +1,67 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * ArithmeticFactor ::= [("+" | "-")] ArithmeticPrimary + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class ArithmeticFactor extends Node +{ + /** + * @var ArithmeticPrimary + */ + public $arithmeticPrimary; + + /** + * @var null|boolean NULL represents no sign, TRUE means positive and FALSE means negative sign + */ + public $sign; + + public function __construct($arithmeticPrimary, $sign = null) + { + $this->arithmeticPrimary = $arithmeticPrimary; + $this->sign = $sign; + } + + public function isPositiveSigned() + { + return $this->sign === true; + } + + public function isNegativeSigned() + { + return $this->sign === false; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkArithmeticFactor($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ArithmeticTerm.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ArithmeticTerm.php new file mode 100644 index 0000000..a233e05 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ArithmeticTerm.php @@ -0,0 +1,48 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * ArithmeticTerm ::= ArithmeticFactor {("*" | "/") ArithmeticFactor}* + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class ArithmeticTerm extends Node +{ + public $arithmeticFactors; + + public function __construct(array $arithmeticFactors) + { + $this->arithmeticFactors = $arithmeticFactors; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkArithmeticTerm($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/BetweenExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/BetweenExpression.php new file mode 100644 index 0000000..c00bca4 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/BetweenExpression.php @@ -0,0 +1,54 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * Description of BetweenExpression + * + @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class BetweenExpression extends Node +{ + public $expression; + public $leftBetweenExpression; + public $rightBetweenExpression; + public $not; + + public function __construct($expr, $leftExpr, $rightExpr) + { + $this->expression = $expr; + $this->leftBetweenExpression = $leftExpr; + $this->rightBetweenExpression = $rightExpr; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkBetweenExpression($this); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/CoalesceExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/CoalesceExpression.php new file mode 100644 index 0000000..dae0742 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/CoalesceExpression.php @@ -0,0 +1,47 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * CoalesceExpression ::= "COALESCE" "(" ScalarExpression {"," ScalarExpression}* ")" + * + * @since 2.1 + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class CoalesceExpression extends Node +{ + public $scalarExpressions = array(); + + + public function __construct(array $scalarExpressions) + { + $this->scalarExpressions = $scalarExpressions; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkCoalesceExpression($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/CollectionMemberExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/CollectionMemberExpression.php new file mode 100644 index 0000000..62d756b --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/CollectionMemberExpression.php @@ -0,0 +1,52 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * CollectionMemberExpression ::= EntityExpression ["NOT"] "MEMBER" ["OF"] CollectionValuedPathExpression + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class CollectionMemberExpression extends Node +{ + public $entityExpression; + public $collectionValuedPathExpression; + public $not; + + public function __construct($entityExpr, $collValuedPathExpr) + { + $this->entityExpression = $entityExpr; + $this->collectionValuedPathExpression = $collValuedPathExpr; + } + + public function dispatch($walker) + { + return $walker->walkCollectionMemberExpression($this); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ComparisonExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ComparisonExpression.php new file mode 100644 index 0000000..a13ae26 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ComparisonExpression.php @@ -0,0 +1,57 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * ComparisonExpression ::= ArithmeticExpression ComparisonOperator ( QuantifiedExpression | ArithmeticExpression ) | + * StringExpression ComparisonOperator (StringExpression | QuantifiedExpression) | + * BooleanExpression ("=" | "<>" | "!=") (BooleanExpression | QuantifiedExpression) | + * EnumExpression ("=" | "<>" | "!=") (EnumExpression | QuantifiedExpression) | + * DatetimeExpression ComparisonOperator (DatetimeExpression | QuantifiedExpression) | + * EntityExpression ("=" | "<>") (EntityExpression | QuantifiedExpression) + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class ComparisonExpression extends Node +{ + public $leftExpression; + public $rightExpression; + public $operator; + + public function __construct($leftExpr, $operator, $rightExpr) + { + $this->leftExpression = $leftExpr; + $this->rightExpression = $rightExpr; + $this->operator = $operator; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkComparisonExpression($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ConditionalExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ConditionalExpression.php new file mode 100644 index 0000000..d2e7762 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ConditionalExpression.php @@ -0,0 +1,48 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * ConditionalExpression ::= ConditionalTerm {"OR" ConditionalTerm}* + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class ConditionalExpression extends Node +{ + public $conditionalTerms = array(); + + public function __construct(array $conditionalTerms) + { + $this->conditionalTerms = $conditionalTerms; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkConditionalExpression($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ConditionalFactor.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ConditionalFactor.php new file mode 100644 index 0000000..f0b165b --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ConditionalFactor.php @@ -0,0 +1,49 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * ConditionalFactor ::= ["NOT"] ConditionalPrimary + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class ConditionalFactor extends Node +{ + public $not = false; + public $conditionalPrimary; + + public function __construct($conditionalPrimary) + { + $this->conditionalPrimary = $conditionalPrimary; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkConditionalFactor($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ConditionalPrimary.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ConditionalPrimary.php new file mode 100644 index 0000000..0e3f127 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ConditionalPrimary.php @@ -0,0 +1,54 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * ConditionalPrimary ::= SimpleConditionalExpression | "(" ConditionalExpression ")" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class ConditionalPrimary extends Node +{ + public $simpleConditionalExpression; + public $conditionalExpression; + + public function isSimpleConditionalExpression() + { + return (bool) $this->simpleConditionalExpression; + } + + public function isConditionalExpression() + { + return (bool) $this->conditionalExpression; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkConditionalPrimary($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ConditionalTerm.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ConditionalTerm.php new file mode 100644 index 0000000..78ba6a2 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ConditionalTerm.php @@ -0,0 +1,48 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * ConditionalTerm ::= ConditionalFactor {"AND" ConditionalFactor}* + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class ConditionalTerm extends Node +{ + public $conditionalFactors = array(); + + public function __construct(array $conditionalFactors) + { + $this->conditionalFactors = $conditionalFactors; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkConditionalTerm($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/DeleteClause.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/DeleteClause.php new file mode 100644 index 0000000..4acf49c --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/DeleteClause.php @@ -0,0 +1,50 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * DeleteClause ::= "DELETE" ["FROM"] AbstractSchemaName [["AS"] AliasIdentificationVariable] + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class DeleteClause extends Node +{ + public $abstractSchemaName; + public $aliasIdentificationVariable; + + public function __construct($abstractSchemaName) + { + $this->abstractSchemaName = $abstractSchemaName; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkDeleteClause($this); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/DeleteStatement.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/DeleteStatement.php new file mode 100644 index 0000000..01c6acb --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/DeleteStatement.php @@ -0,0 +1,49 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * DeleteStatement = DeleteClause [WhereClause] + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class DeleteStatement extends Node +{ + public $deleteClause; + public $whereClause; + + public function __construct($deleteClause) + { + $this->deleteClause = $deleteClause; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkDeleteStatement($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/EmptyCollectionComparisonExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/EmptyCollectionComparisonExpression.php new file mode 100644 index 0000000..6bb50e8 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/EmptyCollectionComparisonExpression.php @@ -0,0 +1,50 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * EmptyCollectionComparisonExpression ::= CollectionValuedPathExpression "IS" ["NOT"] "EMPTY" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class EmptyCollectionComparisonExpression extends Node +{ + public $expression; + public $not; + + public function __construct($expression) + { + $this->expression = $expression; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkEmptyCollectionComparisonExpression($this); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ExistsExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ExistsExpression.php new file mode 100644 index 0000000..3d9ad20 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/ExistsExpression.php @@ -0,0 +1,50 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * ExistsExpression ::= ["NOT"] "EXISTS" "(" Subselect ")" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class ExistsExpression extends Node +{ + public $not; + public $subselect; + + public function __construct($subselect) + { + $this->subselect = $subselect; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkExistsExpression($this); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/FromClause.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/FromClause.php new file mode 100644 index 0000000..a4dc628 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/FromClause.php @@ -0,0 +1,45 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * FromClause ::= "FROM" IdentificationVariableDeclaration {"," IdentificationVariableDeclaration} + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class FromClause extends Node +{ + public $identificationVariableDeclarations = array(); + + public function __construct(array $identificationVariableDeclarations) + { + $this->identificationVariableDeclarations = $identificationVariableDeclarations; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkFromClause($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/AbsFunction.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/AbsFunction.php new file mode 100644 index 0000000..3ee4360 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/AbsFunction.php @@ -0,0 +1,62 @@ +. + */ + +namespace Doctrine\ORM\Query\AST\Functions; + +use Doctrine\ORM\Query\Lexer; + +/** + * "ABS" "(" SimpleArithmeticExpression ")" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class AbsFunction extends FunctionNode +{ + public $simpleArithmeticExpression; + + /** + * @override + */ + public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) + { + return 'ABS(' . $sqlWalker->walkSimpleArithmeticExpression( + $this->simpleArithmeticExpression + ) . ')'; + } + + /** + * @override + */ + public function parse(\Doctrine\ORM\Query\Parser $parser) + { + $parser->match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + + $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression(); + + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/BitAndFunction.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/BitAndFunction.php new file mode 100644 index 0000000..1ee8233 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/BitAndFunction.php @@ -0,0 +1,63 @@ +. + */ + +namespace Doctrine\ORM\Query\AST\Functions; + +use Doctrine\ORM\Query\Lexer; + +/** + * "BIT_AND" "(" ArithmeticPrimary "," ArithmeticPrimary ")" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.2 + * @author Fabio B. Silva + */ +class BitAndFunction extends FunctionNode +{ + public $firstArithmetic; + public $secondArithmetic; + + /** + * @override + */ + public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) + { + $platform = $sqlWalker->getConnection()->getDatabasePlatform(); + return $platform->getBitAndComparisonExpression( + $this->firstArithmetic->dispatch($sqlWalker), + $this->secondArithmetic->dispatch($sqlWalker) + ); + } + + /** + * @override + */ + public function parse(\Doctrine\ORM\Query\Parser $parser) + { + $parser->match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + + $this->firstArithmetic = $parser->ArithmeticPrimary(); + $parser->match(Lexer::T_COMMA); + $this->secondArithmetic = $parser->ArithmeticPrimary(); + + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/BitOrFunction.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/BitOrFunction.php new file mode 100644 index 0000000..ba36e97 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/BitOrFunction.php @@ -0,0 +1,63 @@ +. + */ + +namespace Doctrine\ORM\Query\AST\Functions; + +use Doctrine\ORM\Query\Lexer; + +/** + * "BIT_OR" "(" ArithmeticPrimary "," ArithmeticPrimary ")" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.2 + * @author Fabio B. Silva + */ +class BitOrFunction extends FunctionNode +{ + public $firstArithmetic; + public $secondArithmetic; + + /** + * @override + */ + public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) + { + $platform = $sqlWalker->getConnection()->getDatabasePlatform(); + return $platform->getBitOrComparisonExpression( + $this->firstArithmetic->dispatch($sqlWalker), + $this->secondArithmetic->dispatch($sqlWalker) + ); + } + + /** + * @override + */ + public function parse(\Doctrine\ORM\Query\Parser $parser) + { + $parser->match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + + $this->firstArithmetic = $parser->ArithmeticPrimary(); + $parser->match(Lexer::T_COMMA); + $this->secondArithmetic = $parser->ArithmeticPrimary(); + + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php new file mode 100644 index 0000000..bb2333a --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php @@ -0,0 +1,67 @@ +. + */ + +namespace Doctrine\ORM\Query\AST\Functions; + +use Doctrine\ORM\Query\Lexer; + +/** + * "CONCAT" "(" StringPrimary "," StringPrimary ")" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class ConcatFunction extends FunctionNode +{ + public $firstStringPrimary; + public $secondStringPriamry; + + /** + * @override + */ + public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) + { + $platform = $sqlWalker->getConnection()->getDatabasePlatform(); + return $platform->getConcatExpression( + $sqlWalker->walkStringPrimary($this->firstStringPrimary), + $sqlWalker->walkStringPrimary($this->secondStringPrimary) + ); + } + + /** + * @override + */ + public function parse(\Doctrine\ORM\Query\Parser $parser) + { + $parser->match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + + $this->firstStringPrimary = $parser->StringPrimary(); + $parser->match(Lexer::T_COMMA); + $this->secondStringPrimary = $parser->StringPrimary(); + + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/CurrentDateFunction.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/CurrentDateFunction.php new file mode 100644 index 0000000..66107cc --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/CurrentDateFunction.php @@ -0,0 +1,54 @@ +. + */ + +namespace Doctrine\ORM\Query\AST\Functions; + +use Doctrine\ORM\Query\Lexer; + +/** + * "CURRENT_DATE" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class CurrentDateFunction extends FunctionNode +{ + /** + * @override + */ + public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) + { + return $sqlWalker->getConnection()->getDatabasePlatform()->getCurrentDateSQL(); + } + + /** + * @override + */ + public function parse(\Doctrine\ORM\Query\Parser $parser) + { + $parser->match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php new file mode 100644 index 0000000..1335755 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php @@ -0,0 +1,54 @@ +. + */ + +namespace Doctrine\ORM\Query\AST\Functions; + +use Doctrine\ORM\Query\Lexer; + +/** + * "CURRENT_TIME" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class CurrentTimeFunction extends FunctionNode +{ + /** + * @override + */ + public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) + { + return $sqlWalker->getConnection()->getDatabasePlatform()->getCurrentTimeSQL(); + } + + /** + * @override + */ + public function parse(\Doctrine\ORM\Query\Parser $parser) + { + $parser->match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimestampFunction.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimestampFunction.php new file mode 100644 index 0000000..7b1a25d --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimestampFunction.php @@ -0,0 +1,54 @@ +. + */ + +namespace Doctrine\ORM\Query\AST\Functions; + +use Doctrine\ORM\Query\Lexer; + +/** + * "CURRENT_TIMESTAMP" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class CurrentTimestampFunction extends FunctionNode +{ + /** + * @override + */ + public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) + { + return $sqlWalker->getConnection()->getDatabasePlatform()->getCurrentTimestampSQL(); + } + + /** + * @override + */ + public function parse(\Doctrine\ORM\Query\Parser $parser) + { + $parser->match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/DateAddFunction.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/DateAddFunction.php new file mode 100644 index 0000000..1d840cc --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/DateAddFunction.php @@ -0,0 +1,71 @@ +. + */ + +namespace Doctrine\ORM\Query\AST\Functions; + +use Doctrine\ORM\Query\Lexer; +use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\Parser; +use Doctrine\ORM\Query\QueryException; + +/** + * "DATE_ADD(date1, interval, unit)" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + */ +class DateAddFunction extends FunctionNode +{ + public $firstDateExpression = null; + public $intervalExpression = null; + public $unit = null; + + public function getSql(SqlWalker $sqlWalker) + { + $unit = strtolower($this->unit); + if ($unit == "day") { + return $sqlWalker->getConnection()->getDatabasePlatform()->getDateAddDaysExpression( + $this->firstDateExpression->dispatch($sqlWalker), + $this->intervalExpression->dispatch($sqlWalker) + ); + } else if ($unit == "month") { + return $sqlWalker->getConnection()->getDatabasePlatform()->getDateAddMonthExpression( + $this->firstDateExpression->dispatch($sqlWalker), + $this->intervalExpression->dispatch($sqlWalker) + ); + } else { + throw QueryException::semanticalError('DATE_ADD() only supports units of type day and month.'); + } + } + + public function parse(Parser $parser) + { + $parser->match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + + $this->firstDateExpression = $parser->ArithmeticPrimary(); + $parser->match(Lexer::T_COMMA); + $this->intervalExpression = $parser->ArithmeticPrimary(); + $parser->match(Lexer::T_COMMA); + $this->unit = $parser->StringPrimary(); + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/DateDiffFunction.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/DateDiffFunction.php new file mode 100644 index 0000000..4de5411 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/DateDiffFunction.php @@ -0,0 +1,58 @@ +. + */ + +namespace Doctrine\ORM\Query\AST\Functions; + +use Doctrine\ORM\Query\Lexer; +use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\Parser; + +/** + * "DATE_DIFF(date1, date2)" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + */ +class DateDiffFunction extends FunctionNode +{ + public $date1; + public $date2; + + public function getSql(SqlWalker $sqlWalker) + { + return $sqlWalker->getConnection()->getDatabasePlatform()->getDateDiffExpression( + $this->date1->dispatch($sqlWalker), + $this->date2->dispatch($sqlWalker) + ); + } + + public function parse(Parser $parser) + { + $parser->match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + + $this->date1 = $parser->ArithmeticPrimary(); + $parser->match(Lexer::T_COMMA); + $this->date2 = $parser->ArithmeticPrimary(); + + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/DateSubFunction.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/DateSubFunction.php new file mode 100644 index 0000000..a608d49 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/DateSubFunction.php @@ -0,0 +1,58 @@ +. + */ + +namespace Doctrine\ORM\Query\AST\Functions; + +use Doctrine\ORM\Query\Lexer; +use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\Parser; +use Doctrine\ORM\Query\QueryException; + +/** + * "DATE_ADD(date1, interval, unit)" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + */ +class DateSubFunction extends DateAddFunction +{ + public $firstDateExpression = null; + public $intervalExpression = null; + public $unit = null; + + public function getSql(SqlWalker $sqlWalker) + { + $unit = strtolower($this->unit); + if ($unit == "day") { + return $sqlWalker->getConnection()->getDatabasePlatform()->getDateSubDaysExpression( + $this->firstDateExpression->dispatch($sqlWalker), + $this->intervalExpression->dispatch($sqlWalker) + ); + } else if ($unit == "month") { + return $sqlWalker->getConnection()->getDatabasePlatform()->getDateSubMonthExpression( + $this->firstDateExpression->dispatch($sqlWalker), + $this->intervalExpression->dispatch($sqlWalker) + ); + } else { + throw QueryException::semanticalError('DATE_SUB() only supports units of type day and month.'); + } + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/FunctionNode.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/FunctionNode.php new file mode 100644 index 0000000..b9d36d1 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/FunctionNode.php @@ -0,0 +1,52 @@ +. + */ + +namespace Doctrine\ORM\Query\AST\Functions; + +use Doctrine\ORM\Query\AST\Node; + +/** + * Abtract Function Node. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Benjamin Eberlei + */ +abstract class FunctionNode extends Node +{ + public $name; + + public function __construct($name) + { + $this->name = $name; + } + + abstract public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker); + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkFunction($this); + } + + abstract public function parse(\Doctrine\ORM\Query\Parser $parser); +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/IdentityFunction.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/IdentityFunction.php new file mode 100644 index 0000000..1b75929 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/IdentityFunction.php @@ -0,0 +1,68 @@ +. + */ + +namespace Doctrine\ORM\Query\AST\Functions; + +use Doctrine\ORM\Query\Lexer; + +/** + * "IDENTITY" "(" SingleValuedAssociationPathExpression ")" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.2 + * @author Guilherme Blanco + * @author Benjamin Eberlei + */ +class IdentityFunction extends FunctionNode +{ + public $pathExpression; + + /** + * @override + */ + public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) + { + $platform = $sqlWalker->getConnection()->getDatabasePlatform(); + $dqlAlias = $this->pathExpression->identificationVariable; + $assocField = $this->pathExpression->field; + + $qComp = $sqlWalker->getQueryComponent($dqlAlias); + $class = $qComp['metadata']; + $assoc = $class->associationMappings[$assocField]; + + $tableAlias = $sqlWalker->getSQLTableAlias($class->getTableName(), $dqlAlias); + + return $tableAlias . '.' . reset($assoc['targetToSourceKeyColumns']);; + } + + /** + * @override + */ + public function parse(\Doctrine\ORM\Query\Parser $parser) + { + $parser->match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + + $this->pathExpression = $parser->SingleValuedAssociationPathExpression(); + + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/LengthFunction.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/LengthFunction.php new file mode 100644 index 0000000..82dd4b4 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/LengthFunction.php @@ -0,0 +1,62 @@ +. + */ + +namespace Doctrine\ORM\Query\AST\Functions; + +use Doctrine\ORM\Query\Lexer; + +/** + * "LENGTH" "(" StringPrimary ")" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class LengthFunction extends FunctionNode +{ + public $stringPrimary; + + /** + * @override + */ + public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) + { + return $sqlWalker->getConnection()->getDatabasePlatform()->getLengthExpression( + $sqlWalker->walkSimpleArithmeticExpression($this->stringPrimary) + ); + } + + /** + * @override + */ + public function parse(\Doctrine\ORM\Query\Parser $parser) + { + $parser->match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + + $this->stringPrimary = $parser->StringPrimary(); + + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/LocateFunction.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/LocateFunction.php new file mode 100644 index 0000000..e630b2e --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/LocateFunction.php @@ -0,0 +1,81 @@ +. + */ + +namespace Doctrine\ORM\Query\AST\Functions; + +use Doctrine\ORM\Query\Lexer; + +/** + * "LOCATE" "(" StringPrimary "," StringPrimary ["," SimpleArithmeticExpression]")" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class LocateFunction extends FunctionNode +{ + public $firstStringPrimary; + public $secondStringPrimary; + public $simpleArithmeticExpression = false; + + /** + * @override + */ + public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) + { + + return $sqlWalker->getConnection()->getDatabasePlatform()->getLocateExpression( + $sqlWalker->walkStringPrimary($this->secondStringPrimary), // its the other way around in platform + $sqlWalker->walkStringPrimary($this->firstStringPrimary), + (($this->simpleArithmeticExpression) + ? $sqlWalker->walkSimpleArithmeticExpression($this->simpleArithmeticExpression) + : false + ) + ); + } + + /** + * @override + */ + public function parse(\Doctrine\ORM\Query\Parser $parser) + { + $parser->match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + + $this->firstStringPrimary = $parser->StringPrimary(); + + $parser->match(Lexer::T_COMMA); + + $this->secondStringPrimary = $parser->StringPrimary(); + + $lexer = $parser->getLexer(); + if ($lexer->isNextToken(Lexer::T_COMMA)) { + $parser->match(Lexer::T_COMMA); + + $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression(); + } + + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/LowerFunction.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/LowerFunction.php new file mode 100644 index 0000000..7bc092d --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/LowerFunction.php @@ -0,0 +1,62 @@ +. + */ + +namespace Doctrine\ORM\Query\AST\Functions; + +use Doctrine\ORM\Query\Lexer; + +/** + * "LOWER" "(" StringPrimary ")" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class LowerFunction extends FunctionNode +{ + public $stringPrimary; + + /** + * @override + */ + public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) + { + return $sqlWalker->getConnection()->getDatabasePlatform()->getLowerExpression( + $sqlWalker->walkSimpleArithmeticExpression($this->stringPrimary) + ); + } + + /** + * @override + */ + public function parse(\Doctrine\ORM\Query\Parser $parser) + { + $parser->match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + + $this->stringPrimary = $parser->StringPrimary(); + + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/ModFunction.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/ModFunction.php new file mode 100644 index 0000000..53f064a --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/ModFunction.php @@ -0,0 +1,68 @@ +. + */ + +namespace Doctrine\ORM\Query\AST\Functions; + +use Doctrine\ORM\Query\Lexer; + +/** + * "MOD" "(" SimpleArithmeticExpression "," SimpleArithmeticExpression ")" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class ModFunction extends FunctionNode +{ + public $firstSimpleArithmeticExpression; + public $secondSimpleArithmeticExpression; + + /** + * @override + */ + public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) + { + return $sqlWalker->getConnection()->getDatabasePlatform()->getModExpression( + $sqlWalker->walkSimpleArithmeticExpression($this->firstSimpleArithmeticExpression), + $sqlWalker->walkSimpleArithmeticExpression($this->secondSimpleArithmeticExpression) + ); + } + + /** + * @override + */ + public function parse(\Doctrine\ORM\Query\Parser $parser) + { + $parser->match(Lexer::T_MOD); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + + $this->firstSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); + + $parser->match(Lexer::T_COMMA); + + $this->secondSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); + + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php new file mode 100644 index 0000000..3decb91 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php @@ -0,0 +1,122 @@ +. + */ + +namespace Doctrine\ORM\Query\AST\Functions; + +use Doctrine\ORM\Query\Lexer; + +/** + * "SIZE" "(" CollectionValuedPathExpression ")" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class SizeFunction extends FunctionNode +{ + public $collectionPathExpression; + + /** + * @override + * @todo If the collection being counted is already joined, the SQL can be simpler (more efficient). + */ + public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) + { + $platform = $sqlWalker->getConnection()->getDatabasePlatform(); + $dqlAlias = $this->collectionPathExpression->identificationVariable; + $assocField = $this->collectionPathExpression->field; + + $qComp = $sqlWalker->getQueryComponent($dqlAlias); + $class = $qComp['metadata']; + $assoc = $class->associationMappings[$assocField]; + $sql = 'SELECT COUNT(*) FROM '; + + if ($assoc['type'] == \Doctrine\ORM\Mapping\ClassMetadata::ONE_TO_MANY) { + $targetClass = $sqlWalker->getEntityManager()->getClassMetadata($assoc['targetEntity']); + $targetTableAlias = $sqlWalker->getSQLTableAlias($targetClass->getTableName()); + $sourceTableAlias = $sqlWalker->getSQLTableAlias($class->getTableName(), $dqlAlias); + + $sql .= $targetClass->getQuotedTableName($platform) . ' ' . $targetTableAlias . ' WHERE '; + + $owningAssoc = $targetClass->associationMappings[$assoc['mappedBy']]; + + $first = true; + + foreach ($owningAssoc['targetToSourceKeyColumns'] as $targetColumn => $sourceColumn) { + if ($first) $first = false; else $sql .= ' AND '; + + $sql .= $targetTableAlias . '.' . $sourceColumn + . ' = ' + . $sourceTableAlias . '.' . $class->getQuotedColumnName($class->fieldNames[$targetColumn], $platform); + } + } else { // many-to-many + $targetClass = $sqlWalker->getEntityManager()->getClassMetadata($assoc['targetEntity']); + + $owningAssoc = $assoc['isOwningSide'] ? $assoc : $targetClass->associationMappings[$assoc['mappedBy']]; + $joinTable = $owningAssoc['joinTable']; + + // SQL table aliases + $joinTableAlias = $sqlWalker->getSQLTableAlias($joinTable['name']); + $sourceTableAlias = $sqlWalker->getSQLTableAlias($class->getTableName(), $dqlAlias); + + // join to target table + $sql .= $targetClass->getQuotedJoinTableName($owningAssoc, $platform) . ' ' . $joinTableAlias . ' WHERE '; + + $joinColumns = $assoc['isOwningSide'] + ? $joinTable['joinColumns'] + : $joinTable['inverseJoinColumns']; + + $first = true; + + foreach ($joinColumns as $joinColumn) { + if ($first) $first = false; else $sql .= ' AND '; + + $sourceColumnName = $class->getQuotedColumnName( + $class->fieldNames[$joinColumn['referencedColumnName']], $platform + ); + + $sql .= $joinTableAlias . '.' . $joinColumn['name'] + . ' = ' + . $sourceTableAlias . '.' . $sourceColumnName; + } + } + + return '(' . $sql . ')'; + } + + /** + * @override + */ + public function parse(\Doctrine\ORM\Query\Parser $parser) + { + $lexer = $parser->getLexer(); + + $parser->match(Lexer::T_SIZE); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + + $this->collectionPathExpression = $parser->CollectionValuedPathExpression(); + + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/SqrtFunction.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/SqrtFunction.php new file mode 100644 index 0000000..087b93b --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/SqrtFunction.php @@ -0,0 +1,61 @@ +. + */ + +namespace Doctrine\ORM\Query\AST\Functions; + +use Doctrine\ORM\Query\Lexer; + +/** + * "SQRT" "(" SimpleArithmeticExpression ")" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class SqrtFunction extends FunctionNode +{ + public $simpleArithmeticExpression; + + /** + * @override + */ + public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) + { + //TODO: Use platform to get SQL + return 'SQRT(' . $sqlWalker->walkSimpleArithmeticExpression($this->simpleArithmeticExpression) . ')'; + } + + /** + * @override + */ + public function parse(\Doctrine\ORM\Query\Parser $parser) + { + $parser->match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + + $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression(); + + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/SubstringFunction.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/SubstringFunction.php new file mode 100644 index 0000000..c0e6223 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/SubstringFunction.php @@ -0,0 +1,82 @@ +. + */ + +namespace Doctrine\ORM\Query\AST\Functions; + +use Doctrine\ORM\Query\Lexer; + +/** + * "SUBSTRING" "(" StringPrimary "," SimpleArithmeticExpression "," SimpleArithmeticExpression ")" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class SubstringFunction extends FunctionNode +{ + public $stringPrimary; + public $firstSimpleArithmeticExpression; + public $secondSimpleArithmeticExpression = null; + + /** + * @override + */ + public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) + { + $optionalSecondSimpleArithmeticExpression = null; + if ($this->secondSimpleArithmeticExpression !== null) { + $optionalSecondSimpleArithmeticExpression = $sqlWalker->walkSimpleArithmeticExpression($this->secondSimpleArithmeticExpression); + } + + return $sqlWalker->getConnection()->getDatabasePlatform()->getSubstringExpression( + $sqlWalker->walkStringPrimary($this->stringPrimary), + $sqlWalker->walkSimpleArithmeticExpression($this->firstSimpleArithmeticExpression), + $optionalSecondSimpleArithmeticExpression + ); + } + + /** + * @override + */ + public function parse(\Doctrine\ORM\Query\Parser $parser) + { + $parser->match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + + $this->stringPrimary = $parser->StringPrimary(); + + $parser->match(Lexer::T_COMMA); + + $this->firstSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); + + $lexer = $parser->getLexer(); + if ($lexer->isNextToken(Lexer::T_COMMA)) { + $parser->match(Lexer::T_COMMA); + + $this->secondSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); + } + + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/TrimFunction.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/TrimFunction.php new file mode 100644 index 0000000..47b3cec --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/TrimFunction.php @@ -0,0 +1,100 @@ +. + */ + +namespace Doctrine\ORM\Query\AST\Functions; + +use Doctrine\ORM\Query\Lexer; +use Doctrine\DBAL\Platforms\AbstractPlatform; + +/** + * "TRIM" "(" [["LEADING" | "TRAILING" | "BOTH"] [char] "FROM"] StringPrimary ")" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class TrimFunction extends FunctionNode +{ + public $leading; + public $trailing; + public $both; + public $trimChar = false; + public $stringPrimary; + + /** + * @override + */ + public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) + { + $pos = AbstractPlatform::TRIM_UNSPECIFIED; + if ($this->leading) { + $pos = AbstractPlatform::TRIM_LEADING; + } else if ($this->trailing) { + $pos = AbstractPlatform::TRIM_TRAILING; + } else if ($this->both) { + $pos = AbstractPlatform::TRIM_BOTH; + } + + return $sqlWalker->getConnection()->getDatabasePlatform()->getTrimExpression( + $sqlWalker->walkStringPrimary($this->stringPrimary), + $pos, + ($this->trimChar != false) ? $sqlWalker->getConnection()->quote($this->trimChar) : false + ); + } + + /** + * @override + */ + public function parse(\Doctrine\ORM\Query\Parser $parser) + { + $lexer = $parser->getLexer(); + + $parser->match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + + if (strcasecmp('leading', $lexer->lookahead['value']) === 0) { + $parser->match(Lexer::T_LEADING); + $this->leading = true; + } else if (strcasecmp('trailing', $lexer->lookahead['value']) === 0) { + $parser->match(Lexer::T_TRAILING); + $this->trailing = true; + } else if (strcasecmp('both', $lexer->lookahead['value']) === 0) { + $parser->match(Lexer::T_BOTH); + $this->both = true; + } + + if ($lexer->isNextToken(Lexer::T_STRING)) { + $parser->match(Lexer::T_STRING); + $this->trimChar = $lexer->token['value']; + } + + if ($this->leading || $this->trailing || $this->both || $this->trimChar) { + $parser->match(Lexer::T_FROM); + } + + $this->stringPrimary = $parser->StringPrimary(); + + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } + +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/UpperFunction.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/UpperFunction.php new file mode 100644 index 0000000..16a0ed8 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Functions/UpperFunction.php @@ -0,0 +1,62 @@ +. + */ + +namespace Doctrine\ORM\Query\AST\Functions; + +use Doctrine\ORM\Query\Lexer; + +/** + * "UPPER" "(" StringPrimary ")" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class UpperFunction extends FunctionNode +{ + public $stringPrimary; + + /** + * @override + */ + public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) + { + return $sqlWalker->getConnection()->getDatabasePlatform()->getUpperExpression( + $sqlWalker->walkSimpleArithmeticExpression($this->stringPrimary) + ); + } + + /** + * @override + */ + public function parse(\Doctrine\ORM\Query\Parser $parser) + { + $parser->match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + + $this->stringPrimary = $parser->StringPrimary(); + + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/GeneralCaseExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/GeneralCaseExpression.php new file mode 100644 index 0000000..facacd5 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/GeneralCaseExpression.php @@ -0,0 +1,48 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * GeneralCaseExpression ::= "CASE" WhenClause {WhenClause}* "ELSE" ScalarExpression "END" + * + * @since 2.2 + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class GeneralCaseExpression extends Node +{ + public $whenClauses = array(); + public $elseScalarExpression = null; + + public function __construct(array $whenClauses, $elseScalarExpression) + { + $this->whenClauses = $whenClauses; + $this->elseScalarExpression = $elseScalarExpression; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkGeneralCaseExpression($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/GroupByClause.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/GroupByClause.php new file mode 100644 index 0000000..d5ae72f --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/GroupByClause.php @@ -0,0 +1,48 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * Description of GroupByClause + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class GroupByClause extends Node +{ + public $groupByItems = array(); + + public function __construct(array $groupByItems) + { + $this->groupByItems = $groupByItems; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkGroupByClause($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/HavingClause.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/HavingClause.php new file mode 100644 index 0000000..08912b0 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/HavingClause.php @@ -0,0 +1,48 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * Description of HavingClause + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class HavingClause extends Node +{ + public $conditionalExpression; + + public function __construct($conditionalExpression) + { + $this->conditionalExpression = $conditionalExpression; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkHavingClause($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/IdentificationVariableDeclaration.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/IdentificationVariableDeclaration.php new file mode 100644 index 0000000..2f590cc --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/IdentificationVariableDeclaration.php @@ -0,0 +1,52 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * IdentificationVariableDeclaration ::= RangeVariableDeclaration [IndexBy] {JoinVariableDeclaration}* + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class IdentificationVariableDeclaration extends Node +{ + public $rangeVariableDeclaration = null; + public $indexBy = null; + public $joinVariableDeclarations = array(); + + public function __construct($rangeVariableDecl, $indexBy, array $joinVariableDecls) + { + $this->rangeVariableDeclaration = $rangeVariableDecl; + $this->indexBy = $indexBy; + $this->joinVariableDeclarations = $joinVariableDecls; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkIdentificationVariableDeclaration($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/InExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/InExpression.php new file mode 100644 index 0000000..15c517d --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/InExpression.php @@ -0,0 +1,52 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * InExpression ::= StateFieldPathExpression ["NOT"] "IN" "(" (Literal {"," Literal}* | Subselect) ")" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class InExpression extends Node +{ + public $not; + public $expression; + public $literals = array(); + public $subselect; + + public function __construct($expression) + { + $this->expression = $expression; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkInExpression($this); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/IndexBy.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/IndexBy.php new file mode 100644 index 0000000..16f2206 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/IndexBy.php @@ -0,0 +1,48 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * IndexBy ::= "INDEX" "BY" SimpleStateFieldPathExpression + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class IndexBy extends Node +{ + public $simpleStateFieldPathExpression = null; + + public function __construct($simpleStateFieldPathExpression) + { + $this->simpleStateFieldPathExpression = $simpleStateFieldPathExpression; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkIndexBy($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/InputParameter.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/InputParameter.php new file mode 100644 index 0000000..cf04d70 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/InputParameter.php @@ -0,0 +1,58 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * Description of InputParameter + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class InputParameter extends Node +{ + public $isNamed; + public $name; + + /** + * @param string $value + */ + public function __construct($value) + { + if (strlen($value) == 1) { + throw \Doctrine\ORM\Query\QueryException::invalidParameterFormat($value); + } + + $param = substr($value, 1); + $this->isNamed = ! is_numeric($param); + $this->name = $param; + } + + public function dispatch($walker) + { + return $walker->walkInputParameter($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/InstanceOfExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/InstanceOfExpression.php new file mode 100644 index 0000000..4f254b5 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/InstanceOfExpression.php @@ -0,0 +1,50 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * InstanceOfExpression ::= IdentificationVariable ["NOT"] "INSTANCE" ["OF"] (InstanceOfParameter | "(" InstanceOfParameter {"," InstanceOfParameter}* ")") + * InstanceOfParameter ::= AbstractSchemaName | InputParameter + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class InstanceOfExpression extends Node +{ + public $not; + public $identificationVariable; + public $value; + + public function __construct($identVariable) + { + $this->identificationVariable = $identVariable; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkInstanceOfExpression($this); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Join.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Join.php new file mode 100644 index 0000000..084f7d7 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Join.php @@ -0,0 +1,58 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" JoinAssociationPathExpression + * ["AS"] AliasIdentificationVariable [("ON" | "WITH") ConditionalExpression] + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class Join extends Node +{ + const JOIN_TYPE_LEFT = 1; + const JOIN_TYPE_LEFTOUTER = 2; + const JOIN_TYPE_INNER = 3; + + public $joinType = self::JOIN_TYPE_INNER; + public $joinAssociationPathExpression = null; + public $aliasIdentificationVariable = null; + public $conditionalExpression = null; + + public function __construct($joinType, $joinAssocPathExpr, $aliasIdentVar) + { + $this->joinType = $joinType; + $this->joinAssociationPathExpression = $joinAssocPathExpr; + $this->aliasIdentificationVariable = $aliasIdentVar; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkJoin($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/JoinAssociationPathExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/JoinAssociationPathExpression.php new file mode 100644 index 0000000..f9300b2 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/JoinAssociationPathExpression.php @@ -0,0 +1,50 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * JoinAssociationPathExpression ::= IdentificationVariable "." (SingleValuedAssociationField | CollectionValuedAssociationField) + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class JoinAssociationPathExpression extends Node +{ + public $identificationVariable; + public $associationField; + + public function __construct($identificationVariable, $associationField) + { + $this->identificationVariable = $identificationVariable; + $this->associationField = $associationField; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkJoinPathExpression($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/JoinVariableDeclaration.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/JoinVariableDeclaration.php new file mode 100644 index 0000000..7fa9562 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/JoinVariableDeclaration.php @@ -0,0 +1,50 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * JoinVariableDeclaration ::= Join [IndexBy] + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class JoinVariableDeclaration extends Node +{ + public $join = null; + public $indexBy = null; + + public function __construct($join, $indexBy) + { + $this->join = $join; + $this->indexBy = $indexBy; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkJoinVariableDeclaration($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/LikeExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/LikeExpression.php new file mode 100644 index 0000000..7985be4 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/LikeExpression.php @@ -0,0 +1,53 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * LikeExpression ::= StringExpression ["NOT"] "LIKE" string ["ESCAPE" char] + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class LikeExpression extends Node +{ + public $not; + public $stringExpression; + public $stringPattern; + public $escapeChar; + + public function __construct($stringExpression, $stringPattern, $escapeChar = null) + { + $this->stringExpression = $stringExpression; + $this->stringPattern = $stringPattern; + $this->escapeChar = $escapeChar; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkLikeExpression($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Literal.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Literal.php new file mode 100644 index 0000000..426907f --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Literal.php @@ -0,0 +1,24 @@ +type = $type; + $this->value = $value; + } + + public function dispatch($walker) + { + return $walker->walkLiteral($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Node.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Node.php new file mode 100644 index 0000000..8ef13c0 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Node.php @@ -0,0 +1,98 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * Abstract class of an AST node + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +abstract class Node +{ + /** + * Double-dispatch method, supposed to dispatch back to the walker. + * + * Implementation is not mandatory for all nodes. + * + * @param $walker + */ + public function dispatch($walker) + { + throw ASTException::noDispatchForNode($this); + } + + /** + * Dumps the AST Node into a string representation for information purpose only + * + * @return string + */ + public function __toString() + { + return $this->dump($this); + } + + public function dump($obj) + { + static $ident = 0; + + $str = ''; + + if ($obj instanceof Node) { + $str .= get_class($obj) . '(' . PHP_EOL; + $props = get_object_vars($obj); + + foreach ($props as $name => $prop) { + $ident += 4; + $str .= str_repeat(' ', $ident) . '"' . $name . '": ' + . $this->dump($prop) . ',' . PHP_EOL; + $ident -= 4; + } + + $str .= str_repeat(' ', $ident) . ')'; + } else if (is_array($obj)) { + $ident += 4; + $str .= 'array('; + $some = false; + + foreach ($obj as $k => $v) { + $str .= PHP_EOL . str_repeat(' ', $ident) . '"' + . $k . '" => ' . $this->dump($v) . ','; + $some = true; + } + + $ident -= 4; + $str .= ($some ? PHP_EOL . str_repeat(' ', $ident) : '') . ')'; + } else if (is_object($obj)) { + $str .= 'instanceof(' . get_class($obj) . ')'; + } else { + $str .= var_export($obj, true); + } + + return $str; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/NullComparisonExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/NullComparisonExpression.php new file mode 100644 index 0000000..0e64bd2 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/NullComparisonExpression.php @@ -0,0 +1,50 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * NullComparisonExpression ::= (SingleValuedPathExpression | InputParameter) "IS" ["NOT"] "NULL" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class NullComparisonExpression extends Node +{ + public $not; + public $expression; + + public function __construct($expression) + { + $this->expression = $expression; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkNullComparisonExpression($this); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/NullIfExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/NullIfExpression.php new file mode 100644 index 0000000..12c8c14 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/NullIfExpression.php @@ -0,0 +1,49 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * NullIfExpression ::= "NULLIF" "(" ScalarExpression "," ScalarExpression ")" + * + * @since 2.1 + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class NullIfExpression extends Node +{ + public $firstExpression; + + public $secondExpression; + + public function __construct($firstExpression, $secondExpression) + { + $this->firstExpression = $firstExpression; + $this->secondExpression = $secondExpression; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkNullIfExpression($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/OrderByClause.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/OrderByClause.php new file mode 100644 index 0000000..7e23059 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/OrderByClause.php @@ -0,0 +1,48 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * OrderByClause ::= "ORDER" "BY" OrderByItem {"," OrderByItem}* + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class OrderByClause extends Node +{ + public $orderByItems = array(); + + public function __construct(array $orderByItems) + { + $this->orderByItems = $orderByItems; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkOrderByClause($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/OrderByItem.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/OrderByItem.php new file mode 100644 index 0000000..207cbd3 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/OrderByItem.php @@ -0,0 +1,59 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * OrderByItem ::= (ResultVariable | StateFieldPathExpression) ["ASC" | "DESC"] + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class OrderByItem extends Node +{ + public $expression; + public $type; + + public function __construct($expression) + { + $this->expression = $expression; + } + + public function isAsc() + { + return strtoupper($this->type) == 'ASC'; + } + + public function isDesc() + { + return strtoupper($this->type) == 'DESC'; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkOrderByItem($this); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/PartialObjectExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/PartialObjectExpression.php new file mode 100644 index 0000000..d1757d7 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/PartialObjectExpression.php @@ -0,0 +1,15 @@ +identificationVariable = $identificationVariable; + $this->partialFieldSet = $partialFieldSet; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/PathExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/PathExpression.php new file mode 100644 index 0000000..2f78b9c --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/PathExpression.php @@ -0,0 +1,58 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * AssociationPathExpression ::= CollectionValuedPathExpression | SingleValuedAssociationPathExpression + * SingleValuedPathExpression ::= StateFieldPathExpression | SingleValuedAssociationPathExpression + * StateFieldPathExpression ::= SimpleStateFieldPathExpression | SimpleStateFieldAssociationPathExpression + * SingleValuedAssociationPathExpression ::= IdentificationVariable "." SingleValuedAssociationField + * CollectionValuedPathExpression ::= IdentificationVariable "." CollectionValuedAssociationField + * StateField ::= {EmbeddedClassStateField "."}* SimpleStateField + * SimpleStateFieldPathExpression ::= IdentificationVariable "." StateField + * + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class PathExpression extends Node +{ + const TYPE_COLLECTION_VALUED_ASSOCIATION = 2; + const TYPE_SINGLE_VALUED_ASSOCIATION = 4; + const TYPE_STATE_FIELD = 8; + + public $type; + public $expectedType; + public $identificationVariable; + public $field; + + public function __construct($expectedType, $identificationVariable, $field = null) + { + $this->expectedType = $expectedType; + $this->identificationVariable = $identificationVariable; + $this->field = $field; + } + + public function dispatch($walker) + { + return $walker->walkPathExpression($this); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/QuantifiedExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/QuantifiedExpression.php new file mode 100644 index 0000000..11b60ed --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/QuantifiedExpression.php @@ -0,0 +1,68 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * QuantifiedExpression ::= ("ALL" | "ANY" | "SOME") "(" Subselect ")" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class QuantifiedExpression extends Node +{ + public $type; + public $subselect; + + public function __construct($subselect) + { + $this->subselect = $subselect; + } + + public function isAll() + { + return strtoupper($this->type) == 'ALL'; + } + + public function isAny() + { + return strtoupper($this->type) == 'ANY'; + } + + public function isSome() + { + return strtoupper($this->type) == 'SOME'; + } + + /** + * @override + */ + public function dispatch($sqlWalker) + { + return $sqlWalker->walkQuantifiedExpression($this); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/RangeVariableDeclaration.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/RangeVariableDeclaration.php new file mode 100644 index 0000000..cf8b180 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/RangeVariableDeclaration.php @@ -0,0 +1,50 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * RangeVariableDeclaration ::= AbstractSchemaName ["AS"] AliasIdentificationVariable + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class RangeVariableDeclaration extends Node +{ + public $abstractSchemaName; + public $aliasIdentificationVariable; + + public function __construct($abstractSchemaName, $aliasIdentificationVar) + { + $this->abstractSchemaName = $abstractSchemaName; + $this->aliasIdentificationVariable = $aliasIdentificationVar; + } + + public function dispatch($walker) + { + return $walker->walkRangeVariableDeclaration($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SelectClause.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SelectClause.php new file mode 100644 index 0000000..cf8e9df --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SelectClause.php @@ -0,0 +1,50 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * SelectClause = "SELECT" ["DISTINCT"] SelectExpression {"," SelectExpression} + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class SelectClause extends Node +{ + public $isDistinct; + public $selectExpressions = array(); + + public function __construct(array $selectExpressions, $isDistinct) + { + $this->isDistinct = $isDistinct; + $this->selectExpressions = $selectExpressions; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkSelectClause($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SelectExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SelectExpression.php new file mode 100644 index 0000000..fd0d49b --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SelectExpression.php @@ -0,0 +1,53 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * SelectExpression ::= IdentificationVariable ["." "*"] | StateFieldPathExpression | + * (AggregateExpression | "(" Subselect ")") [["AS"] ["HIDDEN"] FieldAliasIdentificationVariable] + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class SelectExpression extends Node +{ + public $expression; + public $fieldIdentificationVariable; + public $hiddenAliasResultVariable; + + public function __construct($expression, $fieldIdentificationVariable, $hiddenAliasResultVariable = false) + { + $this->expression = $expression; + $this->fieldIdentificationVariable = $fieldIdentificationVariable; + $this->hiddenAliasResultVariable = $hiddenAliasResultVariable; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkSelectExpression($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SelectStatement.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SelectStatement.php new file mode 100644 index 0000000..d65a97b --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SelectStatement.php @@ -0,0 +1,53 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * SelectStatement = SelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class SelectStatement extends Node +{ + public $selectClause; + public $fromClause; + public $whereClause; + public $groupByClause; + public $havingClause; + public $orderByClause; + + public function __construct($selectClause, $fromClause) { + $this->selectClause = $selectClause; + $this->fromClause = $fromClause; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkSelectStatement($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SimpleArithmeticExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SimpleArithmeticExpression.php new file mode 100644 index 0000000..3fb6f05 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SimpleArithmeticExpression.php @@ -0,0 +1,48 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * SimpleArithmeticExpression ::= ArithmeticTerm {("+" | "-") ArithmeticTerm}* + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class SimpleArithmeticExpression extends Node +{ + public $arithmeticTerms = array(); + + public function __construct(array $arithmeticTerms) + { + $this->arithmeticTerms = $arithmeticTerms; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkSimpleArithmeticExpression($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SimpleCaseExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SimpleCaseExpression.php new file mode 100644 index 0000000..586928d --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SimpleCaseExpression.php @@ -0,0 +1,50 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * SimpleCaseExpression ::= "CASE" CaseOperand SimpleWhenClause {SimpleWhenClause}* "ELSE" ScalarExpression "END" + * + * @since 2.2 + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class SimpleCaseExpression extends Node +{ + public $caseOperand = null; + public $simpleWhenClauses = array(); + public $elseScalarExpression = null; + + public function __construct($caseOperand, array $simpleWhenClauses, $elseScalarExpression) + { + $this->caseOperand = $caseOperand; + $this->simpleWhenClauses = $simpleWhenClauses; + $this->elseScalarExpression = $elseScalarExpression; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkSimpleCaseExpression($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SimpleSelectClause.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SimpleSelectClause.php new file mode 100644 index 0000000..8a40280 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SimpleSelectClause.php @@ -0,0 +1,50 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * SimpleSelectClause ::= "SELECT" ["DISTINCT"] SimpleSelectExpression + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class SimpleSelectClause extends Node +{ + public $isDistinct = false; + public $simpleSelectExpression; + + public function __construct($simpleSelectExpression, $isDistinct) + { + $this->simpleSelectExpression = $simpleSelectExpression; + $this->isDistinct = $isDistinct; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkSimpleSelectClause($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SimpleSelectExpression.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SimpleSelectExpression.php new file mode 100644 index 0000000..1648c4d --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SimpleSelectExpression.php @@ -0,0 +1,50 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * SimpleSelectExpression ::= StateFieldPathExpression | IdentificationVariable + * | (AggregateExpression [["AS"] FieldAliasIdentificationVariable]) + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class SimpleSelectExpression extends Node +{ + public $expression; + public $fieldIdentificationVariable; + + public function __construct($expression) + { + $this->expression = $expression; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkSimpleSelectExpression($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SimpleWhenClause.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SimpleWhenClause.php new file mode 100644 index 0000000..0345328 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SimpleWhenClause.php @@ -0,0 +1,48 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * SimpleWhenClause ::= "WHEN" ScalarExpression "THEN" ScalarExpression + * + * @since 2.2 + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class SimpleWhenClause extends Node +{ + public $caseScalarExpression = null; + public $thenScalarExpression = null; + + public function __construct($caseScalarExpression, $thenScalarExpression) + { + $this->caseScalarExpression = $caseScalarExpression; + $this->thenScalarExpression = $thenScalarExpression; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkWhenClauseExpression($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Subselect.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Subselect.php new file mode 100644 index 0000000..548e42b --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/Subselect.php @@ -0,0 +1,54 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * Subselect ::= SimpleSelectClause SubselectFromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class Subselect extends Node +{ + public $simpleSelectClause; + public $subselectFromClause; + public $whereClause; + public $groupByClause; + public $havingClause; + public $orderByClause; + + public function __construct($simpleSelectClause, $subselectFromClause) + { + $this->simpleSelectClause = $simpleSelectClause; + $this->subselectFromClause = $subselectFromClause; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkSubselect($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SubselectFromClause.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SubselectFromClause.php new file mode 100644 index 0000000..c7c2f35 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/SubselectFromClause.php @@ -0,0 +1,48 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * SubselectFromClause ::= "FROM" SubselectIdentificationVariableDeclaration {"," SubselectIdentificationVariableDeclaration}* + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class SubselectFromClause extends Node +{ + public $identificationVariableDeclarations = array(); + + public function __construct(array $identificationVariableDeclarations) + { + $this->identificationVariableDeclarations = $identificationVariableDeclarations; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkSubselectFromClause($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/UpdateClause.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/UpdateClause.php new file mode 100644 index 0000000..158cf24 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/UpdateClause.php @@ -0,0 +1,52 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * UpdateClause ::= "UPDATE" AbstractSchemaName [["AS"] AliasIdentificationVariable] "SET" UpdateItem {"," UpdateItem}* + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class UpdateClause extends Node +{ + public $abstractSchemaName; + public $aliasIdentificationVariable; + public $updateItems = array(); + + public function __construct($abstractSchemaName, array $updateItems) + { + $this->abstractSchemaName = $abstractSchemaName; + $this->updateItems = $updateItems; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkUpdateClause($this); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/UpdateItem.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/UpdateItem.php new file mode 100644 index 0000000..5f8b678 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/UpdateItem.php @@ -0,0 +1,53 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * UpdateItem ::= [IdentificationVariable "."] {StateField | SingleValuedAssociationField} "=" NewValue + * NewValue ::= SimpleArithmeticExpression | StringPrimary | DatetimePrimary | BooleanPrimary | + * EnumPrimary | SimpleEntityExpression | "NULL" + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class UpdateItem extends Node +{ + public $pathExpression; + public $newValue; + + public function __construct($pathExpression, $newValue) + { + $this->pathExpression = $pathExpression; + $this->newValue = $newValue; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkUpdateItem($this); + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/UpdateStatement.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/UpdateStatement.php new file mode 100644 index 0000000..d1e152e --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/UpdateStatement.php @@ -0,0 +1,49 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * UpdateStatement = UpdateClause [WhereClause] + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class UpdateStatement extends Node +{ + public $updateClause; + public $whereClause; + + public function __construct($updateClause) + { + $this->updateClause = $updateClause; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkUpdateStatement($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/WhenClause.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/WhenClause.php new file mode 100644 index 0000000..69556e5 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/WhenClause.php @@ -0,0 +1,48 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * WhenClause ::= "WHEN" ConditionalExpression "THEN" ScalarExpression + * + * @since 2.2 + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class WhenClause extends Node +{ + public $caseConditionExpression = null; + public $thenScalarExpression = null; + + public function __construct($caseConditionExpression, $thenScalarExpression) + { + $this->caseConditionExpression = $caseConditionExpression; + $this->thenScalarExpression = $thenScalarExpression; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkWhenClauseExpression($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/WhereClause.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/WhereClause.php new file mode 100644 index 0000000..5d3f9c9 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/WhereClause.php @@ -0,0 +1,48 @@ +. + */ + +namespace Doctrine\ORM\Query\AST; + +/** + * WhereClause ::= "WHERE" ConditionalExpression + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class WhereClause extends Node +{ + public $conditionalExpression; + + public function __construct($conditionalExpression) + { + $this->conditionalExpression = $conditionalExpression; + } + + public function dispatch($sqlWalker) + { + return $sqlWalker->walkWhereClause($this); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php new file mode 100644 index 0000000..d639223 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php @@ -0,0 +1,70 @@ +. + */ + +namespace Doctrine\ORM\Query\Exec; + +use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Cache\QueryCacheProfile; + +/** + * Base class for SQL statement executors. + * + * @author Roman Borschel + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link http://www.doctrine-project.org + * @since 2.0 + * @todo Rename: AbstractSQLExecutor + */ +abstract class AbstractSqlExecutor +{ + /** + * @var array + */ + protected $_sqlStatements; + + /** + * @var QueryCacheProfile + */ + protected $queryCacheProfile; + + /** + * Gets the SQL statements that are executed by the executor. + * + * @return array All the SQL update statements. + */ + public function getSqlStatements() + { + return $this->_sqlStatements; + } + + public function setQueryCacheProfile(QueryCacheProfile $qcp) + { + $this->queryCacheProfile = $qcp; + } + + /** + * Executes all sql statements. + * + * @param \Doctrine\DBAL\Connection $conn The database connection that is used to execute the queries. + * @param array $params The parameters. + * @param array $types The parameter types. + * @return \Doctrine\DBAL\Driver\Statement + */ + abstract public function execute(Connection $conn, array $params, array $types); +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php new file mode 100644 index 0000000..51f4b8c --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php @@ -0,0 +1,124 @@ +. + */ + +namespace Doctrine\ORM\Query\Exec; + +use Doctrine\DBAL\Connection, + Doctrine\ORM\Query\AST; + +/** + * Executes the SQL statements for bulk DQL DELETE statements on classes in + * Class Table Inheritance (JOINED). + * + * @author Roman Borschel + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link http://www.doctrine-project.org + * @since 2.0 + */ +class MultiTableDeleteExecutor extends AbstractSqlExecutor +{ + private $_createTempTableSql; + private $_dropTempTableSql; + private $_insertSql; + + /** + * Initializes a new MultiTableDeleteExecutor. + * + * @param Node $AST The root AST node of the DQL query. + * @param SqlWalker $sqlWalker The walker used for SQL generation from the AST. + * @internal Any SQL construction and preparation takes place in the constructor for + * best performance. With a query cache the executor will be cached. + */ + public function __construct(AST\Node $AST, $sqlWalker) + { + $em = $sqlWalker->getEntityManager(); + $conn = $em->getConnection(); + $platform = $conn->getDatabasePlatform(); + + $primaryClass = $em->getClassMetadata($AST->deleteClause->abstractSchemaName); + $primaryDqlAlias = $AST->deleteClause->aliasIdentificationVariable; + $rootClass = $em->getClassMetadata($primaryClass->rootEntityName); + + $tempTable = $platform->getTemporaryTableName($rootClass->getTemporaryIdTableName()); + $idColumnNames = $rootClass->getIdentifierColumnNames(); + $idColumnList = implode(', ', $idColumnNames); + + // 1. Create an INSERT INTO temptable ... SELECT identifiers WHERE $AST->getWhereClause() + $sqlWalker->setSQLTableAlias($primaryClass->getTableName(), 't0', $primaryDqlAlias); + + $this->_insertSql = 'INSERT INTO ' . $tempTable . ' (' . $idColumnList . ')' + . ' SELECT t0.' . implode(', t0.', $idColumnNames); + + $rangeDecl = new AST\RangeVariableDeclaration($primaryClass->name, $primaryDqlAlias); + $fromClause = new AST\FromClause(array(new AST\IdentificationVariableDeclaration($rangeDecl, null, array()))); + $this->_insertSql .= $sqlWalker->walkFromClause($fromClause); + + // Append WHERE clause, if there is one. + if ($AST->whereClause) { + $this->_insertSql .= $sqlWalker->walkWhereClause($AST->whereClause); + } + + // 2. Create ID subselect statement used in DELETE ... WHERE ... IN (subselect) + $idSubselect = 'SELECT ' . $idColumnList . ' FROM ' . $tempTable; + + // 3. Create and store DELETE statements + $classNames = array_merge($primaryClass->parentClasses, array($primaryClass->name), $primaryClass->subClasses); + foreach (array_reverse($classNames) as $className) { + $tableName = $em->getClassMetadata($className)->getQuotedTableName($platform); + $this->_sqlStatements[] = 'DELETE FROM ' . $tableName + . ' WHERE (' . $idColumnList . ') IN (' . $idSubselect . ')'; + } + + // 4. Store DDL for temporary identifier table. + $columnDefinitions = array(); + foreach ($idColumnNames as $idColumnName) { + $columnDefinitions[$idColumnName] = array( + 'notnull' => true, + 'type' => \Doctrine\DBAL\Types\Type::getType($rootClass->getTypeOfColumn($idColumnName)) + ); + } + $this->_createTempTableSql = $platform->getCreateTemporaryTableSnippetSQL() . ' ' . $tempTable . ' (' + . $platform->getColumnDeclarationListSQL($columnDefinitions) . ')'; + $this->_dropTempTableSql = $platform->getDropTemporaryTableSQL($tempTable); + } + + /** + * {@inheritDoc} + */ + public function execute(Connection $conn, array $params, array $types) + { + $numDeleted = 0; + + // Create temporary id table + $conn->executeUpdate($this->_createTempTableSql); + + // Insert identifiers + $numDeleted = $conn->executeUpdate($this->_insertSql, $params, $types); + + // Execute DELETE statements + foreach ($this->_sqlStatements as $sql) { + $conn->executeUpdate($sql); + } + + // Drop temporary table + $conn->executeUpdate($this->_dropTempTableSql); + + return $numDeleted; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php new file mode 100644 index 0000000..8be24e5 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php @@ -0,0 +1,178 @@ +. + */ + +namespace Doctrine\ORM\Query\Exec; + +use Doctrine\DBAL\Connection, + Doctrine\DBAL\Types\Type, + Doctrine\ORM\Query\AST; + +/** + * Executes the SQL statements for bulk DQL UPDATE statements on classes in + * Class Table Inheritance (JOINED). + * + * @author Roman Borschel + * @since 2.0 + */ +class MultiTableUpdateExecutor extends AbstractSqlExecutor +{ + private $_createTempTableSql; + private $_dropTempTableSql; + private $_insertSql; + private $_sqlParameters = array(); + private $_numParametersInUpdateClause = 0; + + /** + * Initializes a new MultiTableUpdateExecutor. + * + * @param Node $AST The root AST node of the DQL query. + * @param SqlWalker $sqlWalker The walker used for SQL generation from the AST. + * @internal Any SQL construction and preparation takes place in the constructor for + * best performance. With a query cache the executor will be cached. + */ + public function __construct(AST\Node $AST, $sqlWalker) + { + $em = $sqlWalker->getEntityManager(); + $conn = $em->getConnection(); + $platform = $conn->getDatabasePlatform(); + + $updateClause = $AST->updateClause; + + $primaryClass = $sqlWalker->getEntityManager()->getClassMetadata($updateClause->abstractSchemaName); + $rootClass = $em->getClassMetadata($primaryClass->rootEntityName); + + $updateItems = $updateClause->updateItems; + + $tempTable = $platform->getTemporaryTableName($rootClass->getTemporaryIdTableName()); + $idColumnNames = $rootClass->getIdentifierColumnNames(); + $idColumnList = implode(', ', $idColumnNames); + + // 1. Create an INSERT INTO temptable ... SELECT identifiers WHERE $AST->getWhereClause() + $sqlWalker->setSQLTableAlias($primaryClass->getTableName(), 't0', $updateClause->aliasIdentificationVariable); + + $this->_insertSql = 'INSERT INTO ' . $tempTable . ' (' . $idColumnList . ')' + . ' SELECT t0.' . implode(', t0.', $idColumnNames); + + $rangeDecl = new AST\RangeVariableDeclaration($primaryClass->name, $updateClause->aliasIdentificationVariable); + $fromClause = new AST\FromClause(array(new AST\IdentificationVariableDeclaration($rangeDecl, null, array()))); + + $this->_insertSql .= $sqlWalker->walkFromClause($fromClause); + + // 2. Create ID subselect statement used in UPDATE ... WHERE ... IN (subselect) + $idSubselect = 'SELECT ' . $idColumnList . ' FROM ' . $tempTable; + + // 3. Create and store UPDATE statements + $classNames = array_merge($primaryClass->parentClasses, array($primaryClass->name), $primaryClass->subClasses); + $i = -1; + + foreach (array_reverse($classNames) as $className) { + $affected = false; + $class = $em->getClassMetadata($className); + $updateSql = 'UPDATE ' . $class->getQuotedTableName($platform) . ' SET '; + + foreach ($updateItems as $updateItem) { + $field = $updateItem->pathExpression->field; + + if (isset($class->fieldMappings[$field]) && ! isset($class->fieldMappings[$field]['inherited']) || + isset($class->associationMappings[$field]) && ! isset($class->associationMappings[$field]['inherited'])) { + $newValue = $updateItem->newValue; + + if ( ! $affected) { + $affected = true; + ++$i; + } else { + $updateSql .= ', '; + } + + $updateSql .= $sqlWalker->walkUpdateItem($updateItem); + + //FIXME: parameters can be more deeply nested. traverse the tree. + //FIXME (URGENT): With query cache the parameter is out of date. Move to execute() stage. + if ($newValue instanceof AST\InputParameter) { + $paramKey = $newValue->name; + $this->_sqlParameters[$i]['parameters'][] = $sqlWalker->getQuery()->getParameter($paramKey); + $this->_sqlParameters[$i]['types'][] = $sqlWalker->getQuery()->getParameterType($paramKey); + + ++$this->_numParametersInUpdateClause; + } + } + } + + if ($affected) { + $this->_sqlStatements[$i] = $updateSql . ' WHERE (' . $idColumnList . ') IN (' . $idSubselect . ')'; + } + } + + // Append WHERE clause to insertSql, if there is one. + if ($AST->whereClause) { + $this->_insertSql .= $sqlWalker->walkWhereClause($AST->whereClause); + } + + // 4. Store DDL for temporary identifier table. + $columnDefinitions = array(); + + foreach ($idColumnNames as $idColumnName) { + $columnDefinitions[$idColumnName] = array( + 'notnull' => true, + 'type' => Type::getType($rootClass->getTypeOfColumn($idColumnName)) + ); + } + + $this->_createTempTableSql = $platform->getCreateTemporaryTableSnippetSQL() . ' ' . $tempTable . ' (' + . $platform->getColumnDeclarationListSQL($columnDefinitions) . ')'; + + $this->_dropTempTableSql = $platform->getDropTemporaryTableSQL($tempTable); + } + + /** + * {@inheritDoc} + */ + public function execute(Connection $conn, array $params, array $types) + { + $numUpdated = 0; + + // Create temporary id table + $conn->executeUpdate($this->_createTempTableSql); + + // Insert identifiers. Parameters from the update clause are cut off. + $numUpdated = $conn->executeUpdate( + $this->_insertSql, + array_slice($params, $this->_numParametersInUpdateClause), + array_slice($types, $this->_numParametersInUpdateClause) + ); + + // Execute UPDATE statements + for ($i=0, $count=count($this->_sqlStatements); $i<$count; ++$i) { + $parameters = array(); + $types = array(); + + if (isset($this->_sqlParameters[$i])) { + $parameters = isset($this->_sqlParameters[$i]['parameters']) ? $this->_sqlParameters[$i]['parameters'] : array(); + $types = isset($this->_sqlParameters[$i]['types']) ? $this->_sqlParameters[$i]['types'] : array(); + } + + $conn->executeUpdate($this->_sqlStatements[$i], $parameters, $types); + } + + // Drop temporary table + $conn->executeUpdate($this->_dropTempTableSql); + + return $numUpdated; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Exec/SingleSelectExecutor.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Exec/SingleSelectExecutor.php new file mode 100644 index 0000000..61c42d8 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Exec/SingleSelectExecutor.php @@ -0,0 +1,48 @@ +. + */ + +namespace Doctrine\ORM\Query\Exec; + +use Doctrine\DBAL\Connection, + Doctrine\ORM\Query\AST\SelectStatement, + Doctrine\ORM\Query\SqlWalker; + +/** + * Executor that executes the SQL statement for simple DQL SELECT statements. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @author Roman Borschel + * @link www.doctrine-project.org + * @since 2.0 + */ +class SingleSelectExecutor extends AbstractSqlExecutor +{ + public function __construct(SelectStatement $AST, SqlWalker $sqlWalker) + { + $this->_sqlStatements = $sqlWalker->walkSelectStatement($AST); + } + + /** + * {@inheritDoc} + */ + public function execute(Connection $conn, array $params, array $types) + { + return $conn->executeQuery($this->_sqlStatements, $params, $types, $this->queryCacheProfile); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Exec/SingleTableDeleteUpdateExecutor.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Exec/SingleTableDeleteUpdateExecutor.php new file mode 100644 index 0000000..467ce54 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Exec/SingleTableDeleteUpdateExecutor.php @@ -0,0 +1,53 @@ +. + */ + +namespace Doctrine\ORM\Query\Exec; + +use Doctrine\DBAL\Connection, + Doctrine\ORM\Query\AST; + +/** + * Executor that executes the SQL statements for DQL DELETE/UPDATE statements on classes + * that are mapped to a single table. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @author Roman Borschel + * @link www.doctrine-project.org + * @since 2.0 + * @todo This is exactly the same as SingleSelectExecutor. Unify in SingleStatementExecutor. + */ +class SingleTableDeleteUpdateExecutor extends AbstractSqlExecutor +{ + public function __construct(AST\Node $AST, $sqlWalker) + { + if ($AST instanceof AST\UpdateStatement) { + $this->_sqlStatements = $sqlWalker->walkUpdateStatement($AST); + } else if ($AST instanceof AST\DeleteStatement) { + $this->_sqlStatements = $sqlWalker->walkDeleteStatement($AST); + } + } + + /** + * {@inheritDoc} + */ + public function execute(Connection $conn, array $params, array $types) + { + return $conn->executeUpdate($this->_sqlStatements, $params, $types); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr.php new file mode 100644 index 0000000..adcd25c --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr.php @@ -0,0 +1,595 @@ +. + */ + +namespace Doctrine\ORM\Query; + +/** + * This class is used to generate DQL expressions via a set of PHP static functions + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Benjamin Eberlei + * @todo Rename: ExpressionBuilder + */ +class Expr +{ + /** + * Creates a conjunction of the given boolean expressions. + * + * Example: + * + * [php] + * // (u.type = ?1) AND (u.role = ?2) + * $expr->andX($expr->eq('u.type', ':1'), $expr->eq('u.role', ':2')); + * + * @param \Doctrine\ORM\Query\Expr\Comparison | + * \Doctrine\ORM\Query\Expr\Func | + * \Doctrine\ORM\Query\Expr\Orx + * $x Optional clause. Defaults = null, but requires at least one defined when converting to string. + * @return Expr\Andx + */ + public function andX($x = null) + { + return new Expr\Andx(func_get_args()); + } + + /** + * Creates a disjunction of the given boolean expressions. + * + * Example: + * + * [php] + * // (u.type = ?1) OR (u.role = ?2) + * $q->where($q->expr()->orX('u.type = ?1', 'u.role = ?2')); + * + * @param mixed $x Optional clause. Defaults = null, but requires + * at least one defined when converting to string. + * @return Expr\Orx + */ + public function orX($x = null) + { + return new Expr\Orx(func_get_args()); + } + + /** + * Creates an ASCending order expression. + * + * @param $sort + * @return Expr\OrderBy + */ + public function asc($expr) + { + return new Expr\OrderBy($expr, 'ASC'); + } + + /** + * Creates a DESCending order expression. + * + * @param $sort + * @return Expr\OrderBy + */ + public function desc($expr) + { + return new Expr\OrderBy($expr, 'DESC'); + } + + /** + * Creates an equality comparison expression with the given arguments. + * + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a = . Example: + * + * [php] + * // u.id = ?1 + * $expr->eq('u.id', '?1'); + * + * @param mixed $x Left expression + * @param mixed $y Right expression + * @return Expr\Comparison + */ + public function eq($x, $y) + { + return new Expr\Comparison($x, Expr\Comparison::EQ, $y); + } + + /** + * Creates an instance of Expr\Comparison, with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a <> . Example: + * + * [php] + * // u.id <> ?1 + * $q->where($q->expr()->neq('u.id', '?1')); + * + * @param mixed $x Left expression + * @param mixed $y Right expression + * @return Expr\Comparison + */ + public function neq($x, $y) + { + return new Expr\Comparison($x, Expr\Comparison::NEQ, $y); + } + + /** + * Creates an instance of Expr\Comparison, with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a < . Example: + * + * [php] + * // u.id < ?1 + * $q->where($q->expr()->lt('u.id', '?1')); + * + * @param mixed $x Left expression + * @param mixed $y Right expression + * @return Expr\Comparison + */ + public function lt($x, $y) + { + return new Expr\Comparison($x, Expr\Comparison::LT, $y); + } + + /** + * Creates an instance of Expr\Comparison, with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a <= . Example: + * + * [php] + * // u.id <= ?1 + * $q->where($q->expr()->lte('u.id', '?1')); + * + * @param mixed $x Left expression + * @param mixed $y Right expression + * @return Expr\Comparison + */ + public function lte($x, $y) + { + return new Expr\Comparison($x, Expr\Comparison::LTE, $y); + } + + /** + * Creates an instance of Expr\Comparison, with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a > . Example: + * + * [php] + * // u.id > ?1 + * $q->where($q->expr()->gt('u.id', '?1')); + * + * @param mixed $x Left expression + * @param mixed $y Right expression + * @return Expr\Comparison + */ + public function gt($x, $y) + { + return new Expr\Comparison($x, Expr\Comparison::GT, $y); + } + + /** + * Creates an instance of Expr\Comparison, with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a >= . Example: + * + * [php] + * // u.id >= ?1 + * $q->where($q->expr()->gte('u.id', '?1')); + * + * @param mixed $x Left expression + * @param mixed $y Right expression + * @return Expr\Comparison + */ + public function gte($x, $y) + { + return new Expr\Comparison($x, Expr\Comparison::GTE, $y); + } + + /** + * Creates an instance of AVG() function, with the given argument. + * + * @param mixed $x Argument to be used in AVG() function. + * @return Expr\Func + */ + public function avg($x) + { + return new Expr\Func('AVG', array($x)); + } + + /** + * Creates an instance of MAX() function, with the given argument. + * + * @param mixed $x Argument to be used in MAX() function. + * @return Expr\Func + */ + public function max($x) + { + return new Expr\Func('MAX', array($x)); + } + + /** + * Creates an instance of MIN() function, with the given argument. + * + * @param mixed $x Argument to be used in MIN() function. + * @return Expr\Func + */ + public function min($x) + { + return new Expr\Func('MIN', array($x)); + } + + /** + * Creates an instance of COUNT() function, with the given argument. + * + * @param mixed $x Argument to be used in COUNT() function. + * @return Expr\Func + */ + public function count($x) + { + return new Expr\Func('COUNT', array($x)); + } + + /** + * Creates an instance of COUNT(DISTINCT) function, with the given argument. + * + * @param mixed $x Argument to be used in COUNT(DISTINCT) function. + * @return string + */ + public function countDistinct($x) + { + return 'COUNT(DISTINCT ' . implode(', ', func_get_args()) . ')'; + } + + /** + * Creates an instance of EXISTS() function, with the given DQL Subquery. + * + * @param mixed $subquery DQL Subquery to be used in EXISTS() function. + * @return Expr\Func + */ + public function exists($subquery) + { + return new Expr\Func('EXISTS', array($subquery)); + } + + /** + * Creates an instance of ALL() function, with the given DQL Subquery. + * + * @param mixed $subquery DQL Subquery to be used in ALL() function. + * @return Expr\Func + */ + public function all($subquery) + { + return new Expr\Func('ALL', array($subquery)); + } + + /** + * Creates a SOME() function expression with the given DQL subquery. + * + * @param mixed $subquery DQL Subquery to be used in SOME() function. + * @return Expr\Func + */ + public function some($subquery) + { + return new Expr\Func('SOME', array($subquery)); + } + + /** + * Creates an ANY() function expression with the given DQL subquery. + * + * @param mixed $subquery DQL Subquery to be used in ANY() function. + * @return Expr\Func + */ + public function any($subquery) + { + return new Expr\Func('ANY', array($subquery)); + } + + /** + * Creates a negation expression of the given restriction. + * + * @param mixed $restriction Restriction to be used in NOT() function. + * @return Expr\Func + */ + public function not($restriction) + { + return new Expr\Func('NOT', array($restriction)); + } + + /** + * Creates an ABS() function expression with the given argument. + * + * @param mixed $x Argument to be used in ABS() function. + * @return Expr\Func + */ + public function abs($x) + { + return new Expr\Func('ABS', array($x)); + } + + /** + * Creates a product mathematical expression with the given arguments. + * + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a * . Example: + * + * [php] + * // u.salary * u.percentAnualSalaryIncrease + * $q->expr()->prod('u.salary', 'u.percentAnualSalaryIncrease') + * + * @param mixed $x Left expression + * @param mixed $y Right expression + * @return Expr\Math + */ + public function prod($x, $y) + { + return new Expr\Math($x, '*', $y); + } + + /** + * Creates a difference mathematical expression with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a - . Example: + * + * [php] + * // u.monthlySubscriptionCount - 1 + * $q->expr()->diff('u.monthlySubscriptionCount', '1') + * + * @param mixed $x Left expression + * @param mixed $y Right expression + * @return Expr\Math + */ + public function diff($x, $y) + { + return new Expr\Math($x, '-', $y); + } + + /** + * Creates a sum mathematical expression with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a + . Example: + * + * [php] + * // u.numChildren + 1 + * $q->expr()->diff('u.numChildren', '1') + * + * @param mixed $x Left expression + * @param mixed $y Right expression + * @return Expr\Math + */ + public function sum($x, $y) + { + return new Expr\Math($x, '+', $y); + } + + /** + * Creates a quotient mathematical expression with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a / . Example: + * + * [php] + * // u.total / u.period + * $expr->quot('u.total', 'u.period') + * + * @param mixed $x Left expression + * @param mixed $y Right expression + * @return Expr\Math + */ + public function quot($x, $y) + { + return new Expr\Math($x, '/', $y); + } + + /** + * Creates a SQRT() function expression with the given argument. + * + * @param mixed $x Argument to be used in SQRT() function. + * @return Expr\Func + */ + public function sqrt($x) + { + return new Expr\Func('SQRT', array($x)); + } + + /** + * Creates an IN() expression with the given arguments. + * + * @param string $x Field in string format to be restricted by IN() function + * @param mixed $y Argument to be used in IN() function. + * @return Expr\Func + */ + public function in($x, $y) + { + if (is_array($y)) { + foreach ($y as &$literal) { + if ( ! ($literal instanceof Expr\Literal)) { + $literal = $this->_quoteLiteral($literal); + } + } + } + return new Expr\Func($x . ' IN', (array) $y); + } + + /** + * Creates a NOT IN() expression with the given arguments. + * + * @param string $x Field in string format to be restricted by NOT IN() function + * @param mixed $y Argument to be used in NOT IN() function. + * @return Expr\Func + */ + public function notIn($x, $y) + { + if (is_array($y)) { + foreach ($y as &$literal) { + if ( ! ($literal instanceof Expr\Literal)) { + $literal = $this->_quoteLiteral($literal); + } + } + } + return new Expr\Func($x . ' NOT IN', (array) $y); + } + + /** + * Creates an IS NULL expression with the given arguments. + * + * @param string $x Field in string format to be restricted by IS NULL + * @return string + */ + public function isNull($x) + { + return $x . ' IS NULL'; + } + + /** + * Creates an IS NOT NULL expression with the given arguments. + * + * @param string $x Field in string format to be restricted by IS NOT NULL + * @return string + */ + public function isNotNull($x) + { + return $x . ' IS NOT NULL'; + } + + /** + * Creates a LIKE() comparison expression with the given arguments. + * + * @param string $x Field in string format to be inspected by LIKE() comparison. + * @param mixed $y Argument to be used in LIKE() comparison. + * @return Expr\Comparison + */ + public function like($x, $y) + { + return new Expr\Comparison($x, 'LIKE', $y); + } + + /** + * Creates a CONCAT() function expression with the given arguments. + * + * @param mixed $x First argument to be used in CONCAT() function. + * @param mixed $x Second argument to be used in CONCAT() function. + * @return Expr\Func + */ + public function concat($x, $y) + { + return new Expr\Func('CONCAT', array($x, $y)); + } + + /** + * Creates a SUBSTRING() function expression with the given arguments. + * + * @param mixed $x Argument to be used as string to be cropped by SUBSTRING() function. + * @param integer $from Initial offset to start cropping string. May accept negative values. + * @param integer $len Length of crop. May accept negative values. + * @return Expr\Func + */ + public function substring($x, $from, $len = null) + { + $args = array($x, $from); + if (null !== $len) { + $args[] = $len; + } + return new Expr\Func('SUBSTRING', $args); + } + + /** + * Creates a LOWER() function expression with the given argument. + * + * @param mixed $x Argument to be used in LOWER() function. + * @return Expr\Func A LOWER function expression. + */ + public function lower($x) + { + return new Expr\Func('LOWER', array($x)); + } + + /** + * Creates an UPPER() function expression with the given argument. + * + * @param mixed $x Argument to be used in UPPER() function. + * @return Expr\Func An UPPER function expression. + */ + public function upper($x) + { + return new Expr\Func('UPPER', array($x)); + } + + /** + * Creates a LENGTH() function expression with the given argument. + * + * @param mixed $x Argument to be used as argument of LENGTH() function. + * @return Expr\Func A LENGTH function expression. + */ + public function length($x) + { + return new Expr\Func('LENGTH', array($x)); + } + + /** + * Creates a literal expression of the given argument. + * + * @param mixed $literal Argument to be converted to literal. + * @return Expr\Literal + */ + public function literal($literal) + { + return new Expr\Literal($this->_quoteLiteral($literal)); + } + + /** + * Quotes a literal value, if necessary, according to the DQL syntax. + * + * @param mixed $literal The literal value. + * @return string + */ + private function _quoteLiteral($literal) + { + if (is_numeric($literal) && !is_string($literal)) { + return (string) $literal; + } else if (is_bool($literal)) { + return $literal ? "true" : "false"; + } else { + return "'" . str_replace("'", "''", $literal) . "'"; + } + } + + /** + * Creates an instance of BETWEEN() function, with the given argument. + * + * @param mixed $val Valued to be inspected by range values. + * @param integer $x Starting range value to be used in BETWEEN() function. + * @param integer $y End point value to be used in BETWEEN() function. + * @return Expr\Func A BETWEEN expression. + */ + public function between($val, $x, $y) + { + return $val . ' BETWEEN ' . $x . ' AND ' . $y; + } + + /** + * Creates an instance of TRIM() function, with the given argument. + * + * @param mixed $x Argument to be used as argument of TRIM() function. + * @return Expr\Func a TRIM expression. + */ + public function trim($x) + { + return new Expr\Func('TRIM', $x); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Andx.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Andx.php new file mode 100644 index 0000000..c5cf1f3 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Andx.php @@ -0,0 +1,44 @@ +. + */ + +namespace Doctrine\ORM\Query\Expr; + +/** + * Expression class for building DQL and parts + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class Andx extends Composite +{ + protected $_separator = ' AND '; + protected $_allowedClasses = array( + 'Doctrine\ORM\Query\Expr\Comparison', + 'Doctrine\ORM\Query\Expr\Func', + 'Doctrine\ORM\Query\Expr\Orx', + 'Doctrine\ORM\Query\Expr\Andx', + ); +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base.php new file mode 100644 index 0000000..975d450 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base.php @@ -0,0 +1,89 @@ +. + */ + +namespace Doctrine\ORM\Query\Expr; + +/** + * Abstract base Expr class for building DQL parts + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +abstract class Base +{ + protected $_preSeparator = '('; + protected $_separator = ', '; + protected $_postSeparator = ')'; + protected $_allowedClasses = array(); + + protected $_parts = array(); + + public function __construct($args = array()) + { + $this->addMultiple($args); + } + + public function addMultiple($args = array()) + { + foreach ((array) $args as $arg) { + $this->add($arg); + } + + return $this; + } + + public function add($arg) + { + if ( $arg !== null || ($arg instanceof self && $arg->count() > 0) ) { + // If we decide to keep Expr\Base instances, we can use this check + if ( ! is_string($arg)) { + $class = get_class($arg); + + if ( ! in_array($class, $this->_allowedClasses)) { + throw new \InvalidArgumentException("Expression of type '$class' not allowed in this context."); + } + } + + $this->_parts[] = $arg; + } + + return $this; + } + + public function count() + { + return count($this->_parts); + } + + public function __toString() + { + if ($this->count() == 1) { + return (string) $this->_parts[0]; + } + + return $this->_preSeparator . implode($this->_separator, $this->_parts) . $this->_postSeparator; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Comparison.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Comparison.php new file mode 100644 index 0000000..d42560e --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Comparison.php @@ -0,0 +1,59 @@ +. + */ + +namespace Doctrine\ORM\Query\Expr; + +/** + * Expression class for DQL comparison expressions + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class Comparison +{ + const EQ = '='; + const NEQ = '<>'; + const LT = '<'; + const LTE = '<='; + const GT = '>'; + const GTE = '>='; + + private $_leftExpr; + private $_operator; + private $_rightExpr; + + public function __construct($leftExpr, $operator, $rightExpr) + { + $this->_leftExpr = $leftExpr; + $this->_operator = $operator; + $this->_rightExpr = $rightExpr; + } + + public function __toString() + { + return $this->_leftExpr . ' ' . $this->_operator . ' ' . $this->_rightExpr; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Composite.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Composite.php new file mode 100644 index 0000000..036b241 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Composite.php @@ -0,0 +1,68 @@ +. + */ + +namespace Doctrine\ORM\Query\Expr; + +/** + * Expression class for building DQL and parts + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class Composite extends Base +{ + public function __toString() + { + if ($this->count() === 1) { + return (string) $this->_parts[0]; + } + + $components = array(); + + foreach ($this->_parts as $part) { + $components[] = $this->processQueryPart($part); + } + + return implode($this->_separator, $components); + } + + + private function processQueryPart($part) + { + $queryPart = (string) $part; + + if (is_object($part) && $part instanceof self && $part->count() > 1) { + return $this->_preSeparator . $queryPart . $this->_postSeparator; + } + + // Fixes DDC-1237: User may have added a where item containing nested expression (with "OR" or "AND") + if (stripos($queryPart, ' OR ') !== false || stripos($queryPart, ' AND ') !== false) { + return $this->_preSeparator . $queryPart . $this->_postSeparator; + } + + return $queryPart; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/From.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/From.php new file mode 100644 index 0000000..e5707cc --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/From.php @@ -0,0 +1,88 @@ +. + */ + +namespace Doctrine\ORM\Query\Expr; + +/** + * Expression class for DQL from + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class From +{ + /** + * @var string + */ + private $_from; + + /** + * @var string + */ + private $_alias; + + /** + * @var string + */ + private $_indexBy; + + /** + * @param string $from The class name. + * @param string $alias The alias of the class. + * @param string $indexBy The index for the from. + */ + public function __construct($from, $alias, $indexBy = null) + { + $this->_from = $from; + $this->_alias = $alias; + $this->_indexBy = $indexBy; + } + + /** + * @return string + */ + public function getFrom() + { + return $this->_from; + } + + /** + * @return string + */ + public function getAlias() + { + return $this->_alias; + } + + /** + * @return string + */ + public function __toString() + { + return $this->_from . ' ' . $this->_alias . + ($this->_indexBy ? ' INDEX BY ' . $this->_indexBy : ''); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Func.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Func.php new file mode 100644 index 0000000..48b1a5b --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Func.php @@ -0,0 +1,50 @@ +. + */ + +namespace Doctrine\ORM\Query\Expr; + +/** + * Expression class for generating DQL functions + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class Func +{ + private $_name; + private $_arguments; + + public function __construct($name, $arguments) + { + $this->_name = $name; + $this->_arguments = (array) $arguments; + } + + public function __toString() + { + return $this->_name . '(' . implode(', ', $this->_arguments) . ')'; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/GroupBy.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/GroupBy.php new file mode 100644 index 0000000..dc36ba3 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/GroupBy.php @@ -0,0 +1,39 @@ +. + */ + +namespace Doctrine\ORM\Query\Expr; + +/** + * Expression class for building DQL Group By parts + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class GroupBy extends Base +{ + protected $_preSeparator = ''; + protected $_postSeparator = ''; +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Join.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Join.php new file mode 100644 index 0000000..14f5b43 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Join.php @@ -0,0 +1,67 @@ +. + */ + +namespace Doctrine\ORM\Query\Expr; + +/** + * Expression class for DQL from + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class Join +{ + const INNER_JOIN = 'INNER'; + const LEFT_JOIN = 'LEFT'; + + const ON = 'ON'; + const WITH = 'WITH'; + + private $_joinType; + private $_join; + private $_alias; + private $_conditionType; + private $_condition; + private $_indexBy; + + public function __construct($joinType, $join, $alias = null, $conditionType = null, $condition = null, $indexBy = null) + { + $this->_joinType = $joinType; + $this->_join = $join; + $this->_alias = $alias; + $this->_conditionType = $conditionType; + $this->_condition = $condition; + $this->_indexBy = $indexBy; + } + + public function __toString() + { + return strtoupper($this->_joinType) . ' JOIN ' . $this->_join + . ($this->_alias ? ' ' . $this->_alias : '') + . ($this->_condition ? ' ' . strtoupper($this->_conditionType) . ' ' . $this->_condition : '') + . ($this->_indexBy ? ' INDEX BY ' . $this->_indexBy : ''); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Literal.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Literal.php new file mode 100644 index 0000000..c1dd5f7 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Literal.php @@ -0,0 +1,9 @@ +. + */ + +namespace Doctrine\ORM\Query\Expr; + +/** + * Expression class for DQL math statements + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class Math +{ + private $_leftExpr; + private $_operator; + private $_rightExpr; + + public function __construct($leftExpr, $operator, $rightExpr) + { + $this->_leftExpr = $leftExpr; + $this->_operator = $operator; + $this->_rightExpr = $rightExpr; + } + + public function __toString() + { + // Adjusting Left Expression + $leftExpr = (string) $this->_leftExpr; + + if ($this->_leftExpr instanceof Math) { + $leftExpr = '(' . $leftExpr . ')'; + } + + // Adjusting Right Expression + $rightExpr = (string) $this->_rightExpr; + + if ($this->_rightExpr instanceof Math) { + $rightExpr = '(' . $rightExpr . ')'; + } + + return $leftExpr . ' ' . $this->_operator . ' ' . $rightExpr; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/OrderBy.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/OrderBy.php new file mode 100644 index 0000000..a24e286 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/OrderBy.php @@ -0,0 +1,66 @@ +. + */ + +namespace Doctrine\ORM\Query\Expr; + +/** + * Expression class for building DQL Order By parts + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class OrderBy +{ + protected $_preSeparator = ''; + protected $_separator = ', '; + protected $_postSeparator = ''; + protected $_allowedClasses = array(); + + private $_parts = array(); + + public function __construct($sort = null, $order = null) + { + if ($sort) { + $this->add($sort, $order); + } + } + + public function add($sort, $order = null) + { + $order = ! $order ? 'ASC' : $order; + $this->_parts[] = $sort . ' '. $order; + } + + public function count() + { + return count($this->_parts); + } + + public function __tostring() + { + return $this->_preSeparator . implode($this->_separator, $this->_parts) . $this->_postSeparator; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Orx.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Orx.php new file mode 100644 index 0000000..742e499 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Orx.php @@ -0,0 +1,44 @@ +. + */ + +namespace Doctrine\ORM\Query\Expr; + +/** + * Expression class for building DQL OR clauses + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class Orx extends Composite +{ + protected $_separator = ' OR '; + protected $_allowedClasses = array( + 'Doctrine\ORM\Query\Expr\Comparison', + 'Doctrine\ORM\Query\Expr\Func', + 'Doctrine\ORM\Query\Expr\Andx', + 'Doctrine\ORM\Query\Expr\Orx', + ); +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Select.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Select.php new file mode 100644 index 0000000..a310a0c --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Select.php @@ -0,0 +1,42 @@ +. + */ + +namespace Doctrine\ORM\Query\Expr; + +/** + * Expression class for building DQL select statements + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class Select extends Base +{ + protected $_preSeparator = ''; + protected $_postSeparator = ''; + protected $_allowedClasses = array( + 'Doctrine\ORM\Query\Expr\Func' + ); +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Filter/SQLFilter.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Filter/SQLFilter.php new file mode 100644 index 0000000..a87dd84 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Filter/SQLFilter.php @@ -0,0 +1,122 @@ +. + */ + +namespace Doctrine\ORM\Query\Filter; + +use Doctrine\ORM\EntityManager, + Doctrine\ORM\Mapping\ClassMetaData, + Doctrine\ORM\Query\ParameterTypeInferer; + +/** + * The base class that user defined filters should extend. + * + * Handles the setting and escaping of parameters. + * + * @author Alexander + * @author Benjamin Eberlei + * @abstract + */ +abstract class SQLFilter +{ + /** + * The entity manager. + * @var EntityManager + */ + private $em; + + /** + * Parameters for the filter. + * @var array + */ + private $parameters; + + /** + * Constructs the SQLFilter object. + * + * @param EntityManager $em The EM + */ + final public function __construct(EntityManager $em) + { + $this->em = $em; + } + + /** + * Sets a parameter that can be used by the filter. + * + * @param string $name Name of the parameter. + * @param string $value Value of the parameter. + * @param string $type The parameter type. If specified, the given value will be run through + * the type conversion of this type. This is usually not needed for + * strings and numeric types. + * + * @return SQLFilter The current SQL filter. + */ + final public function setParameter($name, $value, $type = null) + { + if (null === $type) { + $type = ParameterTypeInferer::inferType($value); + } + + $this->parameters[$name] = array('value' => $value, 'type' => $type); + + // Keep the parameters sorted for the hash + ksort($this->parameters); + + // The filter collection of the EM is now dirty + $this->em->getFilters()->setFiltersStateDirty(); + + return $this; + } + + /** + * Gets a parameter to use in a query. + * + * The function is responsible for the right output escaping to use the + * value in a query. + * + * @param string $name Name of the parameter. + * + * @return string The SQL escaped parameter to use in a query. + */ + final public function getParameter($name) + { + if (!isset($this->parameters[$name])) { + throw new \InvalidArgumentException("Parameter '" . $name . "' does not exist."); + } + + return $this->em->getConnection()->quote($this->parameters[$name]['value'], $this->parameters[$name]['type']); + } + + /** + * Returns as string representation of the SQLFilter parameters (the state). + * + * @return string String representation of the SQLFilter. + */ + final public function __toString() + { + return serialize($this->parameters); + } + + /** + * Gets the SQL query part to add to a query. + * + * @return string The constraint SQL if there is available, empty string otherwise + */ + abstract public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias); +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/FilterCollection.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/FilterCollection.php new file mode 100644 index 0000000..35c8d04 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/FilterCollection.php @@ -0,0 +1,198 @@ +. + */ + +namespace Doctrine\ORM\Query; + +use Doctrine\ORM\Configuration, + Doctrine\ORM\EntityManager; + +/** + * Collection class for all the query filters. + * + * @author Alexander + */ +class FilterCollection +{ + /* Filter STATES */ + /** + * A filter object is in CLEAN state when it has no changed parameters. + */ + const FILTERS_STATE_CLEAN = 1; + + /** + * A filter object is in DIRTY state when it has changed parameters. + */ + const FILTERS_STATE_DIRTY = 2; + + /** + * The used Configuration. + * + * @var Doctrine\ORM\Configuration + */ + private $config; + + /** + * The EntityManager that "owns" this FilterCollection instance. + * + * @var Doctrine\ORM\EntityManager + */ + private $em; + + /** + * Instances of enabled filters. + * + * @var array + */ + private $enabledFilters = array(); + + /** + * @var string The filter hash from the last time the query was parsed. + */ + private $filterHash; + + /** + * @var integer $state The current state of this filter + */ + private $filtersState = self::FILTERS_STATE_CLEAN; + + /** + * Constructor. + * + * @param EntityManager $em + */ + public function __construct(EntityManager $em) + { + $this->em = $em; + $this->config = $em->getConfiguration(); + } + + /** + * Get all the enabled filters. + * + * @return array The enabled filters. + */ + public function getEnabledFilters() + { + return $this->enabledFilters; + } + + /** + * Enables a filter from the collection. + * + * @param string $name Name of the filter. + * + * @throws \InvalidArgumentException If the filter does not exist. + * + * @return SQLFilter The enabled filter. + */ + public function enable($name) + { + if (null === $filterClass = $this->config->getFilterClassName($name)) { + throw new \InvalidArgumentException("Filter '" . $name . "' does not exist."); + } + + if (!isset($this->enabledFilters[$name])) { + $this->enabledFilters[$name] = new $filterClass($this->em); + + // Keep the enabled filters sorted for the hash + ksort($this->enabledFilters); + + // Now the filter collection is dirty + $this->filtersState = self::FILTERS_STATE_DIRTY; + } + + return $this->enabledFilters[$name]; + } + + /** + * Disables a filter. + * + * @param string $name Name of the filter. + * + * @return SQLFilter The disabled filter. + * + * @throws \InvalidArgumentException If the filter does not exist. + */ + public function disable($name) + { + // Get the filter to return it + $filter = $this->getFilter($name); + + unset($this->enabledFilters[$name]); + + // Now the filter collection is dirty + $this->filtersState = self::FILTERS_STATE_DIRTY; + + return $filter; + } + + /** + * Get an enabled filter from the collection. + * + * @param string $name Name of the filter. + * + * @return SQLFilter The filter. + * + * @throws \InvalidArgumentException If the filter is not enabled. + */ + public function getFilter($name) + { + if (!isset($this->enabledFilters[$name])) { + throw new \InvalidArgumentException("Filter '" . $name . "' is not enabled."); + } + + return $this->enabledFilters[$name]; + } + + /** + * @return boolean True, if the filter collection is clean. + */ + public function isClean() + { + return self::FILTERS_STATE_CLEAN === $this->filtersState; + } + + /** + * Generates a string of currently enabled filters to use for the cache id. + * + * @return string + */ + public function getHash() + { + // If there are only clean filters, the previous hash can be returned + if (self::FILTERS_STATE_CLEAN === $this->filtersState) { + return $this->filterHash; + } + + $filterHash = ''; + foreach ($this->enabledFilters as $name => $filter) { + $filterHash .= $name . $filter; + } + + return $filterHash; + } + + /** + * Set the filter state to dirty. + */ + public function setFiltersStateDirty() + { + $this->filtersState = self::FILTERS_STATE_DIRTY; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Lexer.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Lexer.php new file mode 100644 index 0000000..1eef6af --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Lexer.php @@ -0,0 +1,208 @@ +. + */ + +namespace Doctrine\ORM\Query; + +/** + * Scans a DQL query for tokens. + * + * @author Guilherme Blanco + * @author Janne Vanhala + * @author Roman Borschel + * @since 2.0 + */ +class Lexer extends \Doctrine\Common\Lexer +{ + // All tokens that are not valid identifiers must be < 100 + const T_NONE = 1; + const T_INTEGER = 2; + const T_STRING = 3; + const T_INPUT_PARAMETER = 4; + const T_FLOAT = 5; + const T_CLOSE_PARENTHESIS = 6; + const T_OPEN_PARENTHESIS = 7; + const T_COMMA = 8; + const T_DIVIDE = 9; + const T_DOT = 10; + const T_EQUALS = 11; + const T_GREATER_THAN = 12; + const T_LOWER_THAN = 13; + const T_MINUS = 14; + const T_MULTIPLY = 15; + const T_NEGATE = 16; + const T_PLUS = 17; + const T_OPEN_CURLY_BRACE = 18; + const T_CLOSE_CURLY_BRACE = 19; + + // All tokens that are also identifiers should be >= 100 + const T_IDENTIFIER = 100; + const T_ALL = 101; + const T_AND = 102; + const T_ANY = 103; + const T_AS = 104; + const T_ASC = 105; + const T_AVG = 106; + const T_BETWEEN = 107; + const T_BOTH = 108; + const T_BY = 109; + const T_CASE = 110; + const T_COALESCE = 111; + const T_COUNT = 112; + const T_DELETE = 113; + const T_DESC = 114; + const T_DISTINCT = 115; + const T_ELSE = 116; + const T_EMPTY = 117; + const T_END = 118; + const T_ESCAPE = 119; + const T_EXISTS = 120; + const T_FALSE = 121; + const T_FROM = 122; + const T_GROUP = 123; + const T_HAVING = 124; + const T_HIDDEN = 125; + const T_IN = 126; + const T_INDEX = 127; + const T_INNER = 128; + const T_INSTANCE = 129; + const T_IS = 130; + const T_JOIN = 131; + const T_LEADING = 132; + const T_LEFT = 133; + const T_LIKE = 134; + const T_MAX = 135; + const T_MEMBER = 136; + const T_MIN = 137; + const T_NOT = 138; + const T_NULL = 139; + const T_NULLIF = 140; + const T_OF = 141; + const T_OR = 142; + const T_ORDER = 143; + const T_OUTER = 144; + const T_SELECT = 145; + const T_SET = 146; + const T_SIZE = 147; + const T_SOME = 148; + const T_SUM = 149; + const T_THEN = 150; + const T_TRAILING = 151; + const T_TRUE = 152; + const T_UPDATE = 153; + const T_WHEN = 154; + const T_WHERE = 155; + const T_WITH = 156; + const T_PARTIAL = 157; + const T_MOD = 158; + + /** + * Creates a new query scanner object. + * + * @param string $input a query string + */ + public function __construct($input) + { + $this->setInput($input); + } + + /** + * @inheritdoc + */ + protected function getCatchablePatterns() + { + return array( + '[a-z_\\\][a-z0-9_\:\\\]*[a-z0-9_]{1}', + '(?:[0-9]+(?:[\.][0-9]+)*)(?:e[+-]?[0-9]+)?', + "'(?:[^']|'')*'", + '\?[0-9]*|:[a-z]{1}[a-z0-9_]{0,}' + ); + } + + /** + * @inheritdoc + */ + protected function getNonCatchablePatterns() + { + return array('\s+', '(.)'); + } + + /** + * @inheritdoc + */ + protected function getType(&$value) + { + $type = self::T_NONE; + + switch (true) { + // Recognize numeric values + case (is_numeric($value)): + if (strpos($value, '.') !== false || stripos($value, 'e') !== false) { + return self::T_FLOAT; + } + + return self::T_INTEGER; + + // Recognize quoted strings + case ($value[0] === "'"): + $value = str_replace("''", "'", substr($value, 1, strlen($value) - 2)); + + return self::T_STRING; + + // Recognize identifiers + case (ctype_alpha($value[0]) || $value[0] === '_'): + $name = 'Doctrine\ORM\Query\Lexer::T_' . strtoupper($value); + + if (defined($name)) { + $type = constant($name); + + if ($type > 100) { + return $type; + } + } + + return self::T_IDENTIFIER; + + // Recognize input parameters + case ($value[0] === '?' || $value[0] === ':'): + return self::T_INPUT_PARAMETER; + + // Recognize symbols + case ($value === '.'): return self::T_DOT; + case ($value === ','): return self::T_COMMA; + case ($value === '('): return self::T_OPEN_PARENTHESIS; + case ($value === ')'): return self::T_CLOSE_PARENTHESIS; + case ($value === '='): return self::T_EQUALS; + case ($value === '>'): return self::T_GREATER_THAN; + case ($value === '<'): return self::T_LOWER_THAN; + case ($value === '+'): return self::T_PLUS; + case ($value === '-'): return self::T_MINUS; + case ($value === '*'): return self::T_MULTIPLY; + case ($value === '/'): return self::T_DIVIDE; + case ($value === '!'): return self::T_NEGATE; + case ($value === '{'): return self::T_OPEN_CURLY_BRACE; + case ($value === '}'): return self::T_CLOSE_CURLY_BRACE; + + // Default + default: + // Do nothing + } + + return $type; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/ParameterTypeInferer.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/ParameterTypeInferer.php new file mode 100644 index 0000000..39aef29 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/ParameterTypeInferer.php @@ -0,0 +1,72 @@ +. + */ + +namespace Doctrine\ORM\Query; + +use Doctrine\DBAL\Connection, + Doctrine\DBAL\Types\Type; + +/** + * Provides an enclosed support for parameter infering. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class ParameterTypeInferer +{ + /** + * Infer type of a given value, returning a compatible constant: + * - Type (\Doctrine\DBAL\Types\Type::*) + * - Connection (\Doctrine\DBAL\Connection::PARAM_*) + * + * @param mixed $value Parameter value + * + * @return mixed Parameter type constant + */ + public static function inferType($value) + { + switch (true) { + case is_integer($value): + return Type::INTEGER; + + case ($value instanceof \DateTime): + return Type::DATETIME; + + case is_array($value): + $key = key($value); + + if (is_integer($value[$key])) { + return Connection::PARAM_INT_ARRAY; + } + + return Connection::PARAM_STR_ARRAY; + + default: + // Do nothing + break; + } + + return \PDO::PARAM_STR; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php new file mode 100644 index 0000000..4200836 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php @@ -0,0 +1,3093 @@ +. + */ + +namespace Doctrine\ORM\Query; + +use Doctrine\ORM\Query; +use Doctrine\ORM\Mapping\ClassMetadata; + +/** + * An LL(*) recursive-descent parser for the context-free grammar of the Doctrine Query Language. + * Parses a DQL query, reports any errors in it, and generates an AST. + * + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Janne Vanhala + */ +class Parser +{ + /** READ-ONLY: Maps BUILT-IN string function names to AST class names. */ + private static $_STRING_FUNCTIONS = array( + 'concat' => 'Doctrine\ORM\Query\AST\Functions\ConcatFunction', + 'substring' => 'Doctrine\ORM\Query\AST\Functions\SubstringFunction', + 'trim' => 'Doctrine\ORM\Query\AST\Functions\TrimFunction', + 'lower' => 'Doctrine\ORM\Query\AST\Functions\LowerFunction', + 'upper' => 'Doctrine\ORM\Query\AST\Functions\UpperFunction', + 'identity' => 'Doctrine\ORM\Query\AST\Functions\IdentityFunction', + ); + + /** READ-ONLY: Maps BUILT-IN numeric function names to AST class names. */ + private static $_NUMERIC_FUNCTIONS = array( + 'length' => 'Doctrine\ORM\Query\AST\Functions\LengthFunction', + 'locate' => 'Doctrine\ORM\Query\AST\Functions\LocateFunction', + 'abs' => 'Doctrine\ORM\Query\AST\Functions\AbsFunction', + 'sqrt' => 'Doctrine\ORM\Query\AST\Functions\SqrtFunction', + 'mod' => 'Doctrine\ORM\Query\AST\Functions\ModFunction', + 'size' => 'Doctrine\ORM\Query\AST\Functions\SizeFunction', + 'date_diff' => 'Doctrine\ORM\Query\AST\Functions\DateDiffFunction', + 'bit_and' => 'Doctrine\ORM\Query\AST\Functions\BitAndFunction', + 'bit_or' => 'Doctrine\ORM\Query\AST\Functions\BitOrFunction', + ); + + /** READ-ONLY: Maps BUILT-IN datetime function names to AST class names. */ + private static $_DATETIME_FUNCTIONS = array( + 'current_date' => 'Doctrine\ORM\Query\AST\Functions\CurrentDateFunction', + 'current_time' => 'Doctrine\ORM\Query\AST\Functions\CurrentTimeFunction', + 'current_timestamp' => 'Doctrine\ORM\Query\AST\Functions\CurrentTimestampFunction', + 'date_add' => 'Doctrine\ORM\Query\AST\Functions\DateAddFunction', + 'date_sub' => 'Doctrine\ORM\Query\AST\Functions\DateSubFunction', + ); + + /** + * Expressions that were encountered during parsing of identifiers and expressions + * and still need to be validated. + */ + private $_deferredIdentificationVariables = array(); + private $_deferredPartialObjectExpressions = array(); + private $_deferredPathExpressions = array(); + private $_deferredResultVariables = array(); + + /** + * The lexer. + * + * @var \Doctrine\ORM\Query\Lexer + */ + private $_lexer; + + /** + * The parser result. + * + * @var \Doctrine\ORM\Query\ParserResult + */ + private $_parserResult; + + /** + * The EntityManager. + * + * @var EnityManager + */ + private $_em; + + /** + * The Query to parse. + * + * @var Query + */ + private $_query; + + /** + * Map of declared query components in the parsed query. + * + * @var array + */ + private $_queryComponents = array(); + + /** + * Keeps the nesting level of defined ResultVariables + * + * @var integer + */ + private $_nestingLevel = 0; + + /** + * Any additional custom tree walkers that modify the AST. + * + * @var array + */ + private $_customTreeWalkers = array(); + + /** + * The custom last tree walker, if any, that is responsible for producing the output. + * + * @var TreeWalker + */ + private $_customOutputWalker; + + /** + * @var array + */ + private $_identVariableExpressions = array(); + + /** + * Creates a new query parser object. + * + * @param Query $query The Query to parse. + */ + public function __construct(Query $query) + { + $this->_query = $query; + $this->_em = $query->getEntityManager(); + $this->_lexer = new Lexer($query->getDql()); + $this->_parserResult = new ParserResult(); + } + + /** + * Sets a custom tree walker that produces output. + * This tree walker will be run last over the AST, after any other walkers. + * + * @param string $className + */ + public function setCustomOutputTreeWalker($className) + { + $this->_customOutputWalker = $className; + } + + /** + * Adds a custom tree walker for modifying the AST. + * + * @param string $className + */ + public function addCustomTreeWalker($className) + { + $this->_customTreeWalkers[] = $className; + } + + /** + * Gets the lexer used by the parser. + * + * @return \Doctrine\ORM\Query\Lexer + */ + public function getLexer() + { + return $this->_lexer; + } + + /** + * Gets the ParserResult that is being filled with information during parsing. + * + * @return \Doctrine\ORM\Query\ParserResult + */ + public function getParserResult() + { + return $this->_parserResult; + } + + /** + * Gets the EntityManager used by the parser. + * + * @return EntityManager + */ + public function getEntityManager() + { + return $this->_em; + } + + /** + * Parse and build AST for the given Query. + * + * @return \Doctrine\ORM\Query\AST\SelectStatement | + * \Doctrine\ORM\Query\AST\UpdateStatement | + * \Doctrine\ORM\Query\AST\DeleteStatement + */ + public function getAST() + { + // Parse & build AST + $AST = $this->QueryLanguage(); + + // Process any deferred validations of some nodes in the AST. + // This also allows post-processing of the AST for modification purposes. + $this->_processDeferredIdentificationVariables(); + + if ($this->_deferredPartialObjectExpressions) { + $this->_processDeferredPartialObjectExpressions(); + } + + if ($this->_deferredPathExpressions) { + $this->_processDeferredPathExpressions($AST); + } + + if ($this->_deferredResultVariables) { + $this->_processDeferredResultVariables(); + } + + $this->_processRootEntityAliasSelected(); + + // TODO: Is there a way to remove this? It may impact the mixed hydration resultset a lot! + $this->fixIdentificationVariableOrder($AST); + + return $AST; + } + + /** + * Attempts to match the given token with the current lookahead token. + * + * If they match, updates the lookahead token; otherwise raises a syntax + * error. + * + * @param int token type + * @return void + * @throws QueryException If the tokens dont match. + */ + public function match($token) + { + $lookaheadType = $this->_lexer->lookahead['type']; + + // short-circuit on first condition, usually types match + if ($lookaheadType !== $token && $token !== Lexer::T_IDENTIFIER && $lookaheadType <= Lexer::T_IDENTIFIER) { + $this->syntaxError($this->_lexer->getLiteral($token)); + } + + $this->_lexer->moveNext(); + } + + /** + * Free this parser enabling it to be reused + * + * @param boolean $deep Whether to clean peek and reset errors + * @param integer $position Position to reset + */ + public function free($deep = false, $position = 0) + { + // WARNING! Use this method with care. It resets the scanner! + $this->_lexer->resetPosition($position); + + // Deep = true cleans peek and also any previously defined errors + if ($deep) { + $this->_lexer->resetPeek(); + } + + $this->_lexer->token = null; + $this->_lexer->lookahead = null; + } + + /** + * Parses a query string. + * + * @return ParserResult + */ + public function parse() + { + $AST = $this->getAST(); + + if (($customWalkers = $this->_query->getHint(Query::HINT_CUSTOM_TREE_WALKERS)) !== false) { + $this->_customTreeWalkers = $customWalkers; + } + + if (($customOutputWalker = $this->_query->getHint(Query::HINT_CUSTOM_OUTPUT_WALKER)) !== false) { + $this->_customOutputWalker = $customOutputWalker; + } + + // Run any custom tree walkers over the AST + if ($this->_customTreeWalkers) { + $treeWalkerChain = new TreeWalkerChain($this->_query, $this->_parserResult, $this->_queryComponents); + + foreach ($this->_customTreeWalkers as $walker) { + $treeWalkerChain->addTreeWalker($walker); + } + + switch (true) { + case ($AST instanceof AST\UpdateStatement): + $treeWalkerChain->walkUpdateStatement($AST); + break; + + case ($AST instanceof AST\DeleteStatement): + $treeWalkerChain->walkDeleteStatement($AST); + break; + + case ($AST instanceof AST\SelectStatement): + default: + $treeWalkerChain->walkSelectStatement($AST); + } + } + + $outputWalkerClass = $this->_customOutputWalker ?: __NAMESPACE__ . '\SqlWalker'; + $outputWalker = new $outputWalkerClass($this->_query, $this->_parserResult, $this->_queryComponents); + + // Assign an SQL executor to the parser result + $this->_parserResult->setSqlExecutor($outputWalker->getExecutor($AST)); + + return $this->_parserResult; + } + + /** + * Fix order of identification variables. + * + * They have to appear in the select clause in the same order as the + * declarations (from ... x join ... y join ... z ...) appear in the query + * as the hydration process relies on that order for proper operation. + * + * @param AST\SelectStatement|AST\DeleteStatement|AST\UpdateStatement $AST + * @return void + */ + private function fixIdentificationVariableOrder($AST) + { + if (count($this->_identVariableExpressions) <= 1) { + return; + } + + foreach ($this->_queryComponents as $dqlAlias => $qComp) { + if ( ! isset($this->_identVariableExpressions[$dqlAlias])) { + continue; + } + + $expr = $this->_identVariableExpressions[$dqlAlias]; + $key = array_search($expr, $AST->selectClause->selectExpressions); + + unset($AST->selectClause->selectExpressions[$key]); + + $AST->selectClause->selectExpressions[] = $expr; + } + } + + /** + * Generates a new syntax error. + * + * @param string $expected Expected string. + * @param array $token Got token. + * + * @throws \Doctrine\ORM\Query\QueryException + */ + public function syntaxError($expected = '', $token = null) + { + if ($token === null) { + $token = $this->_lexer->lookahead; + } + + $tokenPos = (isset($token['position'])) ? $token['position'] : '-1'; + + $message = "line 0, col {$tokenPos}: Error: "; + $message .= ($expected !== '') ? "Expected {$expected}, got " : 'Unexpected '; + $message .= ($this->_lexer->lookahead === null) ? 'end of string.' : "'{$token['value']}'"; + + throw QueryException::syntaxError($message); + } + + /** + * Generates a new semantical error. + * + * @param string $message Optional message. + * @param array $token Optional token. + * + * @throws \Doctrine\ORM\Query\QueryException + */ + public function semanticalError($message = '', $token = null) + { + if ($token === null) { + $token = $this->_lexer->lookahead; + } + + // Minimum exposed chars ahead of token + $distance = 12; + + // Find a position of a final word to display in error string + $dql = $this->_query->getDql(); + $length = strlen($dql); + $pos = $token['position'] + $distance; + $pos = strpos($dql, ' ', ($length > $pos) ? $pos : $length); + $length = ($pos !== false) ? $pos - $token['position'] : $distance; + + $tokenPos = (isset($token['position']) && $token['position'] > 0) ? $token['position'] : '-1'; + $tokenStr = substr($dql, $token['position'], $length); + + // Building informative message + $message = 'line 0, col ' . $tokenPos . " near '" . $tokenStr . "': Error: " . $message; + + throw QueryException::semanticalError($message); + } + + /** + * Peeks beyond the specified token and returns the first token after that one. + * + * @param array $token + * @return array + */ + private function _peekBeyond($token) + { + $peek = $this->_lexer->peek(); + + while ($peek['value'] != $token) { + $peek = $this->_lexer->peek(); + } + + $peek = $this->_lexer->peek(); + $this->_lexer->resetPeek(); + + return $peek; + } + + /** + * Peek beyond the matched closing parenthesis and return the first token after that one. + * + * @return array + */ + private function _peekBeyondClosingParenthesis() + { + $token = $this->_lexer->peek(); + $numUnmatched = 1; + + while ($numUnmatched > 0 && $token !== null) { + switch ($token['type']) { + case Lexer::T_OPEN_PARENTHESIS: + ++$numUnmatched; + break; + + case Lexer::T_CLOSE_PARENTHESIS: + --$numUnmatched; + break; + + default: + // Do nothing + } + + $token = $this->_lexer->peek(); + } + + $this->_lexer->resetPeek(); + + return $token; + } + + /** + * Checks if the given token indicates a mathematical operator. + * + * @return boolean TRUE if the token is a mathematical operator, FALSE otherwise. + */ + private function _isMathOperator($token) + { + return in_array($token['type'], array(Lexer::T_PLUS, Lexer::T_MINUS, Lexer::T_DIVIDE, Lexer::T_MULTIPLY)); + } + + /** + * Checks if the next-next (after lookahead) token starts a function. + * + * @return boolean TRUE if the next-next tokens start a function, FALSE otherwise. + */ + private function _isFunction() + { + $peek = $this->_lexer->peek(); + $nextpeek = $this->_lexer->peek(); + + $this->_lexer->resetPeek(); + + // We deny the COUNT(SELECT * FROM User u) here. COUNT won't be considered a function + return ($peek['type'] === Lexer::T_OPEN_PARENTHESIS && $nextpeek['type'] !== Lexer::T_SELECT); + } + + /** + * Checks whether the given token type indicates an aggregate function. + * + * @return boolean TRUE if the token type is an aggregate function, FALSE otherwise. + */ + private function _isAggregateFunction($tokenType) + { + return in_array($tokenType, array(Lexer::T_AVG, Lexer::T_MIN, Lexer::T_MAX, Lexer::T_SUM, Lexer::T_COUNT)); + } + + /** + * Checks whether the current lookahead token of the lexer has the type T_ALL, T_ANY or T_SOME. + * + * @return boolean + */ + private function _isNextAllAnySome() + { + return in_array($this->_lexer->lookahead['type'], array(Lexer::T_ALL, Lexer::T_ANY, Lexer::T_SOME)); + } + + /** + * Validates that the given IdentificationVariable is semantically correct. + * It must exist in query components list. + * + * @return void + */ + private function _processDeferredIdentificationVariables() + { + foreach ($this->_deferredIdentificationVariables as $deferredItem) { + $identVariable = $deferredItem['expression']; + + // Check if IdentificationVariable exists in queryComponents + if ( ! isset($this->_queryComponents[$identVariable])) { + $this->semanticalError( + "'$identVariable' is not defined.", $deferredItem['token'] + ); + } + + $qComp = $this->_queryComponents[$identVariable]; + + // Check if queryComponent points to an AbstractSchemaName or a ResultVariable + if ( ! isset($qComp['metadata'])) { + $this->semanticalError( + "'$identVariable' does not point to a Class.", $deferredItem['token'] + ); + } + + // Validate if identification variable nesting level is lower or equal than the current one + if ($qComp['nestingLevel'] > $deferredItem['nestingLevel']) { + $this->semanticalError( + "'$identVariable' is used outside the scope of its declaration.", $deferredItem['token'] + ); + } + } + } + + /** + * Validates that the given PartialObjectExpression is semantically correct. + * It must exist in query components list. + * + * @return void + */ + private function _processDeferredPartialObjectExpressions() + { + foreach ($this->_deferredPartialObjectExpressions as $deferredItem) { + $expr = $deferredItem['expression']; + $class = $this->_queryComponents[$expr->identificationVariable]['metadata']; + + foreach ($expr->partialFieldSet as $field) { + if (isset($class->fieldMappings[$field])) { + continue; + } + + $this->semanticalError( + "There is no mapped field named '$field' on class " . $class->name . ".", $deferredItem['token'] + ); + } + + if (array_intersect($class->identifier, $expr->partialFieldSet) != $class->identifier) { + $this->semanticalError( + "The partial field selection of class " . $class->name . " must contain the identifier.", + $deferredItem['token'] + ); + } + } + } + + /** + * Validates that the given ResultVariable is semantically correct. + * It must exist in query components list. + * + * @return void + */ + private function _processDeferredResultVariables() + { + foreach ($this->_deferredResultVariables as $deferredItem) { + $resultVariable = $deferredItem['expression']; + + // Check if ResultVariable exists in queryComponents + if ( ! isset($this->_queryComponents[$resultVariable])) { + $this->semanticalError( + "'$resultVariable' is not defined.", $deferredItem['token'] + ); + } + + $qComp = $this->_queryComponents[$resultVariable]; + + // Check if queryComponent points to an AbstractSchemaName or a ResultVariable + if ( ! isset($qComp['resultVariable'])) { + $this->semanticalError( + "'$identVariable' does not point to a ResultVariable.", $deferredItem['token'] + ); + } + + // Validate if identification variable nesting level is lower or equal than the current one + if ($qComp['nestingLevel'] > $deferredItem['nestingLevel']) { + $this->semanticalError( + "'$resultVariable' is used outside the scope of its declaration.", $deferredItem['token'] + ); + } + } + } + + /** + * Validates that the given PathExpression is semantically correct for grammar rules: + * + * AssociationPathExpression ::= CollectionValuedPathExpression | SingleValuedAssociationPathExpression + * SingleValuedPathExpression ::= StateFieldPathExpression | SingleValuedAssociationPathExpression + * StateFieldPathExpression ::= IdentificationVariable "." StateField + * SingleValuedAssociationPathExpression ::= IdentificationVariable "." SingleValuedAssociationField + * CollectionValuedPathExpression ::= IdentificationVariable "." CollectionValuedAssociationField + * + * @param array $deferredItem + * @param mixed $AST + */ + private function _processDeferredPathExpressions($AST) + { + foreach ($this->_deferredPathExpressions as $deferredItem) { + $pathExpression = $deferredItem['expression']; + + $qComp = $this->_queryComponents[$pathExpression->identificationVariable]; + $class = $qComp['metadata']; + + if (($field = $pathExpression->field) === null) { + $field = $pathExpression->field = $class->identifier[0]; + } + + // Check if field or association exists + if ( ! isset($class->associationMappings[$field]) && ! isset($class->fieldMappings[$field])) { + $this->semanticalError( + 'Class ' . $class->name . ' has no field or association named ' . $field, + $deferredItem['token'] + ); + } + + $fieldType = AST\PathExpression::TYPE_STATE_FIELD; + + if (isset($class->associationMappings[$field])) { + $assoc = $class->associationMappings[$field]; + + $fieldType = ($assoc['type'] & ClassMetadata::TO_ONE) + ? AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION + : AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION; + } + + // Validate if PathExpression is one of the expected types + $expectedType = $pathExpression->expectedType; + + if ( ! ($expectedType & $fieldType)) { + // We need to recognize which was expected type(s) + $expectedStringTypes = array(); + + // Validate state field type + if ($expectedType & AST\PathExpression::TYPE_STATE_FIELD) { + $expectedStringTypes[] = 'StateFieldPathExpression'; + } + + // Validate single valued association (*-to-one) + if ($expectedType & AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION) { + $expectedStringTypes[] = 'SingleValuedAssociationField'; + } + + // Validate single valued association (*-to-many) + if ($expectedType & AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION) { + $expectedStringTypes[] = 'CollectionValuedAssociationField'; + } + + // Build the error message + $semanticalError = 'Invalid PathExpression. '; + $semanticalError .= (count($expectedStringTypes) == 1) + ? 'Must be a ' . $expectedStringTypes[0] . '.' + : implode(' or ', $expectedStringTypes) . ' expected.'; + + $this->semanticalError($semanticalError, $deferredItem['token']); + } + + // We need to force the type in PathExpression + $pathExpression->type = $fieldType; + } + } + + private function _processRootEntityAliasSelected() + { + if ( ! count($this->_identVariableExpressions)) { + return; + } + + $foundRootEntity = false; + + foreach ($this->_identVariableExpressions AS $dqlAlias => $expr) { + if (isset($this->_queryComponents[$dqlAlias]) && $this->_queryComponents[$dqlAlias]['parent'] === null) { + $foundRootEntity = true; + } + } + + if ( ! $foundRootEntity) { + $this->semanticalError('Cannot select entity through identification variables without choosing at least one root entity alias.'); + } + } + + /** + * QueryLanguage ::= SelectStatement | UpdateStatement | DeleteStatement + * + * @return \Doctrine\ORM\Query\AST\SelectStatement | + * \Doctrine\ORM\Query\AST\UpdateStatement | + * \Doctrine\ORM\Query\AST\DeleteStatement + */ + public function QueryLanguage() + { + $this->_lexer->moveNext(); + + switch ($this->_lexer->lookahead['type']) { + case Lexer::T_SELECT: + $statement = $this->SelectStatement(); + break; + + case Lexer::T_UPDATE: + $statement = $this->UpdateStatement(); + break; + + case Lexer::T_DELETE: + $statement = $this->DeleteStatement(); + break; + + default: + $this->syntaxError('SELECT, UPDATE or DELETE'); + break; + } + + // Check for end of string + if ($this->_lexer->lookahead !== null) { + $this->syntaxError('end of string'); + } + + return $statement; + } + + /** + * SelectStatement ::= SelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] + * + * @return \Doctrine\ORM\Query\AST\SelectStatement + */ + public function SelectStatement() + { + $selectStatement = new AST\SelectStatement($this->SelectClause(), $this->FromClause()); + + $selectStatement->whereClause = $this->_lexer->isNextToken(Lexer::T_WHERE) ? $this->WhereClause() : null; + $selectStatement->groupByClause = $this->_lexer->isNextToken(Lexer::T_GROUP) ? $this->GroupByClause() : null; + $selectStatement->havingClause = $this->_lexer->isNextToken(Lexer::T_HAVING) ? $this->HavingClause() : null; + $selectStatement->orderByClause = $this->_lexer->isNextToken(Lexer::T_ORDER) ? $this->OrderByClause() : null; + + return $selectStatement; + } + + /** + * UpdateStatement ::= UpdateClause [WhereClause] + * + * @return \Doctrine\ORM\Query\AST\UpdateStatement + */ + public function UpdateStatement() + { + $updateStatement = new AST\UpdateStatement($this->UpdateClause()); + + $updateStatement->whereClause = $this->_lexer->isNextToken(Lexer::T_WHERE) ? $this->WhereClause() : null; + + return $updateStatement; + } + + /** + * DeleteStatement ::= DeleteClause [WhereClause] + * + * @return \Doctrine\ORM\Query\AST\DeleteStatement + */ + public function DeleteStatement() + { + $deleteStatement = new AST\DeleteStatement($this->DeleteClause()); + + $deleteStatement->whereClause = $this->_lexer->isNextToken(Lexer::T_WHERE) ? $this->WhereClause() : null; + + return $deleteStatement; + } + + /** + * IdentificationVariable ::= identifier + * + * @return string + */ + public function IdentificationVariable() + { + $this->match(Lexer::T_IDENTIFIER); + + $identVariable = $this->_lexer->token['value']; + + $this->_deferredIdentificationVariables[] = array( + 'expression' => $identVariable, + 'nestingLevel' => $this->_nestingLevel, + 'token' => $this->_lexer->token, + ); + + return $identVariable; + } + + /** + * AliasIdentificationVariable = identifier + * + * @return string + */ + public function AliasIdentificationVariable() + { + $this->match(Lexer::T_IDENTIFIER); + + $aliasIdentVariable = $this->_lexer->token['value']; + $exists = isset($this->_queryComponents[$aliasIdentVariable]); + + if ($exists) { + $this->semanticalError("'$aliasIdentVariable' is already defined.", $this->_lexer->token); + } + + return $aliasIdentVariable; + } + + /** + * AbstractSchemaName ::= identifier + * + * @return string + */ + public function AbstractSchemaName() + { + $this->match(Lexer::T_IDENTIFIER); + + $schemaName = ltrim($this->_lexer->token['value'], '\\'); + + if (strrpos($schemaName, ':') !== false) { + list($namespaceAlias, $simpleClassName) = explode(':', $schemaName); + + $schemaName = $this->_em->getConfiguration()->getEntityNamespace($namespaceAlias) . '\\' . $simpleClassName; + } + + $exists = class_exists($schemaName, true); + + if ( ! $exists) { + $this->semanticalError("Class '$schemaName' is not defined.", $this->_lexer->token); + } + + return $schemaName; + } + + /** + * AliasResultVariable ::= identifier + * + * @return string + */ + public function AliasResultVariable() + { + $this->match(Lexer::T_IDENTIFIER); + + $resultVariable = $this->_lexer->token['value']; + $exists = isset($this->_queryComponents[$resultVariable]); + + if ($exists) { + $this->semanticalError("'$resultVariable' is already defined.", $this->_lexer->token); + } + + return $resultVariable; + } + + /** + * ResultVariable ::= identifier + * + * @return string + */ + public function ResultVariable() + { + $this->match(Lexer::T_IDENTIFIER); + + $resultVariable = $this->_lexer->token['value']; + + // Defer ResultVariable validation + $this->_deferredResultVariables[] = array( + 'expression' => $resultVariable, + 'nestingLevel' => $this->_nestingLevel, + 'token' => $this->_lexer->token, + ); + + return $resultVariable; + } + + /** + * JoinAssociationPathExpression ::= IdentificationVariable "." (CollectionValuedAssociationField | SingleValuedAssociationField) + * + * @return \Doctrine\ORM\Query\AST\JoinAssociationPathExpression + */ + public function JoinAssociationPathExpression() + { + $token = $this->_lexer->lookahead; + $identVariable = $this->IdentificationVariable(); + + if ( ! isset($this->_queryComponents[$identVariable])) { + $this->semanticalError( + 'Identification Variable ' . $identVariable .' used in join path expression but was not defined before.' + ); + } + + $this->match(Lexer::T_DOT); + $this->match(Lexer::T_IDENTIFIER); + + $field = $this->_lexer->token['value']; + + // Validate association field + $qComp = $this->_queryComponents[$identVariable]; + $class = $qComp['metadata']; + + if ( ! isset($class->associationMappings[$field])) { + $this->semanticalError('Class ' . $class->name . ' has no association named ' . $field); + } + + return new AST\JoinAssociationPathExpression($identVariable, $field); + } + + /** + * Parses an arbitrary path expression and defers semantical validation + * based on expected types. + * + * PathExpression ::= IdentificationVariable "." identifier + * + * @param integer $expectedTypes + * @return \Doctrine\ORM\Query\AST\PathExpression + */ + public function PathExpression($expectedTypes) + { + $token = $this->_lexer->lookahead; + $identVariable = $this->IdentificationVariable(); + $field = null; + + if ($this->_lexer->isNextToken(Lexer::T_DOT)) { + $this->match(Lexer::T_DOT); + $this->match(Lexer::T_IDENTIFIER); + + $field = $this->_lexer->token['value']; + } + + // Creating AST node + $pathExpr = new AST\PathExpression($expectedTypes, $identVariable, $field); + + // Defer PathExpression validation if requested to be defered + $this->_deferredPathExpressions[] = array( + 'expression' => $pathExpr, + 'nestingLevel' => $this->_nestingLevel, + 'token' => $this->_lexer->token, + ); + + return $pathExpr; + } + + /** + * AssociationPathExpression ::= CollectionValuedPathExpression | SingleValuedAssociationPathExpression + * + * @return \Doctrine\ORM\Query\AST\PathExpression + */ + public function AssociationPathExpression() + { + return $this->PathExpression( + AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION | + AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION + ); + } + + /** + * SingleValuedPathExpression ::= StateFieldPathExpression | SingleValuedAssociationPathExpression + * + * @return \Doctrine\ORM\Query\AST\PathExpression + */ + public function SingleValuedPathExpression() + { + return $this->PathExpression( + AST\PathExpression::TYPE_STATE_FIELD | + AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION + ); + } + + /** + * StateFieldPathExpression ::= IdentificationVariable "." StateField + * + * @return \Doctrine\ORM\Query\AST\PathExpression + */ + public function StateFieldPathExpression() + { + return $this->PathExpression(AST\PathExpression::TYPE_STATE_FIELD); + } + + /** + * SingleValuedAssociationPathExpression ::= IdentificationVariable "." SingleValuedAssociationField + * + * @return \Doctrine\ORM\Query\AST\PathExpression + */ + public function SingleValuedAssociationPathExpression() + { + return $this->PathExpression(AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION); + } + + /** + * CollectionValuedPathExpression ::= IdentificationVariable "." CollectionValuedAssociationField + * + * @return \Doctrine\ORM\Query\AST\PathExpression + */ + public function CollectionValuedPathExpression() + { + return $this->PathExpression(AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION); + } + + /** + * SelectClause ::= "SELECT" ["DISTINCT"] SelectExpression {"," SelectExpression} + * + * @return \Doctrine\ORM\Query\AST\SelectClause + */ + public function SelectClause() + { + $isDistinct = false; + $this->match(Lexer::T_SELECT); + + // Check for DISTINCT + if ($this->_lexer->isNextToken(Lexer::T_DISTINCT)) { + $this->match(Lexer::T_DISTINCT); + + $isDistinct = true; + } + + // Process SelectExpressions (1..N) + $selectExpressions = array(); + $selectExpressions[] = $this->SelectExpression(); + + while ($this->_lexer->isNextToken(Lexer::T_COMMA)) { + $this->match(Lexer::T_COMMA); + + $selectExpressions[] = $this->SelectExpression(); + } + + return new AST\SelectClause($selectExpressions, $isDistinct); + } + + /** + * SimpleSelectClause ::= "SELECT" ["DISTINCT"] SimpleSelectExpression + * + * @return \Doctrine\ORM\Query\AST\SimpleSelectClause + */ + public function SimpleSelectClause() + { + $isDistinct = false; + $this->match(Lexer::T_SELECT); + + if ($this->_lexer->isNextToken(Lexer::T_DISTINCT)) { + $this->match(Lexer::T_DISTINCT); + + $isDistinct = true; + } + + return new AST\SimpleSelectClause($this->SimpleSelectExpression(), $isDistinct); + } + + /** + * UpdateClause ::= "UPDATE" AbstractSchemaName ["AS"] AliasIdentificationVariable "SET" UpdateItem {"," UpdateItem}* + * + * @return \Doctrine\ORM\Query\AST\UpdateClause + */ + public function UpdateClause() + { + $this->match(Lexer::T_UPDATE); + $token = $this->_lexer->lookahead; + $abstractSchemaName = $this->AbstractSchemaName(); + + if ($this->_lexer->isNextToken(Lexer::T_AS)) { + $this->match(Lexer::T_AS); + } + + $aliasIdentificationVariable = $this->AliasIdentificationVariable(); + + $class = $this->_em->getClassMetadata($abstractSchemaName); + + // Building queryComponent + $queryComponent = array( + 'metadata' => $class, + 'parent' => null, + 'relation' => null, + 'map' => null, + 'nestingLevel' => $this->_nestingLevel, + 'token' => $token, + ); + + $this->_queryComponents[$aliasIdentificationVariable] = $queryComponent; + + $this->match(Lexer::T_SET); + + $updateItems = array(); + $updateItems[] = $this->UpdateItem(); + + while ($this->_lexer->isNextToken(Lexer::T_COMMA)) { + $this->match(Lexer::T_COMMA); + + $updateItems[] = $this->UpdateItem(); + } + + $updateClause = new AST\UpdateClause($abstractSchemaName, $updateItems); + $updateClause->aliasIdentificationVariable = $aliasIdentificationVariable; + + return $updateClause; + } + + /** + * DeleteClause ::= "DELETE" ["FROM"] AbstractSchemaName ["AS"] AliasIdentificationVariable + * + * @return \Doctrine\ORM\Query\AST\DeleteClause + */ + public function DeleteClause() + { + $this->match(Lexer::T_DELETE); + + if ($this->_lexer->isNextToken(Lexer::T_FROM)) { + $this->match(Lexer::T_FROM); + } + + $token = $this->_lexer->lookahead; + $deleteClause = new AST\DeleteClause($this->AbstractSchemaName()); + + if ($this->_lexer->isNextToken(Lexer::T_AS)) { + $this->match(Lexer::T_AS); + } + + $aliasIdentificationVariable = $this->AliasIdentificationVariable(); + + $deleteClause->aliasIdentificationVariable = $aliasIdentificationVariable; + $class = $this->_em->getClassMetadata($deleteClause->abstractSchemaName); + + // Building queryComponent + $queryComponent = array( + 'metadata' => $class, + 'parent' => null, + 'relation' => null, + 'map' => null, + 'nestingLevel' => $this->_nestingLevel, + 'token' => $token, + ); + + $this->_queryComponents[$aliasIdentificationVariable] = $queryComponent; + + return $deleteClause; + } + + /** + * FromClause ::= "FROM" IdentificationVariableDeclaration {"," IdentificationVariableDeclaration}* + * + * @return \Doctrine\ORM\Query\AST\FromClause + */ + public function FromClause() + { + $this->match(Lexer::T_FROM); + + $identificationVariableDeclarations = array(); + $identificationVariableDeclarations[] = $this->IdentificationVariableDeclaration(); + + while ($this->_lexer->isNextToken(Lexer::T_COMMA)) { + $this->match(Lexer::T_COMMA); + + $identificationVariableDeclarations[] = $this->IdentificationVariableDeclaration(); + } + + return new AST\FromClause($identificationVariableDeclarations); + } + + /** + * SubselectFromClause ::= "FROM" SubselectIdentificationVariableDeclaration {"," SubselectIdentificationVariableDeclaration}* + * + * @return \Doctrine\ORM\Query\AST\SubselectFromClause + */ + public function SubselectFromClause() + { + $this->match(Lexer::T_FROM); + + $identificationVariables = array(); + $identificationVariables[] = $this->SubselectIdentificationVariableDeclaration(); + + while ($this->_lexer->isNextToken(Lexer::T_COMMA)) { + $this->match(Lexer::T_COMMA); + + $identificationVariables[] = $this->SubselectIdentificationVariableDeclaration(); + } + + return new AST\SubselectFromClause($identificationVariables); + } + + /** + * WhereClause ::= "WHERE" ConditionalExpression + * + * @return \Doctrine\ORM\Query\AST\WhereClause + */ + public function WhereClause() + { + $this->match(Lexer::T_WHERE); + + return new AST\WhereClause($this->ConditionalExpression()); + } + + /** + * HavingClause ::= "HAVING" ConditionalExpression + * + * @return \Doctrine\ORM\Query\AST\HavingClause + */ + public function HavingClause() + { + $this->match(Lexer::T_HAVING); + + return new AST\HavingClause($this->ConditionalExpression()); + } + + /** + * GroupByClause ::= "GROUP" "BY" GroupByItem {"," GroupByItem}* + * + * @return \Doctrine\ORM\Query\AST\GroupByClause + */ + public function GroupByClause() + { + $this->match(Lexer::T_GROUP); + $this->match(Lexer::T_BY); + + $groupByItems = array($this->GroupByItem()); + + while ($this->_lexer->isNextToken(Lexer::T_COMMA)) { + $this->match(Lexer::T_COMMA); + + $groupByItems[] = $this->GroupByItem(); + } + + return new AST\GroupByClause($groupByItems); + } + + /** + * OrderByClause ::= "ORDER" "BY" OrderByItem {"," OrderByItem}* + * + * @return \Doctrine\ORM\Query\AST\OrderByClause + */ + public function OrderByClause() + { + $this->match(Lexer::T_ORDER); + $this->match(Lexer::T_BY); + + $orderByItems = array(); + $orderByItems[] = $this->OrderByItem(); + + while ($this->_lexer->isNextToken(Lexer::T_COMMA)) { + $this->match(Lexer::T_COMMA); + + $orderByItems[] = $this->OrderByItem(); + } + + return new AST\OrderByClause($orderByItems); + } + + /** + * Subselect ::= SimpleSelectClause SubselectFromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] + * + * @return \Doctrine\ORM\Query\AST\Subselect + */ + public function Subselect() + { + // Increase query nesting level + $this->_nestingLevel++; + + $subselect = new AST\Subselect($this->SimpleSelectClause(), $this->SubselectFromClause()); + + $subselect->whereClause = $this->_lexer->isNextToken(Lexer::T_WHERE) ? $this->WhereClause() : null; + $subselect->groupByClause = $this->_lexer->isNextToken(Lexer::T_GROUP) ? $this->GroupByClause() : null; + $subselect->havingClause = $this->_lexer->isNextToken(Lexer::T_HAVING) ? $this->HavingClause() : null; + $subselect->orderByClause = $this->_lexer->isNextToken(Lexer::T_ORDER) ? $this->OrderByClause() : null; + + // Decrease query nesting level + $this->_nestingLevel--; + + return $subselect; + } + + /** + * UpdateItem ::= SingleValuedPathExpression "=" NewValue + * + * @return \Doctrine\ORM\Query\AST\UpdateItem + */ + public function UpdateItem() + { + $pathExpr = $this->SingleValuedPathExpression(); + + $this->match(Lexer::T_EQUALS); + + $updateItem = new AST\UpdateItem($pathExpr, $this->NewValue()); + + return $updateItem; + } + + /** + * GroupByItem ::= IdentificationVariable | ResultVariable | SingleValuedPathExpression + * + * @return string | \Doctrine\ORM\Query\AST\PathExpression + */ + public function GroupByItem() + { + // We need to check if we are in a IdentificationVariable or SingleValuedPathExpression + $glimpse = $this->_lexer->glimpse(); + + if ($glimpse['type'] === Lexer::T_DOT) { + return $this->SingleValuedPathExpression(); + } + + // Still need to decide between IdentificationVariable or ResultVariable + $lookaheadValue = $this->_lexer->lookahead['value']; + + if ( ! isset($this->_queryComponents[$lookaheadValue])) { + $this->semanticalError('Cannot group by undefined identification or result variable.'); + } + + return (isset($this->_queryComponents[$lookaheadValue]['metadata'])) + ? $this->IdentificationVariable() + : $this->ResultVariable(); + } + + /** + * OrderByItem ::= (ResultVariable | SingleValuedPathExpression) ["ASC" | "DESC"] + * + * @return \Doctrine\ORM\Query\AST\OrderByItem + */ + public function OrderByItem() + { + $type = 'ASC'; + + // We need to check if we are in a ResultVariable or StateFieldPathExpression + $glimpse = $this->_lexer->glimpse(); + $expr = ($glimpse['type'] != Lexer::T_DOT) ? $this->ResultVariable() : $this->SingleValuedPathExpression(); + + $item = new AST\OrderByItem($expr); + + switch (true) { + case ($this->_lexer->isNextToken(Lexer::T_DESC)): + $this->match(Lexer::T_DESC); + $type = 'DESC'; + break; + + case ($this->_lexer->isNextToken(Lexer::T_ASC)): + $this->match(Lexer::T_ASC); + break; + + default: + // Do nothing + } + + $item->type = $type; + + return $item; + } + + /** + * NewValue ::= SimpleArithmeticExpression | StringPrimary | DatetimePrimary | BooleanPrimary | + * EnumPrimary | SimpleEntityExpression | "NULL" + * + * NOTE: Since it is not possible to correctly recognize individual types, here is the full + * grammar that needs to be supported: + * + * NewValue ::= SimpleArithmeticExpression | "NULL" + * + * SimpleArithmeticExpression covers all *Primary grammar rules and also SimplEntityExpression + */ + public function NewValue() + { + if ($this->_lexer->isNextToken(Lexer::T_NULL)) { + $this->match(Lexer::T_NULL); + + return null; + } + + if ($this->_lexer->isNextToken(Lexer::T_INPUT_PARAMETER)) { + $this->match(Lexer::T_INPUT_PARAMETER); + + return new AST\InputParameter($this->_lexer->token['value']); + } + + return $this->SimpleArithmeticExpression(); + } + + /** + * IdentificationVariableDeclaration ::= RangeVariableDeclaration [IndexBy] {JoinVariableDeclaration}* + * + * @return \Doctrine\ORM\Query\AST\IdentificationVariableDeclaration + */ + public function IdentificationVariableDeclaration() + { + $rangeVariableDeclaration = $this->RangeVariableDeclaration(); + $indexBy = $this->_lexer->isNextToken(Lexer::T_INDEX) ? $this->IndexBy() : null; + $joinVariableDeclarations = array(); + + while ( + $this->_lexer->isNextToken(Lexer::T_LEFT) || + $this->_lexer->isNextToken(Lexer::T_INNER) || + $this->_lexer->isNextToken(Lexer::T_JOIN) + ) { + $joinVariableDeclarations[] = $this->JoinVariableDeclaration(); + } + + return new AST\IdentificationVariableDeclaration( + $rangeVariableDeclaration, $indexBy, $joinVariableDeclarations + ); + } + + /** + * SubselectIdentificationVariableDeclaration ::= IdentificationVariableDeclaration | (AssociationPathExpression ["AS"] AliasIdentificationVariable) + * + * @return \Doctrine\ORM\Query\AST\SubselectIdentificationVariableDeclaration | + * \Doctrine\ORM\Query\AST\IdentificationVariableDeclaration + */ + public function SubselectIdentificationVariableDeclaration() + { + $glimpse = $this->_lexer->glimpse(); + + /* NOT YET IMPLEMENTED! + + if ($glimpse['type'] == Lexer::T_DOT) { + $subselectIdVarDecl = new AST\SubselectIdentificationVariableDeclaration(); + $subselectIdVarDecl->associationPathExpression = $this->AssociationPathExpression(); + $this->match(Lexer::T_AS); + $subselectIdVarDecl->aliasIdentificationVariable = $this->AliasIdentificationVariable(); + + return $subselectIdVarDecl; + } + */ + + return $this->IdentificationVariableDeclaration(); + } + + /** + * JoinVariableDeclaration ::= Join [IndexBy] + * + * @return \Doctrine\ORM\Query\AST\JoinVariableDeclaration + */ + public function JoinVariableDeclaration() + { + $join = $this->Join(); + $indexBy = $this->_lexer->isNextToken(Lexer::T_INDEX) ? $this->IndexBy() : null; + + return new AST\JoinVariableDeclaration($join, $indexBy); + } + + /** + * RangeVariableDeclaration ::= AbstractSchemaName ["AS"] AliasIdentificationVariable + * + * @return \Doctrine\ORM\Query\AST\RangeVariableDeclaration + */ + public function RangeVariableDeclaration() + { + $abstractSchemaName = $this->AbstractSchemaName(); + + if ($this->_lexer->isNextToken(Lexer::T_AS)) { + $this->match(Lexer::T_AS); + } + + $token = $this->_lexer->lookahead; + $aliasIdentificationVariable = $this->AliasIdentificationVariable(); + $classMetadata = $this->_em->getClassMetadata($abstractSchemaName); + + // Building queryComponent + $queryComponent = array( + 'metadata' => $classMetadata, + 'parent' => null, + 'relation' => null, + 'map' => null, + 'nestingLevel' => $this->_nestingLevel, + 'token' => $token + ); + + $this->_queryComponents[$aliasIdentificationVariable] = $queryComponent; + + return new AST\RangeVariableDeclaration($abstractSchemaName, $aliasIdentificationVariable); + } + + /** + * PartialObjectExpression ::= "PARTIAL" IdentificationVariable "." PartialFieldSet + * PartialFieldSet ::= "{" SimpleStateField {"," SimpleStateField}* "}" + * + * @return array + */ + public function PartialObjectExpression() + { + $this->match(Lexer::T_PARTIAL); + + $partialFieldSet = array(); + + $identificationVariable = $this->IdentificationVariable(); + + $this->match(Lexer::T_DOT); + $this->match(Lexer::T_OPEN_CURLY_BRACE); + $this->match(Lexer::T_IDENTIFIER); + + $partialFieldSet[] = $this->_lexer->token['value']; + + while ($this->_lexer->isNextToken(Lexer::T_COMMA)) { + $this->match(Lexer::T_COMMA); + $this->match(Lexer::T_IDENTIFIER); + + $partialFieldSet[] = $this->_lexer->token['value']; + } + + $this->match(Lexer::T_CLOSE_CURLY_BRACE); + + $partialObjectExpression = new AST\PartialObjectExpression($identificationVariable, $partialFieldSet); + + // Defer PartialObjectExpression validation + $this->_deferredPartialObjectExpressions[] = array( + 'expression' => $partialObjectExpression, + 'nestingLevel' => $this->_nestingLevel, + 'token' => $this->_lexer->token, + ); + + return $partialObjectExpression; + } + + /** + * Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" JoinAssociationPathExpression + * ["AS"] AliasIdentificationVariable ["WITH" ConditionalExpression] + * + * @return \Doctrine\ORM\Query\AST\Join + */ + public function Join() + { + // Check Join type + $joinType = AST\Join::JOIN_TYPE_INNER; + + switch (true) { + case ($this->_lexer->isNextToken(Lexer::T_LEFT)): + $this->match(Lexer::T_LEFT); + + $joinType = AST\Join::JOIN_TYPE_LEFT; + + // Possible LEFT OUTER join + if ($this->_lexer->isNextToken(Lexer::T_OUTER)) { + $this->match(Lexer::T_OUTER); + + $joinType = AST\Join::JOIN_TYPE_LEFTOUTER; + } + break; + + case ($this->_lexer->isNextToken(Lexer::T_INNER)): + $this->match(Lexer::T_INNER); + break; + + default: + // Do nothing + } + + $this->match(Lexer::T_JOIN); + + $joinPathExpression = $this->JoinAssociationPathExpression(); + + if ($this->_lexer->isNextToken(Lexer::T_AS)) { + $this->match(Lexer::T_AS); + } + + $token = $this->_lexer->lookahead; + $aliasIdentificationVariable = $this->AliasIdentificationVariable(); + + // Verify that the association exists. + $parentClass = $this->_queryComponents[$joinPathExpression->identificationVariable]['metadata']; + $assocField = $joinPathExpression->associationField; + + if ( ! $parentClass->hasAssociation($assocField)) { + $this->semanticalError( + "Class " . $parentClass->name . " has no association named '$assocField'." + ); + } + + $targetClassName = $parentClass->associationMappings[$assocField]['targetEntity']; + + // Building queryComponent + $joinQueryComponent = array( + 'metadata' => $this->_em->getClassMetadata($targetClassName), + 'parent' => $joinPathExpression->identificationVariable, + 'relation' => $parentClass->getAssociationMapping($assocField), + 'map' => null, + 'nestingLevel' => $this->_nestingLevel, + 'token' => $token + ); + + $this->_queryComponents[$aliasIdentificationVariable] = $joinQueryComponent; + + // Create AST node + $join = new AST\Join($joinType, $joinPathExpression, $aliasIdentificationVariable); + + // Check for ad-hoc Join conditions + if ($this->_lexer->isNextToken(Lexer::T_WITH)) { + $this->match(Lexer::T_WITH); + + $join->conditionalExpression = $this->ConditionalExpression(); + } + + return $join; + } + + /** + * IndexBy ::= "INDEX" "BY" StateFieldPathExpression + * + * @return \Doctrine\ORM\Query\AST\IndexBy + */ + public function IndexBy() + { + $this->match(Lexer::T_INDEX); + $this->match(Lexer::T_BY); + $pathExpr = $this->StateFieldPathExpression(); + + // Add the INDEX BY info to the query component + $this->_queryComponents[$pathExpr->identificationVariable]['map'] = $pathExpr->field; + + return new AST\IndexBy($pathExpr); + } + + /** + * ScalarExpression ::= SimpleArithmeticExpression | StringPrimary | DateTimePrimary | + * StateFieldPathExpression | BooleanPrimary | CaseExpression | + * InstanceOfExpression + * + * @return mixed One of the possible expressions or subexpressions. + */ + public function ScalarExpression() + { + $lookahead = $this->_lexer->lookahead['type']; + + switch ($lookahead) { + case Lexer::T_IDENTIFIER: + $this->_lexer->peek(); // lookahead => '.' + $this->_lexer->peek(); // lookahead => token after '.' + $peek = $this->_lexer->peek(); // lookahead => token after the token after the '.' + $this->_lexer->resetPeek(); + + if ($this->_isMathOperator($peek)) { + return $this->SimpleArithmeticExpression(); + } + + return $this->StateFieldPathExpression(); + + case Lexer::T_INTEGER: + case Lexer::T_FLOAT: + return $this->SimpleArithmeticExpression(); + + case Lexer::T_STRING: + return $this->StringPrimary(); + + case Lexer::T_TRUE: + case Lexer::T_FALSE: + $this->match($lookahead); + + return new AST\Literal(AST\Literal::BOOLEAN, $this->_lexer->token['value']); + + case Lexer::T_INPUT_PARAMETER: + return $this->InputParameter(); + + case Lexer::T_CASE: + case Lexer::T_COALESCE: + case Lexer::T_NULLIF: + // Since NULLIF and COALESCE can be identified as a function, + // we need to check if before check for FunctionDeclaration + return $this->CaseExpression(); + + default: + if ( ! ($this->_isFunction() || $this->_isAggregateFunction($lookahead))) { + $this->syntaxError(); + } + + // We may be in an ArithmeticExpression (find the matching ")" and inspect for Math operator) + $this->_lexer->peek(); // "(" + $peek = $this->_peekBeyondClosingParenthesis(); + + if ($this->_isMathOperator($peek)) { + return $this->SimpleArithmeticExpression(); + } + + if ($this->_isAggregateFunction($this->_lexer->lookahead['type'])) { + return $this->AggregateExpression(); + } + + return $this->FunctionDeclaration(); + } + } + + /** + * CaseExpression ::= GeneralCaseExpression | SimpleCaseExpression | CoalesceExpression | NullifExpression + * GeneralCaseExpression ::= "CASE" WhenClause {WhenClause}* "ELSE" ScalarExpression "END" + * WhenClause ::= "WHEN" ConditionalExpression "THEN" ScalarExpression + * SimpleCaseExpression ::= "CASE" CaseOperand SimpleWhenClause {SimpleWhenClause}* "ELSE" ScalarExpression "END" + * CaseOperand ::= StateFieldPathExpression | TypeDiscriminator + * SimpleWhenClause ::= "WHEN" ScalarExpression "THEN" ScalarExpression + * CoalesceExpression ::= "COALESCE" "(" ScalarExpression {"," ScalarExpression}* ")" + * NullifExpression ::= "NULLIF" "(" ScalarExpression "," ScalarExpression ")" + * + * @return mixed One of the possible expressions or subexpressions. + */ + public function CaseExpression() + { + $lookahead = $this->_lexer->lookahead['type']; + + switch ($lookahead) { + case Lexer::T_NULLIF: + return $this->NullIfExpression(); + + case Lexer::T_COALESCE: + return $this->CoalesceExpression(); + + case Lexer::T_CASE: + $this->_lexer->resetPeek(); + $peek = $this->_lexer->peek(); + + if ($peek['type'] === Lexer::T_WHEN) { + return $this->GeneralCaseExpression(); + } + + return $this->SimpleCaseExpression(); + + default: + // Do nothing + break; + } + + $this->syntaxError(); + } + + /** + * CoalesceExpression ::= "COALESCE" "(" ScalarExpression {"," ScalarExpression}* ")" + * + * @return \Doctrine\ORM\Query\AST\CoalesceExpression + */ + public function CoalesceExpression() + { + $this->match(Lexer::T_COALESCE); + $this->match(Lexer::T_OPEN_PARENTHESIS); + + // Process ScalarExpressions (1..N) + $scalarExpressions = array(); + $scalarExpressions[] = $this->ScalarExpression(); + + while ($this->_lexer->isNextToken(Lexer::T_COMMA)) { + $this->match(Lexer::T_COMMA); + + $scalarExpressions[] = $this->ScalarExpression(); + } + + $this->match(Lexer::T_CLOSE_PARENTHESIS); + + return new AST\CoalesceExpression($scalarExpressions); + } + + /** + * NullIfExpression ::= "NULLIF" "(" ScalarExpression "," ScalarExpression ")" + * + * @return \Doctrine\ORM\Query\AST\NullIfExpression + */ + public function NullIfExpression() + { + $this->match(Lexer::T_NULLIF); + $this->match(Lexer::T_OPEN_PARENTHESIS); + + $firstExpression = $this->ScalarExpression(); + $this->match(Lexer::T_COMMA); + $secondExpression = $this->ScalarExpression(); + + $this->match(Lexer::T_CLOSE_PARENTHESIS); + + return new AST\NullIfExpression($firstExpression, $secondExpression); + } + + /** + * GeneralCaseExpression ::= "CASE" WhenClause {WhenClause}* "ELSE" ScalarExpression "END" + * + * @return \Doctrine\ORM\Query\AST\GeneralExpression + */ + public function GeneralCaseExpression() + { + $this->match(Lexer::T_CASE); + + // Process WhenClause (1..N) + $whenClauses = array(); + + do { + $whenClauses[] = $this->WhenClause(); + } while ($this->_lexer->isNextToken(Lexer::T_WHEN)); + + $this->match(Lexer::T_ELSE); + $scalarExpression = $this->ScalarExpression(); + $this->match(Lexer::T_END); + + return new AST\GeneralCaseExpression($whenClauses, $scalarExpression); + } + + /** + * SimpleCaseExpression ::= "CASE" CaseOperand SimpleWhenClause {SimpleWhenClause}* "ELSE" ScalarExpression "END" + * CaseOperand ::= StateFieldPathExpression | TypeDiscriminator + */ + public function SimpleCaseExpression() + { + $this->match(Lexer::T_CASE); + $caseOperand = $this->StateFieldPathExpression(); + + // Process SimpleWhenClause (1..N) + $simpleWhenClauses = array(); + + do { + $simpleWhenClauses[] = $this->SimpleWhenClause(); + } while ($this->_lexer->isNextToken(Lexer::T_WHEN)); + + $this->match(Lexer::T_ELSE); + $scalarExpression = $this->ScalarExpression(); + $this->match(Lexer::T_END); + + return new AST\SimpleCaseExpression($caseOperand, $simpleWhenClauses, $scalarExpression); + } + + /** + * WhenClause ::= "WHEN" ConditionalExpression "THEN" ScalarExpression + * + * @return \Doctrine\ORM\Query\AST\WhenExpression + */ + public function WhenClause() + { + $this->match(Lexer::T_WHEN); + $conditionalExpression = $this->ConditionalExpression(); + $this->match(Lexer::T_THEN); + + return new AST\WhenClause($conditionalExpression, $this->ScalarExpression()); + } + + /** + * SimpleWhenClause ::= "WHEN" ScalarExpression "THEN" ScalarExpression + * + * @return \Doctrine\ORM\Query\AST\SimpleWhenExpression + */ + public function SimpleWhenClause() + { + $this->match(Lexer::T_WHEN); + $conditionalExpression = $this->ScalarExpression(); + $this->match(Lexer::T_THEN); + + return new AST\SimpleWhenClause($conditionalExpression, $this->ScalarExpression()); + } + + /** + * SelectExpression ::= ( + * IdentificationVariable | ScalarExpression | AggregateExpression | FunctionDeclaration | + * PartialObjectExpression | "(" Subselect ")" | CaseExpression + * ) [["AS"] ["HIDDEN"] AliasResultVariable] + * + * @return \Doctrine\ORM\Query\AST\SelectExpression + */ + public function SelectExpression() + { + $expression = null; + $identVariable = null; + $peek = $this->_lexer->glimpse(); + $lookaheadType = $this->_lexer->lookahead['type']; + + switch (true) { + // ScalarExpression (u.name) + case ($lookaheadType === Lexer::T_IDENTIFIER && $peek['type'] === Lexer::T_DOT): + $expression = $this->ScalarExpression(); + break; + + // IdentificationVariable (u) + case ($lookaheadType === Lexer::T_IDENTIFIER && $peek['type'] !== Lexer::T_OPEN_PARENTHESIS): + $expression = $identVariable = $this->IdentificationVariable(); + break; + + // CaseExpression (CASE ... or NULLIF(...) or COALESCE(...)) + case ($lookaheadType === Lexer::T_CASE): + case ($lookaheadType === Lexer::T_COALESCE): + case ($lookaheadType === Lexer::T_NULLIF): + $expression = $this->CaseExpression(); + break; + + // DQL Function (SUM(u.value) or SUM(u.value) + 1) + case ($this->_isFunction()): + $this->_lexer->peek(); // "(" + + switch (true) { + case ($this->_isMathOperator($this->_peekBeyondClosingParenthesis())): + // SUM(u.id) + COUNT(u.id) + $expression = $this->ScalarExpression(); + break; + + case ($this->_isAggregateFunction($lookaheadType)): + // COUNT(u.id) + $expression = $this->AggregateExpression(); + break; + + default: + // IDENTITY(u) + $expression = $this->FunctionDeclaration(); + break; + } + + break; + + // PartialObjectExpression (PARTIAL u.{id, name}) + case ($lookaheadType === Lexer::T_PARTIAL): + $expression = $this->PartialObjectExpression(); + $identVariable = $expression->identificationVariable; + break; + + // Subselect + case ($lookaheadType === Lexer::T_OPEN_PARENTHESIS && $peek['type'] === Lexer::T_SELECT): + $this->match(Lexer::T_OPEN_PARENTHESIS); + $expression = $this->Subselect(); + $this->match(Lexer::T_CLOSE_PARENTHESIS); + break; + + // Shortcut: ScalarExpression => SimpleArithmeticExpression + case ($lookaheadType === Lexer::T_OPEN_PARENTHESIS): + case ($lookaheadType === Lexer::T_INTEGER): + case ($lookaheadType === Lexer::T_STRING): + case ($lookaheadType === Lexer::T_FLOAT): + // SimpleArithmeticExpression : (- u.value ) or ( + u.value ) + case ($lookaheadType === Lexer::T_MINUS): + case ($lookaheadType === Lexer::T_PLUS): + $expression = $this->SimpleArithmeticExpression(); + break; + + default: + $this->syntaxError( + 'IdentificationVariable | ScalarExpression | AggregateExpression | FunctionDeclaration | PartialObjectExpression | "(" Subselect ")" | CaseExpression', + $this->_lexer->lookahead + ); + } + + // [["AS"] ["HIDDEN"] AliasResultVariable] + + if ($this->_lexer->isNextToken(Lexer::T_AS)) { + $this->match(Lexer::T_AS); + } + + $hiddenAliasResultVariable = false; + + if ($this->_lexer->isNextToken(Lexer::T_HIDDEN)) { + $this->match(Lexer::T_HIDDEN); + + $hiddenAliasResultVariable = true; + } + + $aliasResultVariable = null; + + if ($this->_lexer->isNextToken(Lexer::T_IDENTIFIER)) { + $token = $this->_lexer->lookahead; + $aliasResultVariable = $this->AliasResultVariable(); + + // Include AliasResultVariable in query components. + $this->_queryComponents[$aliasResultVariable] = array( + 'resultVariable' => $expression, + 'nestingLevel' => $this->_nestingLevel, + 'token' => $token, + ); + } + + // AST + + $expr = new AST\SelectExpression($expression, $aliasResultVariable, $hiddenAliasResultVariable); + + if ($identVariable) { + $this->_identVariableExpressions[$identVariable] = $expr; + } + + return $expr; + } + + /** + * SimpleSelectExpression ::= + * StateFieldPathExpression | IdentificationVariable | + * ((AggregateExpression | "(" Subselect ")" | ScalarExpression) [["AS"] AliasResultVariable]) + * + * @return \Doctrine\ORM\Query\AST\SimpleSelectExpression + */ + public function SimpleSelectExpression() + { + $peek = $this->_lexer->glimpse(); + + switch ($this->_lexer->lookahead['type']) { + case Lexer::T_IDENTIFIER: + switch (true) { + case ($peek['type'] === Lexer::T_DOT): + $expression = $this->StateFieldPathExpression(); + + return new AST\SimpleSelectExpression($expression); + + case ($peek['type'] !== Lexer::T_OPEN_PARENTHESIS): + $expression = $this->IdentificationVariable(); + + return new AST\SimpleSelectExpression($expression); + + default: + // Do nothing + } + break; + + case Lexer::T_OPEN_PARENTHESIS: + if ($peek['type'] !== Lexer::T_SELECT) { + // Shortcut: ScalarExpression => SimpleArithmeticExpression + $expression = $this->SimpleArithmeticExpression(); + + return new AST\SimpleSelectExpression($expression); + } + + // Subselect + $this->match(Lexer::T_OPEN_PARENTHESIS); + $expression = $this->Subselect(); + $this->match(Lexer::T_CLOSE_PARENTHESIS); + + return new AST\SimpleSelectExpression($expression); + + default: + // Do nothing + } + + $this->_lexer->peek(); + + $expression = $this->ScalarExpression(); + $expr = new AST\SimpleSelectExpression($expression); + + if ($this->_lexer->isNextToken(Lexer::T_AS)) { + $this->match(Lexer::T_AS); + } + + if ($this->_lexer->isNextToken(Lexer::T_IDENTIFIER)) { + $token = $this->_lexer->lookahead; + $resultVariable = $this->AliasResultVariable(); + $expr->fieldIdentificationVariable = $resultVariable; + + // Include AliasResultVariable in query components. + $this->_queryComponents[$resultVariable] = array( + 'resultvariable' => $expr, + 'nestingLevel' => $this->_nestingLevel, + 'token' => $token, + ); + } + + return $expr; + } + + /** + * ConditionalExpression ::= ConditionalTerm {"OR" ConditionalTerm}* + * + * @return \Doctrine\ORM\Query\AST\ConditionalExpression + */ + public function ConditionalExpression() + { + $conditionalTerms = array(); + $conditionalTerms[] = $this->ConditionalTerm(); + + while ($this->_lexer->isNextToken(Lexer::T_OR)) { + $this->match(Lexer::T_OR); + + $conditionalTerms[] = $this->ConditionalTerm(); + } + + // Phase 1 AST optimization: Prevent AST\ConditionalExpression + // if only one AST\ConditionalTerm is defined + if (count($conditionalTerms) == 1) { + return $conditionalTerms[0]; + } + + return new AST\ConditionalExpression($conditionalTerms); + } + + /** + * ConditionalTerm ::= ConditionalFactor {"AND" ConditionalFactor}* + * + * @return \Doctrine\ORM\Query\AST\ConditionalTerm + */ + public function ConditionalTerm() + { + $conditionalFactors = array(); + $conditionalFactors[] = $this->ConditionalFactor(); + + while ($this->_lexer->isNextToken(Lexer::T_AND)) { + $this->match(Lexer::T_AND); + + $conditionalFactors[] = $this->ConditionalFactor(); + } + + // Phase 1 AST optimization: Prevent AST\ConditionalTerm + // if only one AST\ConditionalFactor is defined + if (count($conditionalFactors) == 1) { + return $conditionalFactors[0]; + } + + return new AST\ConditionalTerm($conditionalFactors); + } + + /** + * ConditionalFactor ::= ["NOT"] ConditionalPrimary + * + * @return \Doctrine\ORM\Query\AST\ConditionalFactor + */ + public function ConditionalFactor() + { + $not = false; + + if ($this->_lexer->isNextToken(Lexer::T_NOT)) { + $this->match(Lexer::T_NOT); + + $not = true; + } + + $conditionalPrimary = $this->ConditionalPrimary(); + + // Phase 1 AST optimization: Prevent AST\ConditionalFactor + // if only one AST\ConditionalPrimary is defined + if ( ! $not) { + return $conditionalPrimary; + } + + $conditionalFactor = new AST\ConditionalFactor($conditionalPrimary); + $conditionalFactor->not = $not; + + return $conditionalFactor; + } + + /** + * ConditionalPrimary ::= SimpleConditionalExpression | "(" ConditionalExpression ")" + * + * @return \Doctrine\ORM\Query\AST\ConditionalPrimary + */ + public function ConditionalPrimary() + { + $condPrimary = new AST\ConditionalPrimary; + + if ( ! $this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) { + $condPrimary->simpleConditionalExpression = $this->SimpleConditionalExpression(); + + return $condPrimary; + } + + // Peek beyond the matching closing paranthesis ')' + $peek = $this->_peekBeyondClosingParenthesis(); + + if (in_array($peek['value'], array("=", "<", "<=", "<>", ">", ">=", "!=")) || + in_array($peek['type'], array(Lexer::T_NOT, Lexer::T_BETWEEN, Lexer::T_LIKE, Lexer::T_IN, Lexer::T_IS, Lexer::T_EXISTS)) || + $this->_isMathOperator($peek)) { + $condPrimary->simpleConditionalExpression = $this->SimpleConditionalExpression(); + + return $condPrimary; + } + + $this->match(Lexer::T_OPEN_PARENTHESIS); + $condPrimary->conditionalExpression = $this->ConditionalExpression(); + $this->match(Lexer::T_CLOSE_PARENTHESIS); + + return $condPrimary; + } + + /** + * SimpleConditionalExpression ::= + * ComparisonExpression | BetweenExpression | LikeExpression | + * InExpression | NullComparisonExpression | ExistsExpression | + * EmptyCollectionComparisonExpression | CollectionMemberExpression | + * InstanceOfExpression + */ + public function SimpleConditionalExpression() + { + $token = $this->_lexer->lookahead; + + if ($this->_lexer->isNextToken(Lexer::T_NOT)) { + $token = $this->_lexer->glimpse(); + } + + if ($token['type'] === Lexer::T_EXISTS) { + return $this->ExistsExpression(); + } + + $peek = $this->_lexer->glimpse(); + + if ($token['type'] === Lexer::T_IDENTIFIER || $token['type'] === Lexer::T_INPUT_PARAMETER) { + if ($peek['value'] == '(') { + // Peek beyond the matching closing paranthesis ')' + $this->_lexer->peek(); + $token = $this->_peekBeyondClosingParenthesis(); + } else { + // Peek beyond the PathExpression (or InputParameter) + $peek = $this->_lexer->peek(); + + while ($peek['value'] === '.') { + $this->_lexer->peek(); + $peek = $this->_lexer->peek(); + } + + // Also peek beyond a NOT if there is one + if ($peek['type'] === Lexer::T_NOT) { + $peek = $this->_lexer->peek(); + } + + $token = $peek; + + // We need to go even further in case of IS (differenciate between NULL and EMPTY) + $lookahead = $this->_lexer->peek(); + + // Also peek beyond a NOT if there is one + if ($lookahead['type'] === Lexer::T_NOT) { + $lookahead = $this->_lexer->peek(); + } + + $this->_lexer->resetPeek(); + } + } + + switch ($token['type']) { + case Lexer::T_BETWEEN: + return $this->BetweenExpression(); + case Lexer::T_LIKE: + return $this->LikeExpression(); + case Lexer::T_IN: + return $this->InExpression(); + case Lexer::T_INSTANCE: + return $this->InstanceOfExpression(); + case Lexer::T_IS: + if ($lookahead['type'] == Lexer::T_NULL) { + return $this->NullComparisonExpression(); + } + return $this->EmptyCollectionComparisonExpression(); + case Lexer::T_MEMBER: + return $this->CollectionMemberExpression(); + default: + return $this->ComparisonExpression(); + } + } + + /** + * EmptyCollectionComparisonExpression ::= CollectionValuedPathExpression "IS" ["NOT"] "EMPTY" + * + * @return \Doctrine\ORM\Query\AST\EmptyCollectionComparisonExpression + */ + public function EmptyCollectionComparisonExpression() + { + $emptyColletionCompExpr = new AST\EmptyCollectionComparisonExpression( + $this->CollectionValuedPathExpression() + ); + $this->match(Lexer::T_IS); + + if ($this->_lexer->isNextToken(Lexer::T_NOT)) { + $this->match(Lexer::T_NOT); + $emptyColletionCompExpr->not = true; + } + + $this->match(Lexer::T_EMPTY); + + return $emptyColletionCompExpr; + } + + /** + * CollectionMemberExpression ::= EntityExpression ["NOT"] "MEMBER" ["OF"] CollectionValuedPathExpression + * + * EntityExpression ::= SingleValuedAssociationPathExpression | SimpleEntityExpression + * SimpleEntityExpression ::= IdentificationVariable | InputParameter + * + * @return \Doctrine\ORM\Query\AST\CollectionMemberExpression + */ + public function CollectionMemberExpression() + { + $not = false; + $entityExpr = $this->EntityExpression(); + + if ($this->_lexer->isNextToken(Lexer::T_NOT)) { + $this->match(Lexer::T_NOT); + + $not = true; + } + + $this->match(Lexer::T_MEMBER); + + if ($this->_lexer->isNextToken(Lexer::T_OF)) { + $this->match(Lexer::T_OF); + } + + $collMemberExpr = new AST\CollectionMemberExpression( + $entityExpr, $this->CollectionValuedPathExpression() + ); + $collMemberExpr->not = $not; + + return $collMemberExpr; + } + + /** + * Literal ::= string | char | integer | float | boolean + * + * @return string + */ + public function Literal() + { + switch ($this->_lexer->lookahead['type']) { + case Lexer::T_STRING: + $this->match(Lexer::T_STRING); + return new AST\Literal(AST\Literal::STRING, $this->_lexer->token['value']); + + case Lexer::T_INTEGER: + case Lexer::T_FLOAT: + $this->match( + $this->_lexer->isNextToken(Lexer::T_INTEGER) ? Lexer::T_INTEGER : Lexer::T_FLOAT + ); + return new AST\Literal(AST\Literal::NUMERIC, $this->_lexer->token['value']); + + case Lexer::T_TRUE: + case Lexer::T_FALSE: + $this->match( + $this->_lexer->isNextToken(Lexer::T_TRUE) ? Lexer::T_TRUE : Lexer::T_FALSE + ); + return new AST\Literal(AST\Literal::BOOLEAN, $this->_lexer->token['value']); + + default: + $this->syntaxError('Literal'); + } + } + + /** + * InParameter ::= Literal | InputParameter + * + * @return string | \Doctrine\ORM\Query\AST\InputParameter + */ + public function InParameter() + { + if ($this->_lexer->lookahead['type'] == Lexer::T_INPUT_PARAMETER) { + return $this->InputParameter(); + } + + return $this->Literal(); + } + + /** + * InputParameter ::= PositionalParameter | NamedParameter + * + * @return \Doctrine\ORM\Query\AST\InputParameter + */ + public function InputParameter() + { + $this->match(Lexer::T_INPUT_PARAMETER); + + return new AST\InputParameter($this->_lexer->token['value']); + } + + /** + * ArithmeticExpression ::= SimpleArithmeticExpression | "(" Subselect ")" + * + * @return \Doctrine\ORM\Query\AST\ArithmeticExpression + */ + public function ArithmeticExpression() + { + $expr = new AST\ArithmeticExpression; + + if ($this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) { + $peek = $this->_lexer->glimpse(); + + if ($peek['type'] === Lexer::T_SELECT) { + $this->match(Lexer::T_OPEN_PARENTHESIS); + $expr->subselect = $this->Subselect(); + $this->match(Lexer::T_CLOSE_PARENTHESIS); + + return $expr; + } + } + + $expr->simpleArithmeticExpression = $this->SimpleArithmeticExpression(); + + return $expr; + } + + /** + * SimpleArithmeticExpression ::= ArithmeticTerm {("+" | "-") ArithmeticTerm}* + * + * @return \Doctrine\ORM\Query\AST\SimpleArithmeticExpression + */ + public function SimpleArithmeticExpression() + { + $terms = array(); + $terms[] = $this->ArithmeticTerm(); + + while (($isPlus = $this->_lexer->isNextToken(Lexer::T_PLUS)) || $this->_lexer->isNextToken(Lexer::T_MINUS)) { + $this->match(($isPlus) ? Lexer::T_PLUS : Lexer::T_MINUS); + + $terms[] = $this->_lexer->token['value']; + $terms[] = $this->ArithmeticTerm(); + } + + // Phase 1 AST optimization: Prevent AST\SimpleArithmeticExpression + // if only one AST\ArithmeticTerm is defined + if (count($terms) == 1) { + return $terms[0]; + } + + return new AST\SimpleArithmeticExpression($terms); + } + + /** + * ArithmeticTerm ::= ArithmeticFactor {("*" | "/") ArithmeticFactor}* + * + * @return \Doctrine\ORM\Query\AST\ArithmeticTerm + */ + public function ArithmeticTerm() + { + $factors = array(); + $factors[] = $this->ArithmeticFactor(); + + while (($isMult = $this->_lexer->isNextToken(Lexer::T_MULTIPLY)) || $this->_lexer->isNextToken(Lexer::T_DIVIDE)) { + $this->match(($isMult) ? Lexer::T_MULTIPLY : Lexer::T_DIVIDE); + + $factors[] = $this->_lexer->token['value']; + $factors[] = $this->ArithmeticFactor(); + } + + // Phase 1 AST optimization: Prevent AST\ArithmeticTerm + // if only one AST\ArithmeticFactor is defined + if (count($factors) == 1) { + return $factors[0]; + } + + return new AST\ArithmeticTerm($factors); + } + + /** + * ArithmeticFactor ::= [("+" | "-")] ArithmeticPrimary + * + * @return \Doctrine\ORM\Query\AST\ArithmeticFactor + */ + public function ArithmeticFactor() + { + $sign = null; + + if (($isPlus = $this->_lexer->isNextToken(Lexer::T_PLUS)) || $this->_lexer->isNextToken(Lexer::T_MINUS)) { + $this->match(($isPlus) ? Lexer::T_PLUS : Lexer::T_MINUS); + $sign = $isPlus; + } + + $primary = $this->ArithmeticPrimary(); + + // Phase 1 AST optimization: Prevent AST\ArithmeticFactor + // if only one AST\ArithmeticPrimary is defined + if ($sign === null) { + return $primary; + } + + return new AST\ArithmeticFactor($primary, $sign); + } + + /** + * ArithmeticPrimary ::= SingleValuedPathExpression | Literal | "(" SimpleArithmeticExpression ")" + * | FunctionsReturningNumerics | AggregateExpression | FunctionsReturningStrings + * | FunctionsReturningDatetime | IdentificationVariable | ResultVariable | CaseExpression + */ + public function ArithmeticPrimary() + { + if ($this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) { + $this->match(Lexer::T_OPEN_PARENTHESIS); + $expr = $this->SimpleArithmeticExpression(); + + $this->match(Lexer::T_CLOSE_PARENTHESIS); + + return $expr; + } + + switch ($this->_lexer->lookahead['type']) { + case Lexer::T_COALESCE: + case Lexer::T_NULLIF: + case Lexer::T_CASE: + return $this->CaseExpression(); + + case Lexer::T_IDENTIFIER: + $peek = $this->_lexer->glimpse(); + + if ($peek['value'] == '(') { + return $this->FunctionDeclaration(); + } + + if ($peek['value'] == '.') { + return $this->SingleValuedPathExpression(); + } + + if (isset($this->_queryComponents[$this->_lexer->lookahead['value']]['resultVariable'])) { + return $this->ResultVariable(); + } + + return $this->StateFieldPathExpression(); + + case Lexer::T_INPUT_PARAMETER: + return $this->InputParameter(); + + default: + $peek = $this->_lexer->glimpse(); + + if ($peek['value'] == '(') { + if ($this->_isAggregateFunction($this->_lexer->lookahead['type'])) { + return $this->AggregateExpression(); + } + + return $this->FunctionDeclaration(); + } + + return $this->Literal(); + } + } + + /** + * StringExpression ::= StringPrimary | "(" Subselect ")" + * + * @return \Doctrine\ORM\Query\AST\StringPrimary | + * \Doctrine]ORM\Query\AST\Subselect + */ + public function StringExpression() + { + if ($this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) { + $peek = $this->_lexer->glimpse(); + + if ($peek['type'] === Lexer::T_SELECT) { + $this->match(Lexer::T_OPEN_PARENTHESIS); + $expr = $this->Subselect(); + $this->match(Lexer::T_CLOSE_PARENTHESIS); + + return $expr; + } + } + + return $this->StringPrimary(); + } + + /** + * StringPrimary ::= StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression | CaseExpression + */ + public function StringPrimary() + { + $lookaheadType = $this->_lexer->lookahead['type']; + + switch ($lookaheadType) { + case Lexer::T_IDENTIFIER: + $peek = $this->_lexer->glimpse(); + + if ($peek['value'] == '.') { + return $this->StateFieldPathExpression(); + } + + if ($peek['value'] == '(') { + // do NOT directly go to FunctionsReturningString() because it doesnt check for custom functions. + return $this->FunctionDeclaration(); + } + + $this->syntaxError("'.' or '('"); + break; + + case Lexer::T_STRING: + $this->match(Lexer::T_STRING); + + return $this->_lexer->token['value']; + + case Lexer::T_INPUT_PARAMETER: + return $this->InputParameter(); + + case Lexer::T_CASE: + case Lexer::T_COALESCE: + case Lexer::T_NULLIF: + return $this->CaseExpression(); + + default: + if ($this->_isAggregateFunction($lookaheadType)) { + return $this->AggregateExpression(); + } + } + + $this->syntaxError( + 'StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression' + ); + } + + /** + * EntityExpression ::= SingleValuedAssociationPathExpression | SimpleEntityExpression + * + * @return \Doctrine\ORM\Query\AST\SingleValuedAssociationPathExpression | + * \Doctrine\ORM\Query\AST\SimpleEntityExpression + */ + public function EntityExpression() + { + $glimpse = $this->_lexer->glimpse(); + + if ($this->_lexer->isNextToken(Lexer::T_IDENTIFIER) && $glimpse['value'] === '.') { + return $this->SingleValuedAssociationPathExpression(); + } + + return $this->SimpleEntityExpression(); + } + + /** + * SimpleEntityExpression ::= IdentificationVariable | InputParameter + * + * @return string | \Doctrine\ORM\Query\AST\InputParameter + */ + public function SimpleEntityExpression() + { + if ($this->_lexer->isNextToken(Lexer::T_INPUT_PARAMETER)) { + return $this->InputParameter(); + } + + return $this->StateFieldPathExpression(); + } + + /** + * AggregateExpression ::= + * ("AVG" | "MAX" | "MIN" | "SUM") "(" ["DISTINCT"] StateFieldPathExpression ")" | + * "COUNT" "(" ["DISTINCT"] (IdentificationVariable | SingleValuedPathExpression) ")" + * + * @return \Doctrine\ORM\Query\AST\AggregateExpression + */ + public function AggregateExpression() + { + $lookaheadType = $this->_lexer->lookahead['type']; + $isDistinct = false; + + if ( ! in_array($lookaheadType, array(Lexer::T_COUNT, Lexer::T_AVG, Lexer::T_MAX, Lexer::T_MIN, Lexer::T_SUM))) { + $this->syntaxError('One of: MAX, MIN, AVG, SUM, COUNT'); + } + + $this->match($lookaheadType); + $functionName = $this->_lexer->token['value']; + $this->match(Lexer::T_OPEN_PARENTHESIS); + + if ($this->_lexer->isNextToken(Lexer::T_DISTINCT)) { + $this->match(Lexer::T_DISTINCT); + $isDistinct = true; + } + + $pathExp = ($lookaheadType === Lexer::T_COUNT) + ? $this->SingleValuedPathExpression() + : $this->SimpleArithmeticExpression(); + + $this->match(Lexer::T_CLOSE_PARENTHESIS); + + return new AST\AggregateExpression($functionName, $pathExp, $isDistinct); + } + + /** + * QuantifiedExpression ::= ("ALL" | "ANY" | "SOME") "(" Subselect ")" + * + * @return \Doctrine\ORM\Query\AST\QuantifiedExpression + */ + public function QuantifiedExpression() + { + $lookaheadType = $this->_lexer->lookahead['type']; + $value = $this->_lexer->lookahead['value']; + + if ( ! in_array($lookaheadType, array(Lexer::T_ALL, Lexer::T_ANY, Lexer::T_SOME))) { + $this->syntaxError('ALL, ANY or SOME'); + } + + $this->match($lookaheadType); + $this->match(Lexer::T_OPEN_PARENTHESIS); + + $qExpr = new AST\QuantifiedExpression($this->Subselect()); + $qExpr->type = $value; + + $this->match(Lexer::T_CLOSE_PARENTHESIS); + + return $qExpr; + } + + /** + * BetweenExpression ::= ArithmeticExpression ["NOT"] "BETWEEN" ArithmeticExpression "AND" ArithmeticExpression + * + * @return \Doctrine\ORM\Query\AST\BetweenExpression + */ + public function BetweenExpression() + { + $not = false; + $arithExpr1 = $this->ArithmeticExpression(); + + if ($this->_lexer->isNextToken(Lexer::T_NOT)) { + $this->match(Lexer::T_NOT); + $not = true; + } + + $this->match(Lexer::T_BETWEEN); + $arithExpr2 = $this->ArithmeticExpression(); + $this->match(Lexer::T_AND); + $arithExpr3 = $this->ArithmeticExpression(); + + $betweenExpr = new AST\BetweenExpression($arithExpr1, $arithExpr2, $arithExpr3); + $betweenExpr->not = $not; + + return $betweenExpr; + } + + /** + * ComparisonExpression ::= ArithmeticExpression ComparisonOperator ( QuantifiedExpression | ArithmeticExpression ) + * + * @return \Doctrine\ORM\Query\AST\ComparisonExpression + */ + public function ComparisonExpression() + { + $peek = $this->_lexer->glimpse(); + + $leftExpr = $this->ArithmeticExpression(); + $operator = $this->ComparisonOperator(); + $rightExpr = ($this->_isNextAllAnySome()) + ? $this->QuantifiedExpression() + : $this->ArithmeticExpression(); + + return new AST\ComparisonExpression($leftExpr, $operator, $rightExpr); + } + + /** + * InExpression ::= SingleValuedPathExpression ["NOT"] "IN" "(" (InParameter {"," InParameter}* | Subselect) ")" + * + * @return \Doctrine\ORM\Query\AST\InExpression + */ + public function InExpression() + { + $inExpression = new AST\InExpression($this->ArithmeticExpression()); + + if ($this->_lexer->isNextToken(Lexer::T_NOT)) { + $this->match(Lexer::T_NOT); + $inExpression->not = true; + } + + $this->match(Lexer::T_IN); + $this->match(Lexer::T_OPEN_PARENTHESIS); + + if ($this->_lexer->isNextToken(Lexer::T_SELECT)) { + $inExpression->subselect = $this->Subselect(); + } else { + $literals = array(); + $literals[] = $this->InParameter(); + + while ($this->_lexer->isNextToken(Lexer::T_COMMA)) { + $this->match(Lexer::T_COMMA); + $literals[] = $this->InParameter(); + } + + $inExpression->literals = $literals; + } + + $this->match(Lexer::T_CLOSE_PARENTHESIS); + + return $inExpression; + } + + /** + * InstanceOfExpression ::= IdentificationVariable ["NOT"] "INSTANCE" ["OF"] (InstanceOfParameter | "(" InstanceOfParameter {"," InstanceOfParameter}* ")") + * + * @return \Doctrine\ORM\Query\AST\InstanceOfExpression + */ + public function InstanceOfExpression() + { + $instanceOfExpression = new AST\InstanceOfExpression($this->IdentificationVariable()); + + if ($this->_lexer->isNextToken(Lexer::T_NOT)) { + $this->match(Lexer::T_NOT); + $instanceOfExpression->not = true; + } + + $this->match(Lexer::T_INSTANCE); + $this->match(Lexer::T_OF); + + $exprValues = array(); + + if ($this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) { + $this->match(Lexer::T_OPEN_PARENTHESIS); + + $exprValues[] = $this->InstanceOfParameter(); + + while ($this->_lexer->isNextToken(Lexer::T_COMMA)) { + $this->match(Lexer::T_COMMA); + + $exprValues[] = $this->InstanceOfParameter(); + } + + $this->match(Lexer::T_CLOSE_PARENTHESIS); + + $instanceOfExpression->value = $exprValues; + + return $instanceOfExpression; + } + + $exprValues[] = $this->InstanceOfParameter(); + + $instanceOfExpression->value = $exprValues; + + return $instanceOfExpression; + } + + /** + * InstanceOfParameter ::= AbstractSchemaName | InputParameter + * + * @return mixed + */ + public function InstanceOfParameter() + { + if ($this->_lexer->isNextToken(Lexer::T_INPUT_PARAMETER)) { + $this->match(Lexer::T_INPUT_PARAMETER); + + return new AST\InputParameter($this->_lexer->token['value']); + } + + return $this->AliasIdentificationVariable(); + } + + /** + * LikeExpression ::= StringExpression ["NOT"] "LIKE" (string | input_parameter) ["ESCAPE" char] + * + * @return \Doctrine\ORM\Query\AST\LikeExpression + */ + public function LikeExpression() + { + $stringExpr = $this->StringExpression(); + $not = false; + + if ($this->_lexer->isNextToken(Lexer::T_NOT)) { + $this->match(Lexer::T_NOT); + $not = true; + } + + $this->match(Lexer::T_LIKE); + + if ($this->_lexer->isNextToken(Lexer::T_INPUT_PARAMETER)) { + $this->match(Lexer::T_INPUT_PARAMETER); + $stringPattern = new AST\InputParameter($this->_lexer->token['value']); + } else { + $this->match(Lexer::T_STRING); + $stringPattern = $this->_lexer->token['value']; + } + + $escapeChar = null; + + if ($this->_lexer->lookahead['type'] === Lexer::T_ESCAPE) { + $this->match(Lexer::T_ESCAPE); + $this->match(Lexer::T_STRING); + $escapeChar = $this->_lexer->token['value']; + } + + $likeExpr = new AST\LikeExpression($stringExpr, $stringPattern, $escapeChar); + $likeExpr->not = $not; + + return $likeExpr; + } + + /** + * NullComparisonExpression ::= (SingleValuedPathExpression | InputParameter) "IS" ["NOT"] "NULL" + * + * @return \Doctrine\ORM\Query\AST\NullComparisonExpression + */ + public function NullComparisonExpression() + { + if ($this->_lexer->isNextToken(Lexer::T_INPUT_PARAMETER)) { + $this->match(Lexer::T_INPUT_PARAMETER); + $expr = new AST\InputParameter($this->_lexer->token['value']); + } else { + $expr = $this->SingleValuedPathExpression(); + } + + $nullCompExpr = new AST\NullComparisonExpression($expr); + $this->match(Lexer::T_IS); + + if ($this->_lexer->isNextToken(Lexer::T_NOT)) { + $this->match(Lexer::T_NOT); + $nullCompExpr->not = true; + } + + $this->match(Lexer::T_NULL); + + return $nullCompExpr; + } + + /** + * ExistsExpression ::= ["NOT"] "EXISTS" "(" Subselect ")" + * + * @return \Doctrine\ORM\Query\AST\ExistsExpression + */ + public function ExistsExpression() + { + $not = false; + + if ($this->_lexer->isNextToken(Lexer::T_NOT)) { + $this->match(Lexer::T_NOT); + $not = true; + } + + $this->match(Lexer::T_EXISTS); + $this->match(Lexer::T_OPEN_PARENTHESIS); + + $existsExpression = new AST\ExistsExpression($this->Subselect()); + $existsExpression->not = $not; + + $this->match(Lexer::T_CLOSE_PARENTHESIS); + + return $existsExpression; + } + + /** + * ComparisonOperator ::= "=" | "<" | "<=" | "<>" | ">" | ">=" | "!=" + * + * @return string + */ + public function ComparisonOperator() + { + switch ($this->_lexer->lookahead['value']) { + case '=': + $this->match(Lexer::T_EQUALS); + + return '='; + + case '<': + $this->match(Lexer::T_LOWER_THAN); + $operator = '<'; + + if ($this->_lexer->isNextToken(Lexer::T_EQUALS)) { + $this->match(Lexer::T_EQUALS); + $operator .= '='; + } else if ($this->_lexer->isNextToken(Lexer::T_GREATER_THAN)) { + $this->match(Lexer::T_GREATER_THAN); + $operator .= '>'; + } + + return $operator; + + case '>': + $this->match(Lexer::T_GREATER_THAN); + $operator = '>'; + + if ($this->_lexer->isNextToken(Lexer::T_EQUALS)) { + $this->match(Lexer::T_EQUALS); + $operator .= '='; + } + + return $operator; + + case '!': + $this->match(Lexer::T_NEGATE); + $this->match(Lexer::T_EQUALS); + + return '<>'; + + default: + $this->syntaxError('=, <, <=, <>, >, >=, !='); + } + } + + /** + * FunctionDeclaration ::= FunctionsReturningStrings | FunctionsReturningNumerics | FunctionsReturningDatetime + */ + public function FunctionDeclaration() + { + $token = $this->_lexer->lookahead; + $funcName = strtolower($token['value']); + + // Check for built-in functions first! + switch (true) { + case (isset(self::$_STRING_FUNCTIONS[$funcName])): + return $this->FunctionsReturningStrings(); + + case (isset(self::$_NUMERIC_FUNCTIONS[$funcName])): + return $this->FunctionsReturningNumerics(); + + case (isset(self::$_DATETIME_FUNCTIONS[$funcName])): + return $this->FunctionsReturningDatetime(); + + default: + return $this->CustomFunctionDeclaration(); + } + } + + /** + * Helper function for FunctionDeclaration grammar rule + */ + private function CustomFunctionDeclaration() + { + $token = $this->_lexer->lookahead; + $funcName = strtolower($token['value']); + + // Check for custom functions afterwards + $config = $this->_em->getConfiguration(); + + switch (true) { + case ($config->getCustomStringFunction($funcName) !== null): + return $this->CustomFunctionsReturningStrings(); + + case ($config->getCustomNumericFunction($funcName) !== null): + return $this->CustomFunctionsReturningNumerics(); + + case ($config->getCustomDatetimeFunction($funcName) !== null): + return $this->CustomFunctionsReturningDatetime(); + + default: + $this->syntaxError('known function', $token); + } + } + + /** + * FunctionsReturningNumerics ::= + * "LENGTH" "(" StringPrimary ")" | + * "LOCATE" "(" StringPrimary "," StringPrimary ["," SimpleArithmeticExpression]")" | + * "ABS" "(" SimpleArithmeticExpression ")" | + * "SQRT" "(" SimpleArithmeticExpression ")" | + * "MOD" "(" SimpleArithmeticExpression "," SimpleArithmeticExpression ")" | + * "SIZE" "(" CollectionValuedPathExpression ")" + */ + public function FunctionsReturningNumerics() + { + $funcNameLower = strtolower($this->_lexer->lookahead['value']); + $funcClass = self::$_NUMERIC_FUNCTIONS[$funcNameLower]; + + $function = new $funcClass($funcNameLower); + $function->parse($this); + + return $function; + } + + public function CustomFunctionsReturningNumerics() + { + // getCustomNumericFunction is case-insensitive + $funcName = strtolower($this->_lexer->lookahead['value']); + $funcClass = $this->_em->getConfiguration()->getCustomNumericFunction($funcName); + + $function = new $funcClass($funcName); + $function->parse($this); + + return $function; + } + + /** + * FunctionsReturningDateTime ::= "CURRENT_DATE" | "CURRENT_TIME" | "CURRENT_TIMESTAMP" + */ + public function FunctionsReturningDatetime() + { + $funcNameLower = strtolower($this->_lexer->lookahead['value']); + $funcClass = self::$_DATETIME_FUNCTIONS[$funcNameLower]; + + $function = new $funcClass($funcNameLower); + $function->parse($this); + + return $function; + } + + public function CustomFunctionsReturningDatetime() + { + // getCustomDatetimeFunction is case-insensitive + $funcName = $this->_lexer->lookahead['value']; + $funcClass = $this->_em->getConfiguration()->getCustomDatetimeFunction($funcName); + + $function = new $funcClass($funcName); + $function->parse($this); + + return $function; + } + + /** + * FunctionsReturningStrings ::= + * "CONCAT" "(" StringPrimary "," StringPrimary ")" | + * "SUBSTRING" "(" StringPrimary "," SimpleArithmeticExpression "," SimpleArithmeticExpression ")" | + * "TRIM" "(" [["LEADING" | "TRAILING" | "BOTH"] [char] "FROM"] StringPrimary ")" | + * "LOWER" "(" StringPrimary ")" | + * "UPPER" "(" StringPrimary ")" + */ + public function FunctionsReturningStrings() + { + $funcNameLower = strtolower($this->_lexer->lookahead['value']); + $funcClass = self::$_STRING_FUNCTIONS[$funcNameLower]; + + $function = new $funcClass($funcNameLower); + $function->parse($this); + + return $function; + } + + public function CustomFunctionsReturningStrings() + { + // getCustomStringFunction is case-insensitive + $funcName = $this->_lexer->lookahead['value']; + $funcClass = $this->_em->getConfiguration()->getCustomStringFunction($funcName); + + $function = new $funcClass($funcName); + $function->parse($this); + + return $function; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/ParserResult.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/ParserResult.php new file mode 100644 index 0000000..3e938a9 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/ParserResult.php @@ -0,0 +1,141 @@ +. + */ + +namespace Doctrine\ORM\Query; + +/** + * Encapsulates the resulting components from a DQL query parsing process that + * can be serialized. + * + * @author Guilherme Blanco + * @author Janne Vanhala + * @author Roman Borschel + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link http://www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + */ +class ParserResult +{ + /** + * The SQL executor used for executing the SQL. + * + * @var \Doctrine\ORM\Query\Exec\AbstractSqlExecutor + */ + private $_sqlExecutor; + + /** + * The ResultSetMapping that describes how to map the SQL result set. + * + * @var \Doctrine\ORM\Query\ResultSetMapping + */ + private $_resultSetMapping; + + /** + * The mappings of DQL parameter names/positions to SQL parameter positions. + * + * @var array + */ + private $_parameterMappings = array(); + + /** + * Initializes a new instance of the ParserResult class. + * The new instance is initialized with an empty ResultSetMapping. + */ + public function __construct() + { + $this->_resultSetMapping = new ResultSetMapping; + } + + /** + * Gets the ResultSetMapping for the parsed query. + * + * @return ResultSetMapping The result set mapping of the parsed query or NULL + * if the query is not a SELECT query. + */ + public function getResultSetMapping() + { + return $this->_resultSetMapping; + } + + /** + * Sets the ResultSetMapping of the parsed query. + * + * @param ResultSetMapping $rsm + */ + public function setResultSetMapping(ResultSetMapping $rsm) + { + $this->_resultSetMapping = $rsm; + } + + /** + * Sets the SQL executor that should be used for this ParserResult. + * + * @param \Doctrine\ORM\Query\Exec\AbstractSqlExecutor $executor + */ + public function setSqlExecutor($executor) + { + $this->_sqlExecutor = $executor; + } + + /** + * Gets the SQL executor used by this ParserResult. + * + * @return \Doctrine\ORM\Query\Exec\AbstractSqlExecutor + */ + public function getSqlExecutor() + { + return $this->_sqlExecutor; + } + + /** + * Adds a DQL to SQL parameter mapping. One DQL parameter name/position can map to + * several SQL parameter positions. + * + * @param string|integer $dqlPosition + * @param integer $sqlPosition + */ + public function addParameterMapping($dqlPosition, $sqlPosition) + { + $this->_parameterMappings[$dqlPosition][] = $sqlPosition; + } + + /** + * Gets all DQL to SQL parameter mappings. + * + * @return array The parameter mappings. + */ + public function getParameterMappings() + { + return $this->_parameterMappings; + } + + /** + * Gets the SQL parameter positions for a DQL parameter name/position. + * + * @param string|integer $dqlPosition The name or position of the DQL parameter. + * @return array The positions of the corresponding SQL parameters. + */ + public function getSqlParameterPositions($dqlPosition) + { + return $this->_parameterMappings[$dqlPosition]; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Printer.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Printer.php new file mode 100644 index 0000000..972ad51 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Printer.php @@ -0,0 +1,95 @@ +. + */ + +namespace Doctrine\ORM\Query; + +/** + * A parse tree printer for Doctrine Query Language parser. + * + * @author Janne Vanhala + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link http://www.phpdoctrine.org + * @since 2.0 + * @version $Revision$ + */ +class Printer +{ + /** + * Current indentation level + * + * @var int + */ + protected $_indent = 0; + + /** + * Defines whether parse tree is printed (default, false) or not (true). + * + * @var bool + */ + protected $_silent; + + /** + * Constructs a new parse tree printer. + * + * @param bool $silent Parse tree will not be printed if true. + */ + public function __construct($silent = false) + { + $this->_silent = $silent; + } + + /** + * Prints an opening parenthesis followed by production name and increases + * indentation level by one. + * + * This method is called before executing a production. + * + * @param string $name production name + */ + public function startProduction($name) + { + $this->println('(' . $name); + $this->_indent++; + } + + /** + * Decreases indentation level by one and prints a closing parenthesis. + * + * This method is called after executing a production. + */ + public function endProduction() + { + $this->_indent--; + $this->println(')'); + } + + /** + * Prints text indented with spaces depending on current indentation level. + * + * @param string $str text + */ + public function println($str) + { + if ( ! $this->_silent) { + echo str_repeat(' ', $this->_indent), $str, "\n"; + } + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php new file mode 100644 index 0000000..cd74f35 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php @@ -0,0 +1,154 @@ +. + */ + +namespace Doctrine\ORM\Query; + +use Doctrine\ORM\Query\AST\PathExpression; + +/** + * Description of QueryException + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class QueryException extends \Doctrine\ORM\ORMException +{ + public static function syntaxError($message) + { + return new self('[Syntax Error] ' . $message); + } + + public static function semanticalError($message) + { + return new self('[Semantical Error] ' . $message); + } + + public static function invalidLockMode() + { + return new self('Invalid lock mode hint provided.'); + } + + public static function invalidParameterType($expected, $received) + { + return new self('Invalid parameter type, ' . $received . ' given, but ' . $expected . ' expected.'); + } + + public static function invalidParameterPosition($pos) + { + return new self('Invalid parameter position: ' . $pos); + } + + public static function invalidParameterNumber() + { + return new self("Invalid parameter number: number of bound variables does not match number of tokens"); + } + + public static function invalidParameterFormat($value) + { + return new self('Invalid parameter format, '.$value.' given, but : or ? expected.'); + } + + public static function unknownParameter($key) + { + return new self("Invalid parameter: token ".$key." is not defined in the query."); + } + + public static function parameterTypeMissmatch() + { + return new self("DQL Query parameter and type numbers missmatch, but have to be exactly equal."); + } + + public static function invalidPathExpression($pathExpr) + { + return new self( + "Invalid PathExpression '" . $pathExpr->identificationVariable . "." . $pathExpr->field . "'." + ); + } + + public static function invalidLiteral($literal) { + return new self("Invalid literal '$literal'"); + } + + /** + * @param \Doctrine\ORM\Mapping\AssociationMapping $assoc + */ + public static function iterateWithFetchJoinCollectionNotAllowed($assoc) + { + return new self( + "Invalid query operation: Not allowed to iterate over fetch join collections ". + "in class ".$assoc['sourceEntity']." assocation ".$assoc['fieldName'] + ); + } + + public static function partialObjectsAreDangerous() + { + return new self( + "Loading partial objects is dangerous. Fetch full objects or consider " . + "using a different fetch mode. If you really want partial objects, " . + "set the doctrine.forcePartialLoad query hint to TRUE." + ); + } + + public static function overwritingJoinConditionsNotYetSupported($assoc) + { + return new self( + "Unsupported query operation: It is not yet possible to overwrite the join ". + "conditions in class ".$assoc['sourceEntityName']." assocation ".$assoc['fieldName'].". ". + "Use WITH to append additional join conditions to the association." + ); + } + + public static function associationPathInverseSideNotSupported() + { + return new self( + "A single-valued association path expression to an inverse side is not supported". + " in DQL queries. Use an explicit join instead." + ); + } + + public static function iterateWithFetchJoinNotAllowed($assoc) { + return new self( + "Iterate with fetch join in class " . $assoc['sourceEntity'] . + " using association " . $assoc['fieldName'] . " not allowed." + ); + } + + public static function associationPathCompositeKeyNotSupported() + { + return new self( + "A single-valued association path expression to an entity with a composite primary ". + "key is not supported. Explicitly name the components of the composite primary key ". + "in the query." + ); + } + + public static function instanceOfUnrelatedClass($className, $rootClass) + { + return new self("Cannot check if a child of '" . $rootClass . "' is instanceof '" . $className . "', " . + "inheritance hierachy exists between these two classes."); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/ResultSetMapping.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/ResultSetMapping.php new file mode 100644 index 0000000..32aa298 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/ResultSetMapping.php @@ -0,0 +1,485 @@ +. + */ + +namespace Doctrine\ORM\Query; + +/** + * A ResultSetMapping describes how a result set of an SQL query maps to a Doctrine result. + * + * IMPORTANT NOTE: + * The properties of this class are only public for fast internal READ access and to (drastically) + * reduce the size of serialized instances for more effective caching due to better (un-)serialization + * performance. + * + * Users should use the public methods. + * + * @author Roman Borschel + * @since 2.0 + * @todo Think about whether the number of lookup maps can be reduced. + */ +class ResultSetMapping +{ + /** + * @ignore + * @var boolean Whether the result is mixed (contains scalar values together with field values). + */ + public $isMixed = false; + + /** + * @ignore + * @var array Maps alias names to class names. + */ + public $aliasMap = array(); + + /** + * @ignore + * @var array Maps alias names to related association field names. + */ + public $relationMap = array(); + + /** + * @ignore + * @var array Maps alias names to parent alias names. + */ + public $parentAliasMap = array(); + + /** + * @ignore + * @var array Maps column names in the result set to field names for each class. + */ + public $fieldMappings = array(); + + /** + * @ignore + * @var array Maps column names in the result set to the alias/field name to use in the mapped result. + */ + public $scalarMappings = array(); + + /** + * @ignore + * @var array Maps column names in the result set to the alias/field type to use in the mapped result. + */ + public $typeMappings = array(); + + /** + * @ignore + * @var array Maps entities in the result set to the alias name to use in the mapped result. + */ + public $entityMappings = array(); + + /** + * @ignore + * @var array Maps column names of meta columns (foreign keys, discriminator columns, ...) to field names. + */ + public $metaMappings = array(); + + /** + * @ignore + * @var array Maps column names in the result set to the alias they belong to. + */ + public $columnOwnerMap = array(); + + /** + * @ignore + * @var array List of columns in the result set that are used as discriminator columns. + */ + public $discriminatorColumns = array(); + + /** + * @ignore + * @var array Maps alias names to field names that should be used for indexing. + */ + public $indexByMap = array(); + + /** + * @ignore + * @var array Map from column names to class names that declare the field the column is mapped to. + */ + public $declaringClasses = array(); + + /** + * @var array This is necessary to hydrate derivate foreign keys correctly. + */ + public $isIdentifierColumn = array(); + + /** + * Adds an entity result to this ResultSetMapping. + * + * @param string $class The class name of the entity. + * @param string $alias The alias for the class. The alias must be unique among all entity + * results or joined entity results within this ResultSetMapping. + * @param string $resultAlias The result alias with which the entity result should be + * placed in the result structure. + * @return ResultSetMapping This ResultSetMapping instance. + * @todo Rename: addRootEntity + */ + public function addEntityResult($class, $alias, $resultAlias = null) + { + $this->aliasMap[$alias] = $class; + $this->entityMappings[$alias] = $resultAlias; + + if ($resultAlias !== null) { + $this->isMixed = true; + } + + return $this; + } + + /** + * Sets a discriminator column for an entity result or joined entity result. + * The discriminator column will be used to determine the concrete class name to + * instantiate. + * + * @param string $alias The alias of the entity result or joined entity result the discriminator + * column should be used for. + * @param string $discrColumn The name of the discriminator column in the SQL result set. + * @return ResultSetMapping This ResultSetMapping instance. + * @todo Rename: addDiscriminatorColumn + */ + public function setDiscriminatorColumn($alias, $discrColumn) + { + $this->discriminatorColumns[$alias] = $discrColumn; + $this->columnOwnerMap[$discrColumn] = $alias; + + return $this; + } + + /** + * Sets a field to use for indexing an entity result or joined entity result. + * + * @param string $alias The alias of an entity result or joined entity result. + * @param string $fieldName The name of the field to use for indexing. + * @return ResultSetMapping This ResultSetMapping instance. + */ + public function addIndexBy($alias, $fieldName) + { + $found = false; + + foreach ($this->fieldMappings AS $columnName => $columnFieldName) { + if ( ! ($columnFieldName === $fieldName && $this->columnOwnerMap[$columnName] === $alias)) continue; + + $this->addIndexByColumn($alias, $columnName); + $found = true; + + break; + } + + /* TODO: check if this exception can be put back, for now it's gone because of assumptions made by some ORM internals + if ( ! $found) { + $message = sprintf( + 'Cannot add index by for DQL alias %s and field %s without calling addFieldResult() for them before.', + $alias, + $fieldName + ); + + throw new \LogicException($message); + } + */ + + return $this; + } + + /** + * Set to index by a scalar result column name + * + * @param $resultColumnName + * @return ResultSetMapping This ResultSetMapping instance. + */ + public function addIndexByScalar($resultColumnName) + { + $this->indexByMap['scalars'] = $resultColumnName; + + return $this; + } + + /** + * Sets a column to use for indexing an entity or joined entity result by the given alias name. + * + * @param $alias + * @param $resultColumnName + * @return ResultSetMapping This ResultSetMapping instance. + */ + public function addIndexByColumn($alias, $resultColumnName) + { + $this->indexByMap[$alias] = $resultColumnName; + + return $this; + } + + /** + * Checks whether an entity result or joined entity result with a given alias has + * a field set for indexing. + * + * @param string $alias + * @return boolean + * @todo Rename: isIndexed($alias) + */ + public function hasIndexBy($alias) + { + return isset($this->indexByMap[$alias]); + } + + /** + * Checks whether the column with the given name is mapped as a field result + * as part of an entity result or joined entity result. + * + * @param string $columnName The name of the column in the SQL result set. + * @return boolean + * @todo Rename: isField + */ + public function isFieldResult($columnName) + { + return isset($this->fieldMappings[$columnName]); + } + + /** + * Adds a field to the result that belongs to an entity or joined entity. + * + * @param string $alias The alias of the root entity or joined entity to which the field belongs. + * @param string $columnName The name of the column in the SQL result set. + * @param string $fieldName The name of the field on the declaring class. + * @param string $declaringClass The name of the class that declares/owns the specified field. + * When $alias refers to a superclass in a mapped hierarchy but + * the field $fieldName is defined on a subclass, specify that here. + * If not specified, the field is assumed to belong to the class + * designated by $alias. + * @return ResultSetMapping This ResultSetMapping instance. + * @todo Rename: addField + */ + public function addFieldResult($alias, $columnName, $fieldName, $declaringClass = null) + { + // column name (in result set) => field name + $this->fieldMappings[$columnName] = $fieldName; + // column name => alias of owner + $this->columnOwnerMap[$columnName] = $alias; + // field name => class name of declaring class + $this->declaringClasses[$columnName] = $declaringClass ?: $this->aliasMap[$alias]; + + if ( ! $this->isMixed && $this->scalarMappings) { + $this->isMixed = true; + } + + return $this; + } + + /** + * Adds a joined entity result. + * + * @param string $class The class name of the joined entity. + * @param string $alias The unique alias to use for the joined entity. + * @param string $parentAlias The alias of the entity result that is the parent of this joined result. + * @param object $relation The association field that connects the parent entity result with the joined entity result. + * @return ResultSetMapping This ResultSetMapping instance. + * @todo Rename: addJoinedEntity + */ + public function addJoinedEntityResult($class, $alias, $parentAlias, $relation) + { + $this->aliasMap[$alias] = $class; + $this->parentAliasMap[$alias] = $parentAlias; + $this->relationMap[$alias] = $relation; + + return $this; + } + + /** + * Adds a scalar result mapping. + * + * @param string $columnName The name of the column in the SQL result set. + * @param string $alias The result alias with which the scalar result should be placed in the result structure. + * @param string $type The column type + * + * @return ResultSetMapping This ResultSetMapping instance. + * + * @todo Rename: addScalar + */ + public function addScalarResult($columnName, $alias, $type = null) + { + $this->scalarMappings[$columnName] = $alias; + $this->typeMappings[$columnName] = $type ?: 'string'; + + if ( ! $this->isMixed && $this->fieldMappings) { + $this->isMixed = true; + } + + return $this; + } + + /** + * Checks whether a column with a given name is mapped as a scalar result. + * + * @param string $columName The name of the column in the SQL result set. + * @return boolean + * @todo Rename: isScalar + */ + public function isScalarResult($columnName) + { + return isset($this->scalarMappings[$columnName]); + } + + /** + * Gets the name of the class of an entity result or joined entity result, + * identified by the given unique alias. + * + * @param string $alias + * @return string + */ + public function getClassName($alias) + { + return $this->aliasMap[$alias]; + } + + /** + * Gets the field alias for a column that is mapped as a scalar value. + * + * @param string $columnName The name of the column in the SQL result set. + * @return string + */ + public function getScalarAlias($columnName) + { + return $this->scalarMappings[$columnName]; + } + + /** + * Gets the name of the class that owns a field mapping for the specified column. + * + * @param string $columnName + * @return string + */ + public function getDeclaringClass($columnName) + { + return $this->declaringClasses[$columnName]; + } + + /** + * + * @param string $alias + * @return AssociationMapping + */ + public function getRelation($alias) + { + return $this->relationMap[$alias]; + } + + /** + * + * @param string $alias + * @return boolean + */ + public function isRelation($alias) + { + return isset($this->relationMap[$alias]); + } + + /** + * Gets the alias of the class that owns a field mapping for the specified column. + * + * @param string $columnName + * @return string + */ + public function getEntityAlias($columnName) + { + return $this->columnOwnerMap[$columnName]; + } + + /** + * Gets the parent alias of the given alias. + * + * @param string $alias + * @return string + */ + public function getParentAlias($alias) + { + return $this->parentAliasMap[$alias]; + } + + /** + * Checks whether the given alias has a parent alias. + * + * @param string $alias + * @return boolean + */ + public function hasParentAlias($alias) + { + return isset($this->parentAliasMap[$alias]); + } + + /** + * Gets the field name for a column name. + * + * @param string $columnName + * @return string + */ + public function getFieldName($columnName) + { + return $this->fieldMappings[$columnName]; + } + + /** + * + * @return array + */ + public function getAliasMap() + { + return $this->aliasMap; + } + + /** + * Gets the number of different entities that appear in the mapped result. + * + * @return integer + */ + public function getEntityResultCount() + { + return count($this->aliasMap); + } + + /** + * Checks whether this ResultSetMapping defines a mixed result. + * Mixed results can only occur in object and array (graph) hydration. In such a + * case a mixed result means that scalar values are mixed with objects/array in + * the result. + * + * @return boolean + */ + public function isMixedResult() + { + return $this->isMixed; + } + + /** + * Adds a meta column (foreign key or discriminator column) to the result set. + * + * @param string $alias + * @param string $columnName + * @param string $fieldName + * @param bool + * @return ResultSetMapping This ResultSetMapping instance. + */ + public function addMetaResult($alias, $columnName, $fieldName, $isIdentifierColumn = false) + { + $this->metaMappings[$columnName] = $fieldName; + $this->columnOwnerMap[$columnName] = $alias; + + if ($isIdentifierColumn) { + $this->isIdentifierColumn[$alias][$columnName] = true; + } + + return $this; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php new file mode 100644 index 0000000..f84686a --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php @@ -0,0 +1,109 @@ +. + */ + +namespace Doctrine\ORM\Query; + +use Doctrine\ORM\EntityManager; +use Doctrine\ORM\Mapping\ClassMetadataInfo; + +/** + * A ResultSetMappingBuilder uses the EntityManager to automatically populate entity fields + * + * @author Michael Ridgway + * @since 2.1 + */ +class ResultSetMappingBuilder extends ResultSetMapping +{ + /** + * @var EntityManager + */ + private $em; + + /** + * @param EntityManager + */ + public function __construct(EntityManager $em) + { + $this->em = $em; + } + + /** + * Adds a root entity and all of its fields to the result set. + * + * @param string $class The class name of the root entity. + * @param string $alias The unique alias to use for the root entity. + * @param array $renamedColumns Columns that have been renamed (tableColumnName => queryColumnName) + */ + public function addRootEntityFromClassMetadata($class, $alias, $renamedColumns = array()) + { + $this->addEntityResult($class, $alias); + $this->addAllClassFields($class, $alias, $renamedColumns); + } + + /** + * Adds a joined entity and all of its fields to the result set. + * + * @param string $class The class name of the joined entity. + * @param string $alias The unique alias to use for the joined entity. + * @param string $parentAlias The alias of the entity result that is the parent of this joined result. + * @param object $relation The association field that connects the parent entity result with the joined entity result. + * @param array $renamedColumns Columns that have been renamed (tableColumnName => queryColumnName) + */ + public function addJoinedEntityFromClassMetadata($class, $alias, $parentAlias, $relation, $renamedColumns = array()) + { + $this->addJoinedEntityResult($class, $alias, $parentAlias, $relation); + $this->addAllClassFields($class, $alias, $renamedColumns); + } + + /** + * Adds all fields of the given class to the result set mapping (columns and meta fields) + */ + protected function addAllClassFields($class, $alias, $renamedColumns = array()) + { + $classMetadata = $this->em->getClassMetadata($class); + if ($classMetadata->isInheritanceTypeSingleTable() || $classMetadata->isInheritanceTypeJoined()) { + throw new \InvalidArgumentException('ResultSetMapping builder does not currently support inheritance.'); + } + $platform = $this->em->getConnection()->getDatabasePlatform(); + foreach ($classMetadata->getColumnNames() AS $columnName) { + $propertyName = $classMetadata->getFieldName($columnName); + if (isset($renamedColumns[$columnName])) { + $columnName = $renamedColumns[$columnName]; + } + $columnName = $platform->getSQLResultCasing($columnName); + if (isset($this->fieldMappings[$columnName])) { + throw new \InvalidArgumentException("The column '$columnName' conflicts with another column in the mapper."); + } + $this->addFieldResult($alias, $columnName, $propertyName); + } + foreach ($classMetadata->associationMappings AS $associationMapping) { + if ($associationMapping['isOwningSide'] && $associationMapping['type'] & ClassMetadataInfo::TO_ONE) { + foreach ($associationMapping['joinColumns'] AS $joinColumn) { + $columnName = $joinColumn['name']; + $renamedColumnName = isset($renamedColumns[$columnName]) ? $renamedColumns[$columnName] : $columnName; + $renamedColumnName = $platform->getSQLResultCasing($renamedColumnName); + if (isset($this->metaMappings[$renamedColumnName])) { + throw new \InvalidArgumentException("The column '$renamedColumnName' conflicts with another column in the mapper."); + } + $this->addMetaResult($alias, $renamedColumnName, $columnName); + } + } + } + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/SqlWalker.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/SqlWalker.php new file mode 100644 index 0000000..d883aea --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/SqlWalker.php @@ -0,0 +1,2159 @@ +. + */ + +namespace Doctrine\ORM\Query; + +use Doctrine\DBAL\LockMode, + Doctrine\DBAL\Types\Type, + Doctrine\ORM\Mapping\ClassMetadata, + Doctrine\ORM\Query, + Doctrine\ORM\Query\QueryException, + Doctrine\ORM\Mapping\ClassMetadataInfo; + +/** + * The SqlWalker is a TreeWalker that walks over a DQL AST and constructs + * the corresponding SQL. + * + * @author Guilherme Blanco + * @author Roman Borschel + * @author Benjamin Eberlei + * @author Alexander + * @since 2.0 + * @todo Rename: SQLWalker + */ +class SqlWalker implements TreeWalker +{ + /** + * @var string + */ + const HINT_DISTINCT = 'doctrine.distinct'; + + /** + * @var ResultSetMapping + */ + private $_rsm; + + /** Counters for generating unique column aliases, table aliases and parameter indexes. */ + private $_aliasCounter = 0; + private $_tableAliasCounter = 0; + private $_scalarResultCounter = 1; + private $_sqlParamIndex = 0; + + /** + * @var ParserResult + */ + private $_parserResult; + + /** + * @var EntityManager + */ + private $_em; + + /** + * @var \Doctrine\DBAL\Connection + */ + private $_conn; + + /** + * @var AbstractQuery + */ + private $_query; + + private $_tableAliasMap = array(); + + /** Map from result variable names to their SQL column alias names. */ + private $_scalarResultAliasMap = array(); + + /** + * Map from DQL-Alias + Field-Name to SQL Column Alias + * + * @var array + */ + private $_scalarFields = array(); + + /** Map of all components/classes that appear in the DQL query. */ + private $_queryComponents; + + /** A list of classes that appear in non-scalar SelectExpressions. */ + private $_selectedClasses = array(); + + /** + * The DQL alias of the root class of the currently traversed query. + */ + private $_rootAliases = array(); + + /** + * Flag that indicates whether to generate SQL table aliases in the SQL. + * These should only be generated for SELECT queries, not for UPDATE/DELETE. + */ + private $_useSqlTableAliases = true; + + /** + * The database platform abstraction. + * + * @var AbstractPlatform + */ + private $_platform; + + /** + * {@inheritDoc} + */ + public function __construct($query, $parserResult, array $queryComponents) + { + $this->_query = $query; + $this->_parserResult = $parserResult; + $this->_queryComponents = $queryComponents; + $this->_rsm = $parserResult->getResultSetMapping(); + $this->_em = $query->getEntityManager(); + $this->_conn = $this->_em->getConnection(); + $this->_platform = $this->_conn->getDatabasePlatform(); + } + + /** + * Gets the Query instance used by the walker. + * + * @return Query. + */ + public function getQuery() + { + return $this->_query; + } + + /** + * Gets the Connection used by the walker. + * + * @return Connection + */ + public function getConnection() + { + return $this->_conn; + } + + /** + * Gets the EntityManager used by the walker. + * + * @return EntityManager + */ + public function getEntityManager() + { + return $this->_em; + } + + /** + * Gets the information about a single query component. + * + * @param string $dqlAlias The DQL alias. + * @return array + */ + public function getQueryComponent($dqlAlias) + { + return $this->_queryComponents[$dqlAlias]; + } + + /** + * Gets an executor that can be used to execute the result of this walker. + * + * @return AbstractExecutor + */ + public function getExecutor($AST) + { + switch (true) { + case ($AST instanceof AST\DeleteStatement): + $primaryClass = $this->_em->getClassMetadata($AST->deleteClause->abstractSchemaName); + + return ($primaryClass->isInheritanceTypeJoined()) + ? new Exec\MultiTableDeleteExecutor($AST, $this) + : new Exec\SingleTableDeleteUpdateExecutor($AST, $this); + + case ($AST instanceof AST\UpdateStatement): + $primaryClass = $this->_em->getClassMetadata($AST->updateClause->abstractSchemaName); + + return ($primaryClass->isInheritanceTypeJoined()) + ? new Exec\MultiTableUpdateExecutor($AST, $this) + : new Exec\SingleTableDeleteUpdateExecutor($AST, $this); + + default: + return new Exec\SingleSelectExecutor($AST, $this); + } + } + + /** + * Generates a unique, short SQL table alias. + * + * @param string $tableName Table name + * @param string $dqlAlias The DQL alias. + * @return string Generated table alias. + */ + public function getSQLTableAlias($tableName, $dqlAlias = '') + { + $tableName .= ($dqlAlias) ? '@[' . $dqlAlias . ']' : ''; + + if ( ! isset($this->_tableAliasMap[$tableName])) { + $this->_tableAliasMap[$tableName] = strtolower(substr($tableName, 0, 1)) . $this->_tableAliasCounter++ . '_'; + } + + return $this->_tableAliasMap[$tableName]; + } + + /** + * Forces the SqlWalker to use a specific alias for a table name, rather than + * generating an alias on its own. + * + * @param string $tableName + * @param string $alias + * @param string $dqlAlias + * @return string + */ + public function setSQLTableAlias($tableName, $alias, $dqlAlias = '') + { + $tableName .= ($dqlAlias) ? '@[' . $dqlAlias . ']' : ''; + + $this->_tableAliasMap[$tableName] = $alias; + + return $alias; + } + + /** + * Gets an SQL column alias for a column name. + * + * @param string $columnName + * @return string + */ + public function getSQLColumnAlias($columnName) + { + // Trim the column alias to the maximum identifier length of the platform. + // If the alias is to long, characters are cut off from the beginning. + return $this->_platform->getSQLResultCasing( + substr($columnName . $this->_aliasCounter++, -$this->_platform->getMaxIdentifierLength()) + ); + } + + /** + * Generates the SQL JOINs that are necessary for Class Table Inheritance + * for the given class. + * + * @param ClassMetadata $class The class for which to generate the joins. + * @param string $dqlAlias The DQL alias of the class. + * @return string The SQL. + */ + private function _generateClassTableInheritanceJoins($class, $dqlAlias) + { + $sql = ''; + + $baseTableAlias = $this->getSQLTableAlias($class->getTableName(), $dqlAlias); + + // INNER JOIN parent class tables + foreach ($class->parentClasses as $parentClassName) { + $parentClass = $this->_em->getClassMetadata($parentClassName); + $tableAlias = $this->getSQLTableAlias($parentClass->getTableName(), $dqlAlias); + + // If this is a joined association we must use left joins to preserve the correct result. + $sql .= isset($this->_queryComponents[$dqlAlias]['relation']) ? ' LEFT ' : ' INNER '; + $sql .= 'JOIN ' . $parentClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON '; + + $sqlParts = array(); + + foreach ($class->getQuotedIdentifierColumnNames($this->_platform) as $columnName) { + $sqlParts[] = $baseTableAlias . '.' . $columnName . ' = ' . $tableAlias . '.' . $columnName; + } + + // Add filters on the root class + if ($filterSql = $this->generateFilterConditionSQL($parentClass, $tableAlias)) { + $sqlParts[] = $filterSql; + } + + $sql .= implode(' AND ', $sqlParts); + } + + // Ignore subclassing inclusion if partial objects is disallowed + if ($this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD)) { + return $sql; + } + + // LEFT JOIN child class tables + foreach ($class->subClasses as $subClassName) { + $subClass = $this->_em->getClassMetadata($subClassName); + $tableAlias = $this->getSQLTableAlias($subClass->getTableName(), $dqlAlias); + + $sql .= ' LEFT JOIN ' . $subClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON '; + + $sqlParts = array(); + + foreach ($subClass->getQuotedIdentifierColumnNames($this->_platform) as $columnName) { + $sqlParts[] = $baseTableAlias . '.' . $columnName . ' = ' . $tableAlias . '.' . $columnName; + } + + $sql .= implode(' AND ', $sqlParts); + } + + return $sql; + } + + private function _generateOrderedCollectionOrderByItems() + { + $sqlParts = array(); + + foreach ($this->_selectedClasses AS $selectedClass) { + $dqlAlias = $selectedClass['dqlAlias']; + $qComp = $this->_queryComponents[$dqlAlias]; + + if ( ! isset($qComp['relation']['orderBy'])) continue; + + foreach ($qComp['relation']['orderBy'] AS $fieldName => $orientation) { + $columnName = $qComp['metadata']->getQuotedColumnName($fieldName, $this->_platform); + $tableName = ($qComp['metadata']->isInheritanceTypeJoined()) + ? $this->_em->getUnitOfWork()->getEntityPersister($qComp['metadata']->name)->getOwningTable($fieldName) + : $qComp['metadata']->getTableName(); + + $sqlParts[] = $this->getSQLTableAlias($tableName, $dqlAlias) . '.' . $columnName . ' ' . $orientation; + } + } + + return implode(', ', $sqlParts); + } + + /** + * Generates a discriminator column SQL condition for the class with the given DQL alias. + * + * @param array $dqlAliases List of root DQL aliases to inspect for discriminator restrictions. + * @return string + */ + private function _generateDiscriminatorColumnConditionSQL(array $dqlAliases) + { + $sqlParts = array(); + + foreach ($dqlAliases as $dqlAlias) { + $class = $this->_queryComponents[$dqlAlias]['metadata']; + + if ( ! $class->isInheritanceTypeSingleTable()) continue; + + $conn = $this->_em->getConnection(); + $values = array(); + + if ($class->discriminatorValue !== null) { // discrimnators can be 0 + $values[] = $conn->quote($class->discriminatorValue); + } + + foreach ($class->subClasses as $subclassName) { + $values[] = $conn->quote($this->_em->getClassMetadata($subclassName)->discriminatorValue); + } + + $sqlParts[] = (($this->_useSqlTableAliases) ? $this->getSQLTableAlias($class->getTableName(), $dqlAlias) . '.' : '') + . $class->discriminatorColumn['name'] . ' IN (' . implode(', ', $values) . ')'; + } + + $sql = implode(' AND ', $sqlParts); + + return (count($sqlParts) > 1) ? '(' . $sql . ')' : $sql; + } + + /** + * Generates the filter SQL for a given entity and table alias. + * + * @param ClassMetadata $targetEntity Metadata of the target entity. + * @param string $targetTableAlias The table alias of the joined/selected table. + * + * @return string The SQL query part to add to a query. + */ + private function generateFilterConditionSQL(ClassMetadata $targetEntity, $targetTableAlias) + { + if (!$this->_em->hasFilters()) { + return ''; + } + + switch($targetEntity->inheritanceType) { + case ClassMetadata::INHERITANCE_TYPE_NONE: + break; + case ClassMetadata::INHERITANCE_TYPE_JOINED: + // The classes in the inheritance will be added to the query one by one, + // but only the root node is getting filtered + if ($targetEntity->name !== $targetEntity->rootEntityName) { + return ''; + } + break; + case ClassMetadata::INHERITANCE_TYPE_SINGLE_TABLE: + // With STI the table will only be queried once, make sure that the filters + // are added to the root entity + $targetEntity = $this->_em->getClassMetadata($targetEntity->rootEntityName); + break; + default: + //@todo: throw exception? + return ''; + break; + } + + $filterClauses = array(); + foreach ($this->_em->getFilters()->getEnabledFilters() as $filter) { + if ('' !== $filterExpr = $filter->addFilterConstraint($targetEntity, $targetTableAlias)) { + $filterClauses[] = '(' . $filterExpr . ')'; + } + } + + return implode(' AND ', $filterClauses); + } + /** + * Walks down a SelectStatement AST node, thereby generating the appropriate SQL. + * + * @return string The SQL. + */ + public function walkSelectStatement(AST\SelectStatement $AST) + { + $sql = $this->walkSelectClause($AST->selectClause); + $sql .= $this->walkFromClause($AST->fromClause); + $sql .= $this->walkWhereClause($AST->whereClause); + $sql .= $AST->groupByClause ? $this->walkGroupByClause($AST->groupByClause) : ''; + $sql .= $AST->havingClause ? $this->walkHavingClause($AST->havingClause) : ''; + + if (($orderByClause = $AST->orderByClause) !== null) { + $sql .= $AST->orderByClause ? $this->walkOrderByClause($AST->orderByClause) : ''; + } else if (($orderBySql = $this->_generateOrderedCollectionOrderByItems()) !== '') { + $sql .= ' ORDER BY ' . $orderBySql; + } + + $sql = $this->_platform->modifyLimitQuery( + $sql, $this->_query->getMaxResults(), $this->_query->getFirstResult() + ); + + if (($lockMode = $this->_query->getHint(Query::HINT_LOCK_MODE)) !== false) { + switch ($lockMode) { + case LockMode::PESSIMISTIC_READ: + $sql .= ' ' . $this->_platform->getReadLockSQL(); + break; + + case LockMode::PESSIMISTIC_WRITE: + $sql .= ' ' . $this->_platform->getWriteLockSQL(); + break; + + case LockMode::OPTIMISTIC: + foreach ($this->_selectedClasses AS $selectedClass) { + if ( ! $selectedClass['class']->isVersioned) { + throw \Doctrine\ORM\OptimisticLockException::lockFailed($selectedClass['class']->name); + } + } + break; + case LockMode::NONE: + break; + + default: + throw \Doctrine\ORM\Query\QueryException::invalidLockMode(); + } + } + + return $sql; + } + + /** + * Walks down an UpdateStatement AST node, thereby generating the appropriate SQL. + * + * @param UpdateStatement + * @return string The SQL. + */ + public function walkUpdateStatement(AST\UpdateStatement $AST) + { + $this->_useSqlTableAliases = false; + + return $this->walkUpdateClause($AST->updateClause) + . $this->walkWhereClause($AST->whereClause); + } + + /** + * Walks down a DeleteStatement AST node, thereby generating the appropriate SQL. + * + * @param DeleteStatement + * @return string The SQL. + */ + public function walkDeleteStatement(AST\DeleteStatement $AST) + { + $this->_useSqlTableAliases = false; + + return $this->walkDeleteClause($AST->deleteClause) + . $this->walkWhereClause($AST->whereClause); + } + + /** + * Walks down an IdentificationVariable AST node, thereby generating the appropriate SQL. + * This one differs of ->walkIdentificationVariable() because it generates the entity identifiers. + * + * @param string $identVariable + * @return string + */ + public function walkEntityIdentificationVariable($identVariable) + { + $class = $this->_queryComponents[$identVariable]['metadata']; + $tableAlias = $this->getSQLTableAlias($class->getTableName(), $identVariable); + $sqlParts = array(); + + foreach ($class->getQuotedIdentifierColumnNames($this->_platform) as $columnName) { + $sqlParts[] = $tableAlias . '.' . $columnName; + } + + return implode(', ', $sqlParts); + } + + /** + * Walks down an IdentificationVariable (no AST node associated), thereby generating the SQL. + * + * @param string $identificationVariable + * @param string $fieldName + * @return string The SQL. + */ + public function walkIdentificationVariable($identificationVariable, $fieldName = null) + { + $class = $this->_queryComponents[$identificationVariable]['metadata']; + + if ( + $fieldName !== null && $class->isInheritanceTypeJoined() && + isset($class->fieldMappings[$fieldName]['inherited']) + ) { + $class = $this->_em->getClassMetadata($class->fieldMappings[$fieldName]['inherited']); + } + + return $this->getSQLTableAlias($class->getTableName(), $identificationVariable); + } + + /** + * Walks down a PathExpression AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkPathExpression($pathExpr) + { + $sql = ''; + + switch ($pathExpr->type) { + case AST\PathExpression::TYPE_STATE_FIELD: + $fieldName = $pathExpr->field; + $dqlAlias = $pathExpr->identificationVariable; + $class = $this->_queryComponents[$dqlAlias]['metadata']; + + if ($this->_useSqlTableAliases) { + $sql .= $this->walkIdentificationVariable($dqlAlias, $fieldName) . '.'; + } + + $sql .= $class->getQuotedColumnName($fieldName, $this->_platform); + break; + + case AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION: + // 1- the owning side: + // Just use the foreign key, i.e. u.group_id + $fieldName = $pathExpr->field; + $dqlAlias = $pathExpr->identificationVariable; + $class = $this->_queryComponents[$dqlAlias]['metadata']; + + if (isset($class->associationMappings[$fieldName]['inherited'])) { + $class = $this->_em->getClassMetadata($class->associationMappings[$fieldName]['inherited']); + } + + $assoc = $class->associationMappings[$fieldName]; + + if ( ! $assoc['isOwningSide']) { + throw QueryException::associationPathInverseSideNotSupported(); + } + + // COMPOSITE KEYS NOT (YET?) SUPPORTED + if (count($assoc['sourceToTargetKeyColumns']) > 1) { + throw QueryException::associationPathCompositeKeyNotSupported(); + } + + if ($this->_useSqlTableAliases) { + $sql .= $this->getSQLTableAlias($class->getTableName(), $dqlAlias) . '.'; + } + + $sql .= reset($assoc['targetToSourceKeyColumns']); + break; + + default: + throw QueryException::invalidPathExpression($pathExpr); + } + + return $sql; + } + + /** + * Walks down a SelectClause AST node, thereby generating the appropriate SQL. + * + * @param $selectClause + * @return string The SQL. + */ + public function walkSelectClause($selectClause) + { + $sql = 'SELECT ' . (($selectClause->isDistinct) ? 'DISTINCT ' : ''); + $sqlSelectExpressions = array_filter(array_map(array($this, 'walkSelectExpression'), $selectClause->selectExpressions)); + + if ($this->_query->getHint(Query::HINT_INTERNAL_ITERATION) == true && $selectClause->isDistinct) { + $this->_query->setHint(self::HINT_DISTINCT, true); + } + + $addMetaColumns = ! $this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD) && + $this->_query->getHydrationMode() == Query::HYDRATE_OBJECT + || + $this->_query->getHydrationMode() != Query::HYDRATE_OBJECT && + $this->_query->getHint(Query::HINT_INCLUDE_META_COLUMNS); + + foreach ($this->_selectedClasses as $selectedClass) { + $class = $selectedClass['class']; + $dqlAlias = $selectedClass['dqlAlias']; + $resultAlias = $selectedClass['resultAlias']; + + // Register as entity or joined entity result + if ($this->_queryComponents[$dqlAlias]['relation'] === null) { + $this->_rsm->addEntityResult($class->name, $dqlAlias, $resultAlias); + } else { + $this->_rsm->addJoinedEntityResult( + $class->name, + $dqlAlias, + $this->_queryComponents[$dqlAlias]['parent'], + $this->_queryComponents[$dqlAlias]['relation']['fieldName'] + ); + } + + if ($class->isInheritanceTypeSingleTable() || $class->isInheritanceTypeJoined()) { + // Add discriminator columns to SQL + $rootClass = $this->_em->getClassMetadata($class->rootEntityName); + $tblAlias = $this->getSQLTableAlias($rootClass->getTableName(), $dqlAlias); + $discrColumn = $rootClass->discriminatorColumn; + $columnAlias = $this->getSQLColumnAlias($discrColumn['name']); + + $sqlSelectExpressions[] = $tblAlias . '.' . $discrColumn['name'] . ' AS ' . $columnAlias; + + $this->_rsm->setDiscriminatorColumn($dqlAlias, $columnAlias); + $this->_rsm->addMetaResult($dqlAlias, $columnAlias, $discrColumn['fieldName']); + } + + // Add foreign key columns to SQL, if necessary + if ( ! $addMetaColumns && ! $class->containsForeignIdentifier) { + continue; + } + + // Add foreign key columns of class and also parent classes + foreach ($class->associationMappings as $assoc) { + if ( ! ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE)) { + continue; + } else if ( !$addMetaColumns && !isset($assoc['id'])) { + continue; + } + + $owningClass = (isset($assoc['inherited'])) ? $this->_em->getClassMetadata($assoc['inherited']) : $class; + $sqlTableAlias = $this->getSQLTableAlias($owningClass->getTableName(), $dqlAlias); + + foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) { + $columnAlias = $this->getSQLColumnAlias($srcColumn); + + $sqlSelectExpressions[] = $sqlTableAlias . '.' . $srcColumn . ' AS ' . $columnAlias; + + $this->_rsm->addMetaResult($dqlAlias, $columnAlias, $srcColumn, (isset($assoc['id']) && $assoc['id'] === true)); + } + } + + // Add foreign key columns to SQL, if necessary + if ( ! $addMetaColumns) { + continue; + } + + // Add foreign key columns of subclasses + foreach ($class->subClasses as $subClassName) { + $subClass = $this->_em->getClassMetadata($subClassName); + $sqlTableAlias = $this->getSQLTableAlias($subClass->getTableName(), $dqlAlias); + + foreach ($subClass->associationMappings as $assoc) { + // Skip if association is inherited + if (isset($assoc['inherited'])) continue; + + if ( ! ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE)) continue; + + foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) { + $columnAlias = $this->getSQLColumnAlias($srcColumn); + + $sqlSelectExpressions[] = $sqlTableAlias . '.' . $srcColumn . ' AS ' . $columnAlias; + + $this->_rsm->addMetaResult($dqlAlias, $columnAlias, $srcColumn); + } + } + } + } + + $sql .= implode(', ', $sqlSelectExpressions); + + return $sql; + } + + /** + * Walks down a FromClause AST node, thereby generating the appropriate SQL. + * + * @return string The SQL. + */ + public function walkFromClause($fromClause) + { + $identificationVarDecls = $fromClause->identificationVariableDeclarations; + $sqlParts = array(); + + foreach ($identificationVarDecls as $identificationVariableDecl) { + $sql = ''; + + $rangeDecl = $identificationVariableDecl->rangeVariableDeclaration; + $dqlAlias = $rangeDecl->aliasIdentificationVariable; + + $this->_rootAliases[] = $dqlAlias; + + $class = $this->_em->getClassMetadata($rangeDecl->abstractSchemaName); + $sql .= $class->getQuotedTableName($this->_platform) . ' ' + . $this->getSQLTableAlias($class->getTableName(), $dqlAlias); + + if ($class->isInheritanceTypeJoined()) { + $sql .= $this->_generateClassTableInheritanceJoins($class, $dqlAlias); + } + + foreach ($identificationVariableDecl->joinVariableDeclarations as $joinVarDecl) { + $sql .= $this->walkJoinVariableDeclaration($joinVarDecl); + } + + if ($identificationVariableDecl->indexBy) { + $alias = $identificationVariableDecl->indexBy->simpleStateFieldPathExpression->identificationVariable; + $field = $identificationVariableDecl->indexBy->simpleStateFieldPathExpression->field; + + if (isset($this->_scalarFields[$alias][$field])) { + $this->_rsm->addIndexByScalar($this->_scalarFields[$alias][$field]); + } else { + $this->_rsm->addIndexBy( + $identificationVariableDecl->indexBy->simpleStateFieldPathExpression->identificationVariable, + $identificationVariableDecl->indexBy->simpleStateFieldPathExpression->field + ); + } + } + + $sqlParts[] = $this->_platform->appendLockHint($sql, $this->_query->getHint(Query::HINT_LOCK_MODE)); + } + + return ' FROM ' . implode(', ', $sqlParts); + } + + /** + * Walks down a FunctionNode AST node, thereby generating the appropriate SQL. + * + * @return string The SQL. + */ + public function walkFunction($function) + { + return $function->getSql($this); + } + + /** + * Walks down an OrderByClause AST node, thereby generating the appropriate SQL. + * + * @param OrderByClause + * @return string The SQL. + */ + public function walkOrderByClause($orderByClause) + { + $orderByItems = array_map(array($this, 'walkOrderByItem'), $orderByClause->orderByItems); + + if (($collectionOrderByItems = $this->_generateOrderedCollectionOrderByItems()) !== '') { + $orderByItems = array_merge($orderByItems, (array) $collectionOrderByItems); + } + + return ' ORDER BY ' . implode(', ', $orderByItems); + } + + /** + * Walks down an OrderByItem AST node, thereby generating the appropriate SQL. + * + * @param OrderByItem + * @return string The SQL. + */ + public function walkOrderByItem($orderByItem) + { + $expr = $orderByItem->expression; + $sql = ($expr instanceof AST\PathExpression) + ? $this->walkPathExpression($expr) + : $this->walkResultVariable($this->_queryComponents[$expr]['token']['value']); + + return $sql . ' ' . strtoupper($orderByItem->type); + } + + /** + * Walks down a HavingClause AST node, thereby generating the appropriate SQL. + * + * @param HavingClause + * @return string The SQL. + */ + public function walkHavingClause($havingClause) + { + return ' HAVING ' . $this->walkConditionalExpression($havingClause->conditionalExpression); + } + + /** + * Walks down a JoinVariableDeclaration AST node and creates the corresponding SQL. + * + * @param JoinVariableDeclaration $joinVarDecl + * @return string The SQL. + */ + public function walkJoinVariableDeclaration($joinVarDecl) + { + $join = $joinVarDecl->join; + $joinType = $join->joinType; + $sql = ($joinType == AST\Join::JOIN_TYPE_LEFT || $joinType == AST\Join::JOIN_TYPE_LEFTOUTER) + ? ' LEFT JOIN ' + : ' INNER JOIN '; + + if ($joinVarDecl->indexBy) { + // For Many-To-One or One-To-One associations this obviously makes no sense, but is ignored silently. + $this->_rsm->addIndexBy( + $joinVarDecl->indexBy->simpleStateFieldPathExpression->identificationVariable, + $joinVarDecl->indexBy->simpleStateFieldPathExpression->field + ); + } + + $joinAssocPathExpr = $join->joinAssociationPathExpression; + $joinedDqlAlias = $join->aliasIdentificationVariable; + + $relation = $this->_queryComponents[$joinedDqlAlias]['relation']; + $targetClass = $this->_em->getClassMetadata($relation['targetEntity']); + $sourceClass = $this->_em->getClassMetadata($relation['sourceEntity']); + $targetTableName = $targetClass->getQuotedTableName($this->_platform); + + $targetTableAlias = $this->getSQLTableAlias($targetClass->getTableName(), $joinedDqlAlias); + $sourceTableAlias = $this->getSQLTableAlias($sourceClass->getTableName(), $joinAssocPathExpr->identificationVariable); + + // Ensure we got the owning side, since it has all mapping info + $assoc = ( ! $relation['isOwningSide']) ? $targetClass->associationMappings[$relation['mappedBy']] : $relation; + if ($this->_query->getHint(Query::HINT_INTERNAL_ITERATION) == true && (!$this->_query->getHint(self::HINT_DISTINCT) || isset($this->_selectedClasses[$joinedDqlAlias]))) { + if ($relation['type'] == ClassMetadata::ONE_TO_MANY || $relation['type'] == ClassMetadata::MANY_TO_MANY) { + throw QueryException::iterateWithFetchJoinNotAllowed($assoc); + } + } + + if ($joinVarDecl->indexBy) { + // For Many-To-One or One-To-One associations this obviously makes no sense, but is ignored silently. + $this->_rsm->addIndexBy( + $joinVarDecl->indexBy->simpleStateFieldPathExpression->identificationVariable, + $joinVarDecl->indexBy->simpleStateFieldPathExpression->field + ); + } else if (isset($relation['indexBy'])) { + $this->_rsm->addIndexBy($joinedDqlAlias, $relation['indexBy']); + } + + // This condition is not checking ClassMetadata::MANY_TO_ONE, because by definition it cannot + // be the owning side and previously we ensured that $assoc is always the owning side of the associations. + // The owning side is necessary at this point because only it contains the JoinColumn information. + if ($assoc['type'] & ClassMetadata::TO_ONE) { + $sql .= $targetTableName . ' ' . $targetTableAlias . ' ON '; + $first = true; + + foreach ($assoc['sourceToTargetKeyColumns'] as $sourceColumn => $targetColumn) { + if ( ! $first) $sql .= ' AND '; else $first = false; + + if ($relation['isOwningSide']) { + if ($targetClass->containsForeignIdentifier && !isset($targetClass->fieldNames[$targetColumn])) { + $quotedTargetColumn = $targetColumn; // Join columns cannot be quoted. + } else { + $quotedTargetColumn = $targetClass->getQuotedColumnName($targetClass->fieldNames[$targetColumn], $this->_platform); + } + $sql .= $sourceTableAlias . '.' . $sourceColumn . ' = ' . $targetTableAlias . '.' . $quotedTargetColumn; + } else { + if ($sourceClass->containsForeignIdentifier && !isset($sourceClass->fieldNames[$targetColumn])) { + $quotedTargetColumn = $targetColumn; // Join columns cannot be quoted. + } else { + $quotedTargetColumn = $sourceClass->getQuotedColumnName($sourceClass->fieldNames[$targetColumn], $this->_platform); + } + $sql .= $sourceTableAlias . '.' . $quotedTargetColumn . ' = ' . $targetTableAlias . '.' . $sourceColumn; + } + } + + } else if ($assoc['type'] == ClassMetadata::MANY_TO_MANY) { + // Join relation table + $joinTable = $assoc['joinTable']; + $joinTableAlias = $this->getSQLTableAlias($joinTable['name'], $joinedDqlAlias); + $sql .= $sourceClass->getQuotedJoinTableName($assoc, $this->_platform) . ' ' . $joinTableAlias . ' ON '; + + $first = true; + if ($relation['isOwningSide']) { + foreach ($assoc['relationToSourceKeyColumns'] as $relationColumn => $sourceColumn) { + if ( ! $first) $sql .= ' AND '; else $first = false; + + if ($sourceClass->containsForeignIdentifier && !isset($sourceClass->fieldNames[$sourceColumn])) { + $quotedTargetColumn = $sourceColumn; // Join columns cannot be quoted. + } else { + $quotedTargetColumn = $sourceClass->getQuotedColumnName($sourceClass->fieldNames[$sourceColumn], $this->_platform); + } + + $sql .= $sourceTableAlias . '.' . $quotedTargetColumn . ' = ' . $joinTableAlias . '.' . $relationColumn; + } + } else { + foreach ($assoc['relationToTargetKeyColumns'] as $relationColumn => $targetColumn) { + if ( ! $first) $sql .= ' AND '; else $first = false; + + if ($sourceClass->containsForeignIdentifier && !isset($sourceClass->fieldNames[$targetColumn])) { + $quotedTargetColumn = $targetColumn; // Join columns cannot be quoted. + } else { + $quotedTargetColumn = $sourceClass->getQuotedColumnName($sourceClass->fieldNames[$targetColumn], $this->_platform); + } + + $sql .= $sourceTableAlias . '.' . $quotedTargetColumn . ' = ' . $joinTableAlias . '.' . $relationColumn; + } + } + + // Join target table + $sql .= ($joinType == AST\Join::JOIN_TYPE_LEFT || $joinType == AST\Join::JOIN_TYPE_LEFTOUTER) ? ' LEFT JOIN ' : ' INNER JOIN '; + $sql .= $targetTableName . ' ' . $targetTableAlias . ' ON '; + + $first = true; + if ($relation['isOwningSide']) { + foreach ($assoc['relationToTargetKeyColumns'] as $relationColumn => $targetColumn) { + if ( ! $first) $sql .= ' AND '; else $first = false; + + if ($targetClass->containsForeignIdentifier && !isset($targetClass->fieldNames[$targetColumn])) { + $quotedTargetColumn = $targetColumn; // Join columns cannot be quoted. + } else { + $quotedTargetColumn = $targetClass->getQuotedColumnName($targetClass->fieldNames[$targetColumn], $this->_platform); + } + + $sql .= $targetTableAlias . '.' . $quotedTargetColumn . ' = ' . $joinTableAlias . '.' . $relationColumn; + } + } else { + foreach ($assoc['relationToSourceKeyColumns'] as $relationColumn => $sourceColumn) { + if ( ! $first) $sql .= ' AND '; else $first = false; + + if ($targetClass->containsForeignIdentifier && !isset($targetClass->fieldNames[$sourceColumn])) { + $quotedTargetColumn = $sourceColumn; // Join columns cannot be quoted. + } else { + $quotedTargetColumn = $targetClass->getQuotedColumnName($targetClass->fieldNames[$sourceColumn], $this->_platform); + } + + $sql .= $targetTableAlias . '.' . $quotedTargetColumn . ' = ' . $joinTableAlias . '.' . $relationColumn; + } + } + } + + // Apply the filters + if ($filterExpr = $this->generateFilterConditionSQL($targetClass, $targetTableAlias)) { + $sql .= ' AND ' . $filterExpr; + } + + // Handle WITH clause + if (($condExpr = $join->conditionalExpression) !== null) { + // Phase 2 AST optimization: Skip processment of ConditionalExpression + // if only one ConditionalTerm is defined + $sql .= ' AND (' . $this->walkConditionalExpression($condExpr) . ')'; + } + + $discrSql = $this->_generateDiscriminatorColumnConditionSQL(array($joinedDqlAlias)); + + if ($discrSql) { + $sql .= ' AND ' . $discrSql; + } + + // FIXME: these should either be nested or all forced to be left joins (DDC-XXX) + if ($targetClass->isInheritanceTypeJoined()) { + $sql .= $this->_generateClassTableInheritanceJoins($targetClass, $joinedDqlAlias); + } + + return $sql; + } + + /** + * Walks down a CaseExpression AST node and generates the corresponding SQL. + * + * @param CoalesceExpression|NullIfExpression|GeneralCaseExpression|SimpleCaseExpression $expression + * @return string The SQL. + */ + public function walkCaseExpression($expression) + { + switch (true) { + case ($expression instanceof AST\CoalesceExpression): + return $this->walkCoalesceExpression($expression); + + case ($expression instanceof AST\NullIfExpression): + return $this->walkNullIfExpression($expression); + + case ($expression instanceof AST\GeneralCaseExpression): + return $this->walkGeneralCaseExpression($expression); + + case ($expression instanceof AST\SimpleCaseExpression): + return $this->walkSimpleCaseExpression($expression); + + default: + return ''; + } + } + + /** + * Walks down a CoalesceExpression AST node and generates the corresponding SQL. + * + * @param CoalesceExpression $coalesceExpression + * @return string The SQL. + */ + public function walkCoalesceExpression($coalesceExpression) + { + $sql = 'COALESCE('; + + $scalarExpressions = array(); + + foreach ($coalesceExpression->scalarExpressions as $scalarExpression) { + $scalarExpressions[] = $this->walkSimpleArithmeticExpression($scalarExpression); + } + + $sql .= implode(', ', $scalarExpressions) . ')'; + + return $sql; + } + + /** + * Walks down a NullIfExpression AST node and generates the corresponding SQL. + * + * @param NullIfExpression $nullIfExpression + * @return string The SQL. + */ + public function walkNullIfExpression($nullIfExpression) + { + $firstExpression = is_string($nullIfExpression->firstExpression) + ? $this->_conn->quote($nullIfExpression->firstExpression) + : $this->walkSimpleArithmeticExpression($nullIfExpression->firstExpression); + + $secondExpression = is_string($nullIfExpression->secondExpression) + ? $this->_conn->quote($nullIfExpression->secondExpression) + : $this->walkSimpleArithmeticExpression($nullIfExpression->secondExpression); + + return 'NULLIF(' . $firstExpression . ', ' . $secondExpression . ')'; + } + + /** + * Walks down a GeneralCaseExpression AST node and generates the corresponding SQL. + * + * @param GeneralCaseExpression $generalCaseExpression + * @return string The SQL. + */ + public function walkGeneralCaseExpression(AST\GeneralCaseExpression $generalCaseExpression) + { + $sql = 'CASE'; + + foreach ($generalCaseExpression->whenClauses as $whenClause) { + $sql .= ' WHEN ' . $this->walkConditionalExpression($whenClause->caseConditionExpression); + $sql .= ' THEN ' . $this->walkSimpleArithmeticExpression($whenClause->thenScalarExpression); + } + + $sql .= ' ELSE ' . $this->walkSimpleArithmeticExpression($generalCaseExpression->elseScalarExpression) . ' END'; + + return $sql; + } + + /** + * Walks down a SimpleCaseExpression AST node and generates the corresponding SQL. + * + * @param SimpleCaseExpression $simpleCaseExpression + * @return string The SQL. + */ + public function walkSimpleCaseExpression($simpleCaseExpression) + { + $sql = 'CASE ' . $this->walkStateFieldPathExpression($simpleCaseExpression->caseOperand); + + foreach ($simpleCaseExpression->simpleWhenClauses as $simpleWhenClause) { + $sql .= ' WHEN ' . $this->walkSimpleArithmeticExpression($simpleWhenClause->caseScalarExpression); + $sql .= ' THEN ' . $this->walkSimpleArithmeticExpression($simpleWhenClause->thenScalarExpression); + } + + $sql .= ' ELSE ' . $this->walkSimpleArithmeticExpression($simpleCaseExpression->elseScalarExpression) . ' END'; + + return $sql; + } + + /** + * Walks down a SelectExpression AST node and generates the corresponding SQL. + * + * @param SelectExpression $selectExpression + * @return string The SQL. + */ + public function walkSelectExpression($selectExpression) + { + $sql = ''; + $expr = $selectExpression->expression; + $hidden = $selectExpression->hiddenAliasResultVariable; + + switch (true) { + case ($expr instanceof AST\PathExpression): + if ($expr->type !== AST\PathExpression::TYPE_STATE_FIELD) { + throw QueryException::invalidPathExpression($expr->type); + } + + $fieldName = $expr->field; + $dqlAlias = $expr->identificationVariable; + $qComp = $this->_queryComponents[$dqlAlias]; + $class = $qComp['metadata']; + + $resultAlias = $selectExpression->fieldIdentificationVariable ?: $fieldName; + $tableName = ($class->isInheritanceTypeJoined()) + ? $this->_em->getUnitOfWork()->getEntityPersister($class->name)->getOwningTable($fieldName) + : $class->getTableName(); + + $sqlTableAlias = $this->getSQLTableAlias($tableName, $dqlAlias); + $columnName = $class->getQuotedColumnName($fieldName, $this->_platform); + $columnAlias = $this->getSQLColumnAlias($class->fieldMappings[$fieldName]['columnName']); + + $col = $sqlTableAlias . '.' . $columnName; + + $fieldType = $class->getTypeOfField($fieldName); + + if (isset($class->fieldMappings[$fieldName]['requireSQLConversion'])) { + $type = Type::getType($fieldType); + $col = $type->convertToPHPValueSQL($col, $this->_conn->getDatabasePlatform()); + } + + $sql .= $col . ' AS ' . $columnAlias; + + $this->_scalarResultAliasMap[$resultAlias] = $columnAlias; + + if ( ! $hidden) { + $this->_rsm->addScalarResult($columnAlias, $resultAlias, $fieldType); + $this->_scalarFields[$dqlAlias][$fieldName] = $columnAlias; + } + break; + + case ($expr instanceof AST\AggregateExpression): + case ($expr instanceof AST\Functions\FunctionNode): + case ($expr instanceof AST\SimpleArithmeticExpression): + case ($expr instanceof AST\ArithmeticTerm): + case ($expr instanceof AST\ArithmeticFactor): + case ($expr instanceof AST\ArithmeticPrimary): + case ($expr instanceof AST\Literal): + case ($expr instanceof AST\NullIfExpression): + case ($expr instanceof AST\CoalesceExpression): + case ($expr instanceof AST\GeneralCaseExpression): + case ($expr instanceof AST\SimpleCaseExpression): + $columnAlias = $this->getSQLColumnAlias('sclr'); + $resultAlias = $selectExpression->fieldIdentificationVariable ?: $this->_scalarResultCounter++; + + $sql .= $expr->dispatch($this) . ' AS ' . $columnAlias; + + $this->_scalarResultAliasMap[$resultAlias] = $columnAlias; + + if ( ! $hidden) { + // We cannot resolve field type here; assume 'string'. + $this->_rsm->addScalarResult($columnAlias, $resultAlias, 'string'); + } + break; + + case ($expr instanceof AST\Subselect): + $columnAlias = $this->getSQLColumnAlias('sclr'); + $resultAlias = $selectExpression->fieldIdentificationVariable ?: $this->_scalarResultCounter++; + + $sql .= '(' . $this->walkSubselect($expr) . ') AS ' . $columnAlias; + + $this->_scalarResultAliasMap[$resultAlias] = $columnAlias; + + if ( ! $hidden) { + // We cannot resolve field type here; assume 'string'. + $this->_rsm->addScalarResult($columnAlias, $resultAlias, 'string'); + } + break; + + default: + // IdentificationVariable or PartialObjectExpression + if ($expr instanceof AST\PartialObjectExpression) { + $dqlAlias = $expr->identificationVariable; + $partialFieldSet = $expr->partialFieldSet; + } else { + $dqlAlias = $expr; + $partialFieldSet = array(); + } + + $queryComp = $this->_queryComponents[$dqlAlias]; + $class = $queryComp['metadata']; + $resultAlias = $selectExpression->fieldIdentificationVariable ?: null; + + if ( ! isset($this->_selectedClasses[$dqlAlias])) { + $this->_selectedClasses[$dqlAlias] = array( + 'class' => $class, + 'dqlAlias' => $dqlAlias, + 'resultAlias' => $resultAlias + ); + } + + $sqlParts = array(); + + // Select all fields from the queried class + foreach ($class->fieldMappings as $fieldName => $mapping) { + if ($partialFieldSet && ! in_array($fieldName, $partialFieldSet)) { + continue; + } + + $tableName = (isset($mapping['inherited'])) + ? $this->_em->getClassMetadata($mapping['inherited'])->getTableName() + : $class->getTableName(); + + $sqlTableAlias = $this->getSQLTableAlias($tableName, $dqlAlias); + $columnAlias = $this->getSQLColumnAlias($mapping['columnName']); + $quotedColumnName = $class->getQuotedColumnName($fieldName, $this->_platform); + + $col = $sqlTableAlias . '.' . $quotedColumnName; + + if (isset($class->fieldMappings[$fieldName]['requireSQLConversion'])) { + $type = Type::getType($class->getTypeOfField($fieldName)); + $col = $type->convertToPHPValueSQL($col, $this->_platform); + } + + $sqlParts[] = $col . ' AS '. $columnAlias; + + $this->_scalarResultAliasMap[$resultAlias][] = $columnAlias; + + $this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName, $class->name); + } + + // Add any additional fields of subclasses (excluding inherited fields) + // 1) on Single Table Inheritance: always, since its marginal overhead + // 2) on Class Table Inheritance only if partial objects are disallowed, + // since it requires outer joining subtables. + if ($class->isInheritanceTypeSingleTable() || ! $this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD)) { + foreach ($class->subClasses as $subClassName) { + $subClass = $this->_em->getClassMetadata($subClassName); + $sqlTableAlias = $this->getSQLTableAlias($subClass->getTableName(), $dqlAlias); + + foreach ($subClass->fieldMappings as $fieldName => $mapping) { + if (isset($mapping['inherited']) || $partialFieldSet && !in_array($fieldName, $partialFieldSet)) { + continue; + } + + $columnAlias = $this->getSQLColumnAlias($mapping['columnName']); + $quotedColumnName = $subClass->getQuotedColumnName($fieldName, $this->_platform); + + $col = $sqlTableAlias . '.' . $quotedColumnName; + + if (isset($subClass->fieldMappings[$fieldName]['requireSQLConversion'])) { + $type = Type::getType($subClass->getTypeOfField($fieldName)); + $col = $type->convertToPHPValueSQL($col, $this->_platform); + } + + $sqlParts[] = $col . ' AS ' . $columnAlias; + + $this->_scalarResultAliasMap[$resultAlias][] = $columnAlias; + + $this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName, $subClassName); + } + } + } + + $sql .= implode(', ', $sqlParts); + } + + return $sql; + } + + /** + * Walks down a QuantifiedExpression AST node, thereby generating the appropriate SQL. + * + * @param QuantifiedExpression + * @return string The SQL. + */ + public function walkQuantifiedExpression($qExpr) + { + return ' ' . strtoupper($qExpr->type) . '(' . $this->walkSubselect($qExpr->subselect) . ')'; + } + + /** + * Walks down a Subselect AST node, thereby generating the appropriate SQL. + * + * @param Subselect + * @return string The SQL. + */ + public function walkSubselect($subselect) + { + $useAliasesBefore = $this->_useSqlTableAliases; + $rootAliasesBefore = $this->_rootAliases; + + $this->_rootAliases = array(); // reset the rootAliases for the subselect + $this->_useSqlTableAliases = true; + + $sql = $this->walkSimpleSelectClause($subselect->simpleSelectClause); + $sql .= $this->walkSubselectFromClause($subselect->subselectFromClause); + $sql .= $this->walkWhereClause($subselect->whereClause); + + $sql .= $subselect->groupByClause ? $this->walkGroupByClause($subselect->groupByClause) : ''; + $sql .= $subselect->havingClause ? $this->walkHavingClause($subselect->havingClause) : ''; + $sql .= $subselect->orderByClause ? $this->walkOrderByClause($subselect->orderByClause) : ''; + + $this->_rootAliases = $rootAliasesBefore; // put the main aliases back + $this->_useSqlTableAliases = $useAliasesBefore; + + return $sql; + } + + /** + * Walks down a SubselectFromClause AST node, thereby generating the appropriate SQL. + * + * @param SubselectFromClause + * @return string The SQL. + */ + public function walkSubselectFromClause($subselectFromClause) + { + $identificationVarDecls = $subselectFromClause->identificationVariableDeclarations; + $sqlParts = array (); + + foreach ($identificationVarDecls as $subselectIdVarDecl) { + $sql = ''; + + $rangeDecl = $subselectIdVarDecl->rangeVariableDeclaration; + $dqlAlias = $rangeDecl->aliasIdentificationVariable; + + $class = $this->_em->getClassMetadata($rangeDecl->abstractSchemaName); + $sql .= $class->getQuotedTableName($this->_platform) . ' ' + . $this->getSQLTableAlias($class->getTableName(), $dqlAlias); + + $this->_rootAliases[] = $dqlAlias; + + if ($class->isInheritanceTypeJoined()) { + $sql .= $this->_generateClassTableInheritanceJoins($class, $dqlAlias); + } + + foreach ($subselectIdVarDecl->joinVariableDeclarations as $joinVarDecl) { + $sql .= $this->walkJoinVariableDeclaration($joinVarDecl); + } + + $sqlParts[] = $this->_platform->appendLockHint($sql, $this->_query->getHint(Query::HINT_LOCK_MODE)); + } + + return ' FROM ' . implode(', ', $sqlParts); + } + + /** + * Walks down a SimpleSelectClause AST node, thereby generating the appropriate SQL. + * + * @param SimpleSelectClause + * @return string The SQL. + */ + public function walkSimpleSelectClause($simpleSelectClause) + { + return 'SELECT' . ($simpleSelectClause->isDistinct ? ' DISTINCT' : '') + . $this->walkSimpleSelectExpression($simpleSelectClause->simpleSelectExpression); + } + + /** + * Walks down a SimpleSelectExpression AST node, thereby generating the appropriate SQL. + * + * @param SimpleSelectExpression + * @return string The SQL. + */ + public function walkSimpleSelectExpression($simpleSelectExpression) + { + $expr = $simpleSelectExpression->expression; + $sql = ' '; + + switch (true) { + case ($expr instanceof AST\PathExpression): + $sql .= $this->walkPathExpression($expr); + break; + + case ($expr instanceof AST\AggregateExpression): + $alias = $simpleSelectExpression->fieldIdentificationVariable ?: $this->_scalarResultCounter++; + + $sql .= $this->walkAggregateExpression($expr) . ' AS dctrn__' . $alias; + break; + + case ($expr instanceof AST\Subselect): + $alias = $simpleSelectExpression->fieldIdentificationVariable ?: $this->_scalarResultCounter++; + + $columnAlias = 'sclr' . $this->_aliasCounter++; + $this->_scalarResultAliasMap[$alias] = $columnAlias; + + $sql .= '(' . $this->walkSubselect($expr) . ') AS ' . $columnAlias; + break; + + case ($expr instanceof AST\Functions\FunctionNode): + case ($expr instanceof AST\SimpleArithmeticExpression): + case ($expr instanceof AST\ArithmeticTerm): + case ($expr instanceof AST\ArithmeticFactor): + case ($expr instanceof AST\ArithmeticPrimary): + case ($expr instanceof AST\Literal): + case ($expr instanceof AST\NullIfExpression): + case ($expr instanceof AST\CoalesceExpression): + case ($expr instanceof AST\GeneralCaseExpression): + case ($expr instanceof AST\SimpleCaseExpression): + $alias = $simpleSelectExpression->fieldIdentificationVariable ?: $this->_scalarResultCounter++; + + $columnAlias = $this->getSQLColumnAlias('sclr'); + $this->_scalarResultAliasMap[$alias] = $columnAlias; + + $sql .= $expr->dispatch($this) . ' AS ' . $columnAlias; + break; + + default: // IdentificationVariable + $sql .= $this->walkEntityIdentificationVariable($expr); + break; + } + + return $sql; + } + + /** + * Walks down an AggregateExpression AST node, thereby generating the appropriate SQL. + * + * @param AggregateExpression + * @return string The SQL. + */ + public function walkAggregateExpression($aggExpression) + { + return $aggExpression->functionName . '(' . ($aggExpression->isDistinct ? 'DISTINCT ' : '') + . $this->walkSimpleArithmeticExpression($aggExpression->pathExpression) . ')'; + } + + /** + * Walks down a GroupByClause AST node, thereby generating the appropriate SQL. + * + * @param GroupByClause + * @return string The SQL. + */ + public function walkGroupByClause($groupByClause) + { + $sqlParts = array(); + + foreach ($groupByClause->groupByItems AS $groupByItem) { + $sqlParts[] = $this->walkGroupByItem($groupByItem); + } + + return ' GROUP BY ' . implode(', ', $sqlParts); + } + + /** + * Walks down a GroupByItem AST node, thereby generating the appropriate SQL. + * + * @param GroupByItem + * @return string The SQL. + */ + public function walkGroupByItem($groupByItem) + { + // StateFieldPathExpression + if ( ! is_string($groupByItem)) { + return $this->walkPathExpression($groupByItem); + } + + // ResultVariable + if (isset($this->_queryComponents[$groupByItem]['resultVariable'])) { + return $this->walkResultVariable($groupByItem); + } + + // IdentificationVariable + $sqlParts = array(); + + foreach ($this->_queryComponents[$groupByItem]['metadata']->fieldNames AS $field) { + $item = new AST\PathExpression(AST\PathExpression::TYPE_STATE_FIELD, $groupByItem, $field); + $item->type = AST\PathExpression::TYPE_STATE_FIELD; + + $sqlParts[] = $this->walkPathExpression($item); + } + + foreach ($this->_queryComponents[$groupByItem]['metadata']->associationMappings AS $mapping) { + if ($mapping['isOwningSide'] && $mapping['type'] & ClassMetadataInfo::TO_ONE) { + $item = new AST\PathExpression(AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, $groupByItem, $mapping['fieldName']); + $item->type = AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION; + + $sqlParts[] = $this->walkPathExpression($item); + } + } + + return implode(', ', $sqlParts); + } + + /** + * Walks down a DeleteClause AST node, thereby generating the appropriate SQL. + * + * @param DeleteClause + * @return string The SQL. + */ + public function walkDeleteClause(AST\DeleteClause $deleteClause) + { + $class = $this->_em->getClassMetadata($deleteClause->abstractSchemaName); + $tableName = $class->getTableName(); + $sql = 'DELETE FROM ' . $class->getQuotedTableName($this->_platform); + + $this->setSQLTableAlias($tableName, $tableName, $deleteClause->aliasIdentificationVariable); + $this->_rootAliases[] = $deleteClause->aliasIdentificationVariable; + + return $sql; + } + + /** + * Walks down an UpdateClause AST node, thereby generating the appropriate SQL. + * + * @param UpdateClause + * @return string The SQL. + */ + public function walkUpdateClause($updateClause) + { + $class = $this->_em->getClassMetadata($updateClause->abstractSchemaName); + $tableName = $class->getTableName(); + $sql = 'UPDATE ' . $class->getQuotedTableName($this->_platform); + + $this->setSQLTableAlias($tableName, $tableName, $updateClause->aliasIdentificationVariable); + $this->_rootAliases[] = $updateClause->aliasIdentificationVariable; + + $sql .= ' SET ' . implode(', ', array_map(array($this, 'walkUpdateItem'), $updateClause->updateItems)); + + return $sql; + } + + /** + * Walks down an UpdateItem AST node, thereby generating the appropriate SQL. + * + * @param UpdateItem + * @return string The SQL. + */ + public function walkUpdateItem($updateItem) + { + $useTableAliasesBefore = $this->_useSqlTableAliases; + $this->_useSqlTableAliases = false; + + $sql = $this->walkPathExpression($updateItem->pathExpression) . ' = '; + $newValue = $updateItem->newValue; + + switch (true) { + case ($newValue instanceof AST\Node): + $sql .= $newValue->dispatch($this); + break; + + case ($newValue === null): + $sql .= 'NULL'; + break; + + default: + $sql .= $this->_conn->quote($newValue); + break; + } + + $this->_useSqlTableAliases = $useTableAliasesBefore; + + return $sql; + } + + /** + * Walks down a WhereClause AST node, thereby generating the appropriate SQL. + * WhereClause or not, the appropriate discriminator sql is added. + * + * @param WhereClause + * @return string The SQL. + */ + public function walkWhereClause($whereClause) + { + $condSql = null !== $whereClause ? $this->walkConditionalExpression($whereClause->conditionalExpression) : ''; + $discrSql = $this->_generateDiscriminatorColumnConditionSql($this->_rootAliases); + + if ($this->_em->hasFilters()) { + $filterClauses = array(); + foreach ($this->_rootAliases as $dqlAlias) { + $class = $this->_queryComponents[$dqlAlias]['metadata']; + $tableAlias = $this->getSQLTableAlias($class->table['name'], $dqlAlias); + + if ($filterExpr = $this->generateFilterConditionSQL($class, $tableAlias)) { + $filterClauses[] = $filterExpr; + } + } + + if (count($filterClauses)) { + if ($condSql) { + $condSql .= ' AND '; + } + + $condSql .= implode(' AND ', $filterClauses); + } + } + + if ($condSql) { + return ' WHERE ' . (( ! $discrSql) ? $condSql : '(' . $condSql . ') AND ' . $discrSql); + } + + if ($discrSql) { + return ' WHERE ' . $discrSql; + } + + return ''; + } + + /** + * Walk down a ConditionalExpression AST node, thereby generating the appropriate SQL. + * + * @param ConditionalExpression + * @return string The SQL. + */ + public function walkConditionalExpression($condExpr) + { + // Phase 2 AST optimization: Skip processment of ConditionalExpression + // if only one ConditionalTerm is defined + if ( ! ($condExpr instanceof AST\ConditionalExpression)) { + return $this->walkConditionalTerm($condExpr); + } + + return implode(' OR ', array_map(array($this, 'walkConditionalTerm'), $condExpr->conditionalTerms)); + } + + /** + * Walks down a ConditionalTerm AST node, thereby generating the appropriate SQL. + * + * @param ConditionalTerm + * @return string The SQL. + */ + public function walkConditionalTerm($condTerm) + { + // Phase 2 AST optimization: Skip processment of ConditionalTerm + // if only one ConditionalFactor is defined + if ( ! ($condTerm instanceof AST\ConditionalTerm)) { + return $this->walkConditionalFactor($condTerm); + } + + return implode(' AND ', array_map(array($this, 'walkConditionalFactor'), $condTerm->conditionalFactors)); + } + + /** + * Walks down a ConditionalFactor AST node, thereby generating the appropriate SQL. + * + * @param ConditionalFactor + * @return string The SQL. + */ + public function walkConditionalFactor($factor) + { + // Phase 2 AST optimization: Skip processment of ConditionalFactor + // if only one ConditionalPrimary is defined + return ( ! ($factor instanceof AST\ConditionalFactor)) + ? $this->walkConditionalPrimary($factor) + : ($factor->not ? 'NOT ' : '') . $this->walkConditionalPrimary($factor->conditionalPrimary); + } + + /** + * Walks down a ConditionalPrimary AST node, thereby generating the appropriate SQL. + * + * @param ConditionalPrimary + * @return string The SQL. + */ + public function walkConditionalPrimary($primary) + { + if ($primary->isSimpleConditionalExpression()) { + return $primary->simpleConditionalExpression->dispatch($this); + } + + if ($primary->isConditionalExpression()) { + $condExpr = $primary->conditionalExpression; + + return '(' . $this->walkConditionalExpression($condExpr) . ')'; + } + } + + /** + * Walks down an ExistsExpression AST node, thereby generating the appropriate SQL. + * + * @param ExistsExpression + * @return string The SQL. + */ + public function walkExistsExpression($existsExpr) + { + $sql = ($existsExpr->not) ? 'NOT ' : ''; + + $sql .= 'EXISTS (' . $this->walkSubselect($existsExpr->subselect) . ')'; + + return $sql; + } + + /** + * Walks down a CollectionMemberExpression AST node, thereby generating the appropriate SQL. + * + * @param CollectionMemberExpression + * @return string The SQL. + */ + public function walkCollectionMemberExpression($collMemberExpr) + { + $sql = $collMemberExpr->not ? 'NOT ' : ''; + $sql .= 'EXISTS (SELECT 1 FROM '; + + $entityExpr = $collMemberExpr->entityExpression; + $collPathExpr = $collMemberExpr->collectionValuedPathExpression; + + $fieldName = $collPathExpr->field; + $dqlAlias = $collPathExpr->identificationVariable; + + $class = $this->_queryComponents[$dqlAlias]['metadata']; + + switch (true) { + // InputParameter + case ($entityExpr instanceof AST\InputParameter): + $dqlParamKey = $entityExpr->name; + $entity = $this->_query->getParameter($dqlParamKey); + $entitySql = '?'; + break; + + // SingleValuedAssociationPathExpression | IdentificationVariable + case ($entityExpr instanceof AST\PathExpression): + $entitySql = $this->walkPathExpression($entityExpr); + break; + + default: + throw new \BadMethodCallException("Not implemented"); + } + + $assoc = $class->associationMappings[$fieldName]; + + if ($assoc['type'] == ClassMetadata::ONE_TO_MANY) { + $targetClass = $this->_em->getClassMetadata($assoc['targetEntity']); + $targetTableAlias = $this->getSQLTableAlias($targetClass->getTableName()); + $sourceTableAlias = $this->getSQLTableAlias($class->getTableName(), $dqlAlias); + + $sql .= $targetClass->getQuotedTableName($this->_platform) . ' ' . $targetTableAlias . ' WHERE '; + + $owningAssoc = $targetClass->associationMappings[$assoc['mappedBy']]; + $sqlParts = array(); + + foreach ($owningAssoc['targetToSourceKeyColumns'] as $targetColumn => $sourceColumn) { + $targetColumn = $class->getQuotedColumnName($class->fieldNames[$targetColumn], $this->_platform); + + $sqlParts[] = $sourceTableAlias . '.' . $targetColumn . ' = ' . $targetTableAlias . '.' . $sourceColumn; + } + + foreach ($targetClass->getQuotedIdentifierColumnNames($this->_platform) as $targetColumnName) { + if (isset($dqlParamKey)) { + $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++); + } + + $sqlParts[] = $targetTableAlias . '.' . $targetColumnName . ' = ' . $entitySql; + } + + $sql .= implode(' AND ', $sqlParts); + } else { // many-to-many + $targetClass = $this->_em->getClassMetadata($assoc['targetEntity']); + + $owningAssoc = $assoc['isOwningSide'] ? $assoc : $targetClass->associationMappings[$assoc['mappedBy']]; + $joinTable = $owningAssoc['joinTable']; + + // SQL table aliases + $joinTableAlias = $this->getSQLTableAlias($joinTable['name']); + $targetTableAlias = $this->getSQLTableAlias($targetClass->getTableName()); + $sourceTableAlias = $this->getSQLTableAlias($class->getTableName(), $dqlAlias); + + // join to target table + $sql .= $targetClass->getQuotedJoinTableName($owningAssoc, $this->_platform) . ' ' . $joinTableAlias + . ' INNER JOIN ' . $targetClass->getQuotedTableName($this->_platform) . ' ' . $targetTableAlias . ' ON '; + + // join conditions + $joinColumns = $assoc['isOwningSide'] ? $joinTable['inverseJoinColumns'] : $joinTable['joinColumns']; + $joinSqlParts = array(); + + foreach ($joinColumns as $joinColumn) { + $targetColumn = $targetClass->getQuotedColumnName( + $targetClass->fieldNames[$joinColumn['referencedColumnName']], + $this->_platform + ); + + $joinSqlParts[] = $joinTableAlias . '.' . $joinColumn['name'] . ' = ' . $targetTableAlias . '.' . $targetColumn; + } + + $sql .= implode(' AND ', $joinSqlParts); + $sql .= ' WHERE '; + + $joinColumns = $assoc['isOwningSide'] ? $joinTable['joinColumns'] : $joinTable['inverseJoinColumns']; + $sqlParts = array(); + + foreach ($joinColumns as $joinColumn) { + $targetColumn = $class->getQuotedColumnName( + $class->fieldNames[$joinColumn['referencedColumnName']], + $this->_platform + ); + + $sqlParts[] = $joinTableAlias . '.' . $joinColumn['name'] . ' = ' . $sourceTableAlias . '.' . $targetColumn; + } + + foreach ($targetClass->getQuotedIdentifierColumnNames($this->_platform) as $targetColumnName) { + if (isset($dqlParamKey)) { + $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++); + } + + $sqlParts[] = $targetTableAlias . '.' . $targetColumnName . ' = ' . $entitySql; + } + + $sql .= implode(' AND ', $sqlParts); + } + + return $sql . ')'; + } + + /** + * Walks down an EmptyCollectionComparisonExpression AST node, thereby generating the appropriate SQL. + * + * @param EmptyCollectionComparisonExpression + * @return string The SQL. + */ + public function walkEmptyCollectionComparisonExpression($emptyCollCompExpr) + { + $sizeFunc = new AST\Functions\SizeFunction('size'); + $sizeFunc->collectionPathExpression = $emptyCollCompExpr->expression; + + return $sizeFunc->getSql($this) . ($emptyCollCompExpr->not ? ' > 0' : ' = 0'); + } + + /** + * Walks down a NullComparisonExpression AST node, thereby generating the appropriate SQL. + * + * @param NullComparisonExpression + * @return string The SQL. + */ + public function walkNullComparisonExpression($nullCompExpr) + { + $sql = ''; + $innerExpr = $nullCompExpr->expression; + + if ($innerExpr instanceof AST\InputParameter) { + $dqlParamKey = $innerExpr->name; + $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++); + $sql .= ' ?'; + } else { + $sql .= $this->walkPathExpression($innerExpr); + } + + $sql .= ' IS' . ($nullCompExpr->not ? ' NOT' : '') . ' NULL'; + + return $sql; + } + + /** + * Walks down an InExpression AST node, thereby generating the appropriate SQL. + * + * @param InExpression + * @return string The SQL. + */ + public function walkInExpression($inExpr) + { + $sql = $this->walkArithmeticExpression($inExpr->expression) . ($inExpr->not ? ' NOT' : '') . ' IN ('; + + $sql .= ($inExpr->subselect) + ? $this->walkSubselect($inExpr->subselect) + : implode(', ', array_map(array($this, 'walkInParameter'), $inExpr->literals)); + + $sql .= ')'; + + return $sql; + } + + /** + * Walks down an InstanceOfExpression AST node, thereby generating the appropriate SQL. + * + * @param InstanceOfExpression + * @return string The SQL. + */ + public function walkInstanceOfExpression($instanceOfExpr) + { + $sql = ''; + + $dqlAlias = $instanceOfExpr->identificationVariable; + $discrClass = $class = $this->_queryComponents[$dqlAlias]['metadata']; + $fieldName = null; + + if ($class->discriminatorColumn) { + $discrClass = $this->_em->getClassMetadata($class->rootEntityName); + } + + if ($this->_useSqlTableAliases) { + $sql .= $this->getSQLTableAlias($discrClass->getTableName(), $dqlAlias) . '.'; + } + + $sql .= $class->discriminatorColumn['name'] . ($instanceOfExpr->not ? ' NOT IN ' : ' IN '); + + $sqlParameterList = array(); + + foreach ($instanceOfExpr->value as $parameter) { + if ($parameter instanceof AST\InputParameter) { + // We need to modify the parameter value to be its correspondent mapped value + $dqlParamKey = $parameter->name; + $paramValue = $this->_query->getParameter($dqlParamKey); + + if ( ! ($paramValue instanceof \Doctrine\ORM\Mapping\ClassMetadata)) { + throw QueryException::invalidParameterType('ClassMetadata', get_class($paramValue)); + } + + $entityClassName = $paramValue->name; + } else { + // Get name from ClassMetadata to resolve aliases. + $entityClassName = $this->_em->getClassMetadata($parameter)->name; + } + + if ($entityClassName == $class->name) { + $sqlParameterList[] = $this->_conn->quote($class->discriminatorValue); + } else { + $discrMap = array_flip($class->discriminatorMap); + + if (!isset($discrMap[$entityClassName])) { + throw QueryException::instanceOfUnrelatedClass($entityClassName, $class->rootEntityName); + } + + $sqlParameterList[] = $this->_conn->quote($discrMap[$entityClassName]); + } + } + + $sql .= '(' . implode(', ', $sqlParameterList) . ')'; + + return $sql; + } + + /** + * Walks down an InParameter AST node, thereby generating the appropriate SQL. + * + * @param InParameter + * @return string The SQL. + */ + public function walkInParameter($inParam) + { + return $inParam instanceof AST\InputParameter + ? $this->walkInputParameter($inParam) + : $this->walkLiteral($inParam); + } + + /** + * Walks down a literal that represents an AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkLiteral($literal) + { + switch ($literal->type) { + case AST\Literal::STRING: + return $this->_conn->quote($literal->value); + + case AST\Literal::BOOLEAN: + $bool = strtolower($literal->value) == 'true' ? true : false; + $boolVal = $this->_conn->getDatabasePlatform()->convertBooleans($bool); + + return $boolVal; + + case AST\Literal::NUMERIC: + return $literal->value; + + default: + throw QueryException::invalidLiteral($literal); + } + } + + /** + * Walks down a BetweenExpression AST node, thereby generating the appropriate SQL. + * + * @param BetweenExpression + * @return string The SQL. + */ + public function walkBetweenExpression($betweenExpr) + { + $sql = $this->walkArithmeticExpression($betweenExpr->expression); + + if ($betweenExpr->not) $sql .= ' NOT'; + + $sql .= ' BETWEEN ' . $this->walkArithmeticExpression($betweenExpr->leftBetweenExpression) + . ' AND ' . $this->walkArithmeticExpression($betweenExpr->rightBetweenExpression); + + return $sql; + } + + /** + * Walks down a LikeExpression AST node, thereby generating the appropriate SQL. + * + * @param LikeExpression + * @return string The SQL. + */ + public function walkLikeExpression($likeExpr) + { + $stringExpr = $likeExpr->stringExpression; + $sql = $stringExpr->dispatch($this) . ($likeExpr->not ? ' NOT' : '') . ' LIKE '; + + if ($likeExpr->stringPattern instanceof AST\InputParameter) { + $inputParam = $likeExpr->stringPattern; + $dqlParamKey = $inputParam->name; + $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++); + $sql .= '?'; + } else { + $sql .= $this->_conn->quote($likeExpr->stringPattern); + } + + if ($likeExpr->escapeChar) { + $sql .= ' ESCAPE ' . $this->_conn->quote($likeExpr->escapeChar); + } + + return $sql; + } + + /** + * Walks down a StateFieldPathExpression AST node, thereby generating the appropriate SQL. + * + * @param StateFieldPathExpression + * @return string The SQL. + */ + public function walkStateFieldPathExpression($stateFieldPathExpression) + { + return $this->walkPathExpression($stateFieldPathExpression); + } + + /** + * Walks down a ComparisonExpression AST node, thereby generating the appropriate SQL. + * + * @param ComparisonExpression + * @return string The SQL. + */ + public function walkComparisonExpression($compExpr) + { + $leftExpr = $compExpr->leftExpression; + $rightExpr = $compExpr->rightExpression; + $sql = ''; + + $sql .= ($leftExpr instanceof AST\Node) + ? $leftExpr->dispatch($this) + : (is_numeric($leftExpr) ? $leftExpr : $this->_conn->quote($leftExpr)); + + $sql .= ' ' . $compExpr->operator . ' '; + + $sql .= ($rightExpr instanceof AST\Node) + ? $rightExpr->dispatch($this) + : (is_numeric($rightExpr) ? $rightExpr : $this->_conn->quote($rightExpr)); + + return $sql; + } + + /** + * Walks down an InputParameter AST node, thereby generating the appropriate SQL. + * + * @param InputParameter + * @return string The SQL. + */ + public function walkInputParameter($inputParam) + { + $this->_parserResult->addParameterMapping($inputParam->name, $this->_sqlParamIndex++); + + return '?'; + } + + /** + * Walks down an ArithmeticExpression AST node, thereby generating the appropriate SQL. + * + * @param ArithmeticExpression + * @return string The SQL. + */ + public function walkArithmeticExpression($arithmeticExpr) + { + return ($arithmeticExpr->isSimpleArithmeticExpression()) + ? $this->walkSimpleArithmeticExpression($arithmeticExpr->simpleArithmeticExpression) + : '(' . $this->walkSubselect($arithmeticExpr->subselect) . ')'; + } + + /** + * Walks down an SimpleArithmeticExpression AST node, thereby generating the appropriate SQL. + * + * @param SimpleArithmeticExpression + * @return string The SQL. + */ + public function walkSimpleArithmeticExpression($simpleArithmeticExpr) + { + if ( ! ($simpleArithmeticExpr instanceof AST\SimpleArithmeticExpression)) { + return $this->walkArithmeticTerm($simpleArithmeticExpr); + } + + return implode(' ', array_map(array($this, 'walkArithmeticTerm'), $simpleArithmeticExpr->arithmeticTerms)); + } + + /** + * Walks down an ArithmeticTerm AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkArithmeticTerm($term) + { + if (is_string($term)) { + return (isset($this->_queryComponents[$term])) + ? $this->walkResultVariable($this->_queryComponents[$term]['token']['value']) + : $term; + } + + // Phase 2 AST optimization: Skip processment of ArithmeticTerm + // if only one ArithmeticFactor is defined + if ( ! ($term instanceof AST\ArithmeticTerm)) { + return $this->walkArithmeticFactor($term); + } + + return implode(' ', array_map(array($this, 'walkArithmeticFactor'), $term->arithmeticFactors)); + } + + /** + * Walks down an ArithmeticFactor that represents an AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkArithmeticFactor($factor) + { + if (is_string($factor)) { + return $factor; + } + + // Phase 2 AST optimization: Skip processment of ArithmeticFactor + // if only one ArithmeticPrimary is defined + if ( ! ($factor instanceof AST\ArithmeticFactor)) { + return $this->walkArithmeticPrimary($factor); + } + + $sign = $factor->isNegativeSigned() ? '-' : ($factor->isPositiveSigned() ? '+' : ''); + + return $sign . $this->walkArithmeticPrimary($factor->arithmeticPrimary); + } + + /** + * Walks down an ArithmeticPrimary that represents an AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkArithmeticPrimary($primary) + { + if ($primary instanceof AST\SimpleArithmeticExpression) { + return '(' . $this->walkSimpleArithmeticExpression($primary) . ')'; + } + + if ($primary instanceof AST\Node) { + return $primary->dispatch($this); + } + + return $this->walkEntityIdentificationVariable($primary); + } + + /** + * Walks down a StringPrimary that represents an AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkStringPrimary($stringPrimary) + { + return (is_string($stringPrimary)) + ? $this->_conn->quote($stringPrimary) + : $stringPrimary->dispatch($this); + } + + /** + * Walks down a ResultVriable that represents an AST node, thereby generating the appropriate SQL. + * + * @param string $resultVariable + * @return string The SQL. + */ + public function walkResultVariable($resultVariable) + { + $resultAlias = $this->_scalarResultAliasMap[$resultVariable]; + + if (is_array($resultAlias)) { + return implode(', ', $resultAlias); + } + + return $resultAlias; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/TreeWalker.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/TreeWalker.php new file mode 100644 index 0000000..8462898 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/TreeWalker.php @@ -0,0 +1,411 @@ +. + */ + +namespace Doctrine\ORM\Query; + +/** + * Interface for walkers of DQL ASTs (abstract syntax trees). + * + * @author Roman Borschel + * @since 2.0 + */ +interface TreeWalker +{ + /** + * Initializes TreeWalker with important information about the ASTs to be walked + * + * @param Query $query The parsed Query. + * @param ParserResult $parserResult The result of the parsing process. + * @param array $queryComponents Query components (symbol table) + */ + public function __construct($query, $parserResult, array $queryComponents); + + /** + * Walks down a SelectStatement AST node, thereby generating the appropriate SQL. + * + * @return string The SQL. + */ + function walkSelectStatement(AST\SelectStatement $AST); + + /** + * Walks down a SelectClause AST node, thereby generating the appropriate SQL. + * + * @return string The SQL. + */ + function walkSelectClause($selectClause); + + /** + * Walks down a FromClause AST node, thereby generating the appropriate SQL. + * + * @return string The SQL. + */ + function walkFromClause($fromClause); + + /** + * Walks down a FunctionNode AST node, thereby generating the appropriate SQL. + * + * @return string The SQL. + */ + function walkFunction($function); + + /** + * Walks down an OrderByClause AST node, thereby generating the appropriate SQL. + * + * @param OrderByClause + * @return string The SQL. + */ + function walkOrderByClause($orderByClause); + + /** + * Walks down an OrderByItem AST node, thereby generating the appropriate SQL. + * + * @param OrderByItem + * @return string The SQL. + */ + function walkOrderByItem($orderByItem); + + /** + * Walks down a HavingClause AST node, thereby generating the appropriate SQL. + * + * @param HavingClause + * @return string The SQL. + */ + function walkHavingClause($havingClause); + + /** + * Walks down a JoinVariableDeclaration AST node and creates the corresponding SQL. + * + * @param JoinVariableDeclaration $joinVarDecl + * @return string The SQL. + */ + function walkJoinVariableDeclaration($joinVarDecl); + + /** + * Walks down a SelectExpression AST node and generates the corresponding SQL. + * + * @param SelectExpression $selectExpression + * @return string The SQL. + */ + function walkSelectExpression($selectExpression); + + /** + * Walks down a QuantifiedExpression AST node, thereby generating the appropriate SQL. + * + * @param QuantifiedExpression + * @return string The SQL. + */ + function walkQuantifiedExpression($qExpr); + + /** + * Walks down a Subselect AST node, thereby generating the appropriate SQL. + * + * @param Subselect + * @return string The SQL. + */ + function walkSubselect($subselect); + + /** + * Walks down a SubselectFromClause AST node, thereby generating the appropriate SQL. + * + * @param SubselectFromClause + * @return string The SQL. + */ + function walkSubselectFromClause($subselectFromClause); + + /** + * Walks down a SimpleSelectClause AST node, thereby generating the appropriate SQL. + * + * @param SimpleSelectClause + * @return string The SQL. + */ + function walkSimpleSelectClause($simpleSelectClause); + + /** + * Walks down a SimpleSelectExpression AST node, thereby generating the appropriate SQL. + * + * @param SimpleSelectExpression + * @return string The SQL. + */ + function walkSimpleSelectExpression($simpleSelectExpression); + + /** + * Walks down an AggregateExpression AST node, thereby generating the appropriate SQL. + * + * @param AggregateExpression + * @return string The SQL. + */ + function walkAggregateExpression($aggExpression); + + /** + * Walks down a GroupByClause AST node, thereby generating the appropriate SQL. + * + * @param GroupByClause + * @return string The SQL. + */ + function walkGroupByClause($groupByClause); + + /** + * Walks down a GroupByItem AST node, thereby generating the appropriate SQL. + * + * @param GroupByItem + * @return string The SQL. + */ + function walkGroupByItem($groupByItem); + + /** + * Walks down an UpdateStatement AST node, thereby generating the appropriate SQL. + * + * @param UpdateStatement + * @return string The SQL. + */ + function walkUpdateStatement(AST\UpdateStatement $AST); + + /** + * Walks down a DeleteStatement AST node, thereby generating the appropriate SQL. + * + * @param DeleteStatement + * @return string The SQL. + */ + function walkDeleteStatement(AST\DeleteStatement $AST); + + /** + * Walks down a DeleteClause AST node, thereby generating the appropriate SQL. + * + * @param DeleteClause + * @return string The SQL. + */ + function walkDeleteClause(AST\DeleteClause $deleteClause); + + /** + * Walks down an UpdateClause AST node, thereby generating the appropriate SQL. + * + * @param UpdateClause + * @return string The SQL. + */ + function walkUpdateClause($updateClause); + + /** + * Walks down an UpdateItem AST node, thereby generating the appropriate SQL. + * + * @param UpdateItem + * @return string The SQL. + */ + function walkUpdateItem($updateItem); + + /** + * Walks down a WhereClause AST node, thereby generating the appropriate SQL. + * + * @param WhereClause + * @return string The SQL. + */ + function walkWhereClause($whereClause); + + /** + * Walks down a ConditionalExpression AST node, thereby generating the appropriate SQL. + * + * @param ConditionalExpression + * @return string The SQL. + */ + function walkConditionalExpression($condExpr); + + /** + * Walks down a ConditionalTerm AST node, thereby generating the appropriate SQL. + * + * @param ConditionalTerm + * @return string The SQL. + */ + function walkConditionalTerm($condTerm); + + /** + * Walks down a ConditionalFactor AST node, thereby generating the appropriate SQL. + * + * @param ConditionalFactor + * @return string The SQL. + */ + function walkConditionalFactor($factor); + + /** + * Walks down a ConditionalPrimary AST node, thereby generating the appropriate SQL. + * + * @param ConditionalPrimary + * @return string The SQL. + */ + function walkConditionalPrimary($primary); + + /** + * Walks down an ExistsExpression AST node, thereby generating the appropriate SQL. + * + * @param ExistsExpression + * @return string The SQL. + */ + function walkExistsExpression($existsExpr); + + /** + * Walks down a CollectionMemberExpression AST node, thereby generating the appropriate SQL. + * + * @param CollectionMemberExpression + * @return string The SQL. + */ + function walkCollectionMemberExpression($collMemberExpr); + + /** + * Walks down an EmptyCollectionComparisonExpression AST node, thereby generating the appropriate SQL. + * + * @param EmptyCollectionComparisonExpression + * @return string The SQL. + */ + function walkEmptyCollectionComparisonExpression($emptyCollCompExpr); + + /** + * Walks down a NullComparisonExpression AST node, thereby generating the appropriate SQL. + * + * @param NullComparisonExpression + * @return string The SQL. + */ + function walkNullComparisonExpression($nullCompExpr); + + /** + * Walks down an InExpression AST node, thereby generating the appropriate SQL. + * + * @param InExpression + * @return string The SQL. + */ + function walkInExpression($inExpr); + + /** + * Walks down an InstanceOfExpression AST node, thereby generating the appropriate SQL. + * + * @param InstanceOfExpression + * @return string The SQL. + */ + function walkInstanceOfExpression($instanceOfExpr); + + /** + * Walks down a literal that represents an AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + function walkLiteral($literal); + + /** + * Walks down a BetweenExpression AST node, thereby generating the appropriate SQL. + * + * @param BetweenExpression + * @return string The SQL. + */ + function walkBetweenExpression($betweenExpr); + + /** + * Walks down a LikeExpression AST node, thereby generating the appropriate SQL. + * + * @param LikeExpression + * @return string The SQL. + */ + function walkLikeExpression($likeExpr); + + /** + * Walks down a StateFieldPathExpression AST node, thereby generating the appropriate SQL. + * + * @param StateFieldPathExpression + * @return string The SQL. + */ + function walkStateFieldPathExpression($stateFieldPathExpression); + + /** + * Walks down a ComparisonExpression AST node, thereby generating the appropriate SQL. + * + * @param ComparisonExpression + * @return string The SQL. + */ + function walkComparisonExpression($compExpr); + + /** + * Walks down an InputParameter AST node, thereby generating the appropriate SQL. + * + * @param InputParameter + * @return string The SQL. + */ + function walkInputParameter($inputParam); + + /** + * Walks down an ArithmeticExpression AST node, thereby generating the appropriate SQL. + * + * @param ArithmeticExpression + * @return string The SQL. + */ + function walkArithmeticExpression($arithmeticExpr); + + /** + * Walks down an ArithmeticTerm AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + function walkArithmeticTerm($term); + + /** + * Walks down a StringPrimary that represents an AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + function walkStringPrimary($stringPrimary); + + /** + * Walks down an ArithmeticFactor that represents an AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + function walkArithmeticFactor($factor); + + /** + * Walks down an SimpleArithmeticExpression AST node, thereby generating the appropriate SQL. + * + * @param SimpleArithmeticExpression + * @return string The SQL. + */ + function walkSimpleArithmeticExpression($simpleArithmeticExpr); + + /** + * Walks down an PathExpression AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + function walkPathExpression($pathExpr); + + /** + * Walks down an ResultVariable AST node, thereby generating the appropriate SQL. + * + * @param string $resultVariable + * @return string The SQL. + */ + function walkResultVariable($resultVariable); + + /** + * Gets an executor that can be used to execute the result of this walker. + * + * @return AbstractExecutor + */ + function getExecutor($AST); +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/TreeWalkerAdapter.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/TreeWalkerAdapter.php new file mode 100644 index 0000000..5907aa9 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/TreeWalkerAdapter.php @@ -0,0 +1,445 @@ +. + */ + +namespace Doctrine\ORM\Query; + +/** + * An adapter implementation of the TreeWalker interface. The methods in this class + * are empty. This class exists as convenience for creating tree walkers. + * + * @author Roman Borschel + * @since 2.0 + */ +abstract class TreeWalkerAdapter implements TreeWalker +{ + private $_query; + private $_parserResult; + private $_queryComponents; + + /** + * {@inheritdoc} + */ + public function __construct($query, $parserResult, array $queryComponents) + { + $this->_query = $query; + $this->_parserResult = $parserResult; + $this->_queryComponents = $queryComponents; + } + + /** + * @return array + */ + protected function _getQueryComponents() + { + return $this->_queryComponents; + } + + /** + * Retrieve Query Instance reponsible for the current walkers execution. + * + * @return \Doctrine\ORM\Query + */ + protected function _getQuery() + { + return $this->_query; + } + + /** + * Retrieve ParserResult + * + * @return \Doctrine\ORM\Query\ParserResult + */ + protected function _getParserResult() + { + return $this->_parserResult; + } + + /** + * Walks down a SelectStatement AST node, thereby generating the appropriate SQL. + * + * @return string The SQL. + */ + public function walkSelectStatement(AST\SelectStatement $AST) {} + + /** + * Walks down a SelectClause AST node, thereby generating the appropriate SQL. + * + * @return string The SQL. + */ + public function walkSelectClause($selectClause) {} + + /** + * Walks down a FromClause AST node, thereby generating the appropriate SQL. + * + * @return string The SQL. + */ + public function walkFromClause($fromClause) {} + + /** + * Walks down a FunctionNode AST node, thereby generating the appropriate SQL. + * + * @return string The SQL. + */ + public function walkFunction($function) {} + + /** + * Walks down an OrderByClause AST node, thereby generating the appropriate SQL. + * + * @param OrderByClause + * @return string The SQL. + */ + public function walkOrderByClause($orderByClause) {} + + /** + * Walks down an OrderByItem AST node, thereby generating the appropriate SQL. + * + * @param OrderByItem + * @return string The SQL. + */ + public function walkOrderByItem($orderByItem) {} + + /** + * Walks down a HavingClause AST node, thereby generating the appropriate SQL. + * + * @param HavingClause + * @return string The SQL. + */ + public function walkHavingClause($havingClause) {} + + /** + * Walks down a JoinVariableDeclaration AST node and creates the corresponding SQL. + * + * @param JoinVariableDeclaration $joinVarDecl + * @return string The SQL. + */ + public function walkJoinVariableDeclaration($joinVarDecl) {} + + /** + * Walks down a SelectExpression AST node and generates the corresponding SQL. + * + * @param SelectExpression $selectExpression + * @return string The SQL. + */ + public function walkSelectExpression($selectExpression) {} + + /** + * Walks down a QuantifiedExpression AST node, thereby generating the appropriate SQL. + * + * @param QuantifiedExpression + * @return string The SQL. + */ + public function walkQuantifiedExpression($qExpr) {} + + /** + * Walks down a Subselect AST node, thereby generating the appropriate SQL. + * + * @param Subselect + * @return string The SQL. + */ + public function walkSubselect($subselect) {} + + /** + * Walks down a SubselectFromClause AST node, thereby generating the appropriate SQL. + * + * @param SubselectFromClause + * @return string The SQL. + */ + public function walkSubselectFromClause($subselectFromClause) {} + + /** + * Walks down a SimpleSelectClause AST node, thereby generating the appropriate SQL. + * + * @param SimpleSelectClause + * @return string The SQL. + */ + public function walkSimpleSelectClause($simpleSelectClause) {} + + /** + * Walks down a SimpleSelectExpression AST node, thereby generating the appropriate SQL. + * + * @param SimpleSelectExpression + * @return string The SQL. + */ + public function walkSimpleSelectExpression($simpleSelectExpression) {} + + /** + * Walks down an AggregateExpression AST node, thereby generating the appropriate SQL. + * + * @param AggregateExpression + * @return string The SQL. + */ + public function walkAggregateExpression($aggExpression) {} + + /** + * Walks down a GroupByClause AST node, thereby generating the appropriate SQL. + * + * @param GroupByClause + * @return string The SQL. + */ + public function walkGroupByClause($groupByClause) {} + + /** + * Walks down a GroupByItem AST node, thereby generating the appropriate SQL. + * + * @param GroupByItem + * @return string The SQL. + */ + public function walkGroupByItem($groupByItem) {} + + /** + * Walks down an UpdateStatement AST node, thereby generating the appropriate SQL. + * + * @param UpdateStatement + * @return string The SQL. + */ + public function walkUpdateStatement(AST\UpdateStatement $AST) {} + + /** + * Walks down a DeleteStatement AST node, thereby generating the appropriate SQL. + * + * @param DeleteStatement + * @return string The SQL. + */ + public function walkDeleteStatement(AST\DeleteStatement $AST) {} + + /** + * Walks down a DeleteClause AST node, thereby generating the appropriate SQL. + * + * @param DeleteClause + * @return string The SQL. + */ + public function walkDeleteClause(AST\DeleteClause $deleteClause) {} + + /** + * Walks down an UpdateClause AST node, thereby generating the appropriate SQL. + * + * @param UpdateClause + * @return string The SQL. + */ + public function walkUpdateClause($updateClause) {} + + /** + * Walks down an UpdateItem AST node, thereby generating the appropriate SQL. + * + * @param UpdateItem + * @return string The SQL. + */ + public function walkUpdateItem($updateItem) {} + + /** + * Walks down a WhereClause AST node, thereby generating the appropriate SQL. + * + * @param WhereClause + * @return string The SQL. + */ + public function walkWhereClause($whereClause) {} + + /** + * Walks down a ConditionalExpression AST node, thereby generating the appropriate SQL. + * + * @param ConditionalExpression + * @return string The SQL. + */ + public function walkConditionalExpression($condExpr) {} + + /** + * Walks down a ConditionalTerm AST node, thereby generating the appropriate SQL. + * + * @param ConditionalTerm + * @return string The SQL. + */ + public function walkConditionalTerm($condTerm) {} + + /** + * Walks down a ConditionalFactor AST node, thereby generating the appropriate SQL. + * + * @param ConditionalFactor + * @return string The SQL. + */ + public function walkConditionalFactor($factor) {} + + /** + * Walks down a ConditionalPrimary AST node, thereby generating the appropriate SQL. + * + * @param ConditionalPrimary + * @return string The SQL. + */ + public function walkConditionalPrimary($primary) {} + + /** + * Walks down an ExistsExpression AST node, thereby generating the appropriate SQL. + * + * @param ExistsExpression + * @return string The SQL. + */ + public function walkExistsExpression($existsExpr) {} + + /** + * Walks down a CollectionMemberExpression AST node, thereby generating the appropriate SQL. + * + * @param CollectionMemberExpression + * @return string The SQL. + */ + public function walkCollectionMemberExpression($collMemberExpr) {} + + /** + * Walks down an EmptyCollectionComparisonExpression AST node, thereby generating the appropriate SQL. + * + * @param EmptyCollectionComparisonExpression + * @return string The SQL. + */ + public function walkEmptyCollectionComparisonExpression($emptyCollCompExpr) {} + + /** + * Walks down a NullComparisonExpression AST node, thereby generating the appropriate SQL. + * + * @param NullComparisonExpression + * @return string The SQL. + */ + public function walkNullComparisonExpression($nullCompExpr) {} + + /** + * Walks down an InExpression AST node, thereby generating the appropriate SQL. + * + * @param InExpression + * @return string The SQL. + */ + public function walkInExpression($inExpr) {} + + /** + * Walks down an InstanceOfExpression AST node, thereby generating the appropriate SQL. + * + * @param InstanceOfExpression + * @return string The SQL. + */ + function walkInstanceOfExpression($instanceOfExpr) {} + + /** + * Walks down a literal that represents an AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkLiteral($literal) {} + + /** + * Walks down a BetweenExpression AST node, thereby generating the appropriate SQL. + * + * @param BetweenExpression + * @return string The SQL. + */ + public function walkBetweenExpression($betweenExpr) {} + + /** + * Walks down a LikeExpression AST node, thereby generating the appropriate SQL. + * + * @param LikeExpression + * @return string The SQL. + */ + public function walkLikeExpression($likeExpr) {} + + /** + * Walks down a StateFieldPathExpression AST node, thereby generating the appropriate SQL. + * + * @param StateFieldPathExpression + * @return string The SQL. + */ + public function walkStateFieldPathExpression($stateFieldPathExpression) {} + + /** + * Walks down a ComparisonExpression AST node, thereby generating the appropriate SQL. + * + * @param ComparisonExpression + * @return string The SQL. + */ + public function walkComparisonExpression($compExpr) {} + + /** + * Walks down an InputParameter AST node, thereby generating the appropriate SQL. + * + * @param InputParameter + * @return string The SQL. + */ + public function walkInputParameter($inputParam) {} + + /** + * Walks down an ArithmeticExpression AST node, thereby generating the appropriate SQL. + * + * @param ArithmeticExpression + * @return string The SQL. + */ + public function walkArithmeticExpression($arithmeticExpr) {} + + /** + * Walks down an ArithmeticTerm AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkArithmeticTerm($term) {} + + /** + * Walks down a StringPrimary that represents an AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkStringPrimary($stringPrimary) {} + + /** + * Walks down an ArithmeticFactor that represents an AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkArithmeticFactor($factor) {} + + /** + * Walks down an SimpleArithmeticExpression AST node, thereby generating the appropriate SQL. + * + * @param SimpleArithmeticExpression + * @return string The SQL. + */ + public function walkSimpleArithmeticExpression($simpleArithmeticExpr) {} + + /** + * Walks down an PathExpression AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkPathExpression($pathExpr) {} + + /** + * Walks down an ResultVariable AST node, thereby generating the appropriate SQL. + * + * @param string $resultVariable + * @return string The SQL. + */ + public function walkResultVariable($resultVariable) {} + + /** + * Gets an executor that can be used to execute the result of this walker. + * + * @return AbstractExecutor + */ + public function getExecutor($AST) {} +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Query/TreeWalkerChain.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/TreeWalkerChain.php new file mode 100644 index 0000000..d3891a1 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Query/TreeWalkerChain.php @@ -0,0 +1,664 @@ +. + */ + +namespace Doctrine\ORM\Query; + +/** + * Represents a chain of tree walkers that modify an AST and finally emit output. + * Only the last walker in the chain can emit output. Any previous walkers can modify + * the AST to influence the final output produced by the last walker. + * + * @author Roman Borschel + * @since 2.0 + */ +class TreeWalkerChain implements TreeWalker +{ + /** The tree walkers. */ + private $_walkers = array(); + /** The original Query. */ + private $_query; + /** The ParserResult of the original query that was produced by the Parser. */ + private $_parserResult; + /** The query components of the original query (the "symbol table") that was produced by the Parser. */ + private $_queryComponents; + + /** + * @inheritdoc + */ + public function __construct($query, $parserResult, array $queryComponents) + { + $this->_query = $query; + $this->_parserResult = $parserResult; + $this->_queryComponents = $queryComponents; + } + + /** + * Adds a tree walker to the chain. + * + * @param string $walkerClass The class of the walker to instantiate. + */ + public function addTreeWalker($walkerClass) + { + $this->_walkers[] = new $walkerClass($this->_query, $this->_parserResult, $this->_queryComponents); + } + + /** + * Walks down a SelectStatement AST node, thereby generating the appropriate SQL. + * + * @return string The SQL. + */ + public function walkSelectStatement(AST\SelectStatement $AST) + { + foreach ($this->_walkers as $walker) { + $walker->walkSelectStatement($AST); + } + } + + /** + * Walks down a SelectClause AST node, thereby generating the appropriate SQL. + * + * @return string The SQL. + */ + public function walkSelectClause($selectClause) + { + foreach ($this->_walkers as $walker) { + $walker->walkSelectClause($selectClause); + } + } + + /** + * Walks down a FromClause AST node, thereby generating the appropriate SQL. + * + * @return string The SQL. + */ + public function walkFromClause($fromClause) + { + foreach ($this->_walkers as $walker) { + $walker->walkFromClause($fromClause); + } + } + + /** + * Walks down a FunctionNode AST node, thereby generating the appropriate SQL. + * + * @return string The SQL. + */ + public function walkFunction($function) + { + foreach ($this->_walkers as $walker) { + $walker->walkFunction($function); + } + } + + /** + * Walks down an OrderByClause AST node, thereby generating the appropriate SQL. + * + * @param OrderByClause + * @return string The SQL. + */ + public function walkOrderByClause($orderByClause) + { + foreach ($this->_walkers as $walker) { + $walker->walkOrderByClause($orderByClause); + } + } + + /** + * Walks down an OrderByItem AST node, thereby generating the appropriate SQL. + * + * @param OrderByItem + * @return string The SQL. + */ + public function walkOrderByItem($orderByItem) + { + foreach ($this->_walkers as $walker) { + $walker->walkOrderByItem($orderByItem); + } + } + + /** + * Walks down a HavingClause AST node, thereby generating the appropriate SQL. + * + * @param HavingClause + * @return string The SQL. + */ + public function walkHavingClause($havingClause) + { + foreach ($this->_walkers as $walker) { + $walker->walkHavingClause($havingClause); + } + } + + /** + * Walks down a JoinVariableDeclaration AST node and creates the corresponding SQL. + * + * @param JoinVariableDeclaration $joinVarDecl + * @return string The SQL. + */ + public function walkJoinVariableDeclaration($joinVarDecl) + { + foreach ($this->_walkers as $walker) { + $walker->walkJoinVariableDeclaration($joinVarDecl); + } + } + + /** + * Walks down a SelectExpression AST node and generates the corresponding SQL. + * + * @param SelectExpression $selectExpression + * @return string The SQL. + */ + public function walkSelectExpression($selectExpression) + { + foreach ($this->_walkers as $walker) { + $walker->walkSelectExpression($selectExpression); + } + } + + /** + * Walks down a QuantifiedExpression AST node, thereby generating the appropriate SQL. + * + * @param QuantifiedExpression + * @return string The SQL. + */ + public function walkQuantifiedExpression($qExpr) + { + foreach ($this->_walkers as $walker) { + $walker->walkQuantifiedExpression($qExpr); + } + } + + /** + * Walks down a Subselect AST node, thereby generating the appropriate SQL. + * + * @param Subselect + * @return string The SQL. + */ + public function walkSubselect($subselect) + { + foreach ($this->_walkers as $walker) { + $walker->walkSubselect($subselect); + } + } + + /** + * Walks down a SubselectFromClause AST node, thereby generating the appropriate SQL. + * + * @param SubselectFromClause + * @return string The SQL. + */ + public function walkSubselectFromClause($subselectFromClause) + { + foreach ($this->_walkers as $walker) { + $walker->walkSubselectFromClause($subselectFromClause); + } + } + + /** + * Walks down a SimpleSelectClause AST node, thereby generating the appropriate SQL. + * + * @param SimpleSelectClause + * @return string The SQL. + */ + public function walkSimpleSelectClause($simpleSelectClause) + { + foreach ($this->_walkers as $walker) { + $walker->walkSimpleSelectClause($simpleSelectClause); + } + } + + /** + * Walks down a SimpleSelectExpression AST node, thereby generating the appropriate SQL. + * + * @param SimpleSelectExpression + * @return string The SQL. + */ + public function walkSimpleSelectExpression($simpleSelectExpression) + { + foreach ($this->_walkers as $walker) { + $walker->walkSimpleSelectExpression($simpleSelectExpression); + } + } + + /** + * Walks down an AggregateExpression AST node, thereby generating the appropriate SQL. + * + * @param AggregateExpression + * @return string The SQL. + */ + public function walkAggregateExpression($aggExpression) + { + foreach ($this->_walkers as $walker) { + $walker->walkAggregateExpression($aggExpression); + } + } + + /** + * Walks down a GroupByClause AST node, thereby generating the appropriate SQL. + * + * @param GroupByClause + * @return string The SQL. + */ + public function walkGroupByClause($groupByClause) + { + foreach ($this->_walkers as $walker) { + $walker->walkGroupByClause($groupByClause); + } + } + + /** + * Walks down a GroupByItem AST node, thereby generating the appropriate SQL. + * + * @param GroupByItem + * @return string The SQL. + */ + public function walkGroupByItem($groupByItem) + { + foreach ($this->_walkers as $walker) { + $walker->walkGroupByItem($groupByItem); + } + } + + /** + * Walks down an UpdateStatement AST node, thereby generating the appropriate SQL. + * + * @param UpdateStatement + * @return string The SQL. + */ + public function walkUpdateStatement(AST\UpdateStatement $AST) + { + foreach ($this->_walkers as $walker) { + $walker->walkUpdateStatement($AST); + } + } + + /** + * Walks down a DeleteStatement AST node, thereby generating the appropriate SQL. + * + * @param DeleteStatement + * @return string The SQL. + */ + public function walkDeleteStatement(AST\DeleteStatement $AST) + { + foreach ($this->_walkers as $walker) { + $walker->walkDeleteStatement($AST); + } + } + + /** + * Walks down a DeleteClause AST node, thereby generating the appropriate SQL. + * + * @param DeleteClause + * @return string The SQL. + */ + public function walkDeleteClause(AST\DeleteClause $deleteClause) + { + foreach ($this->_walkers as $walker) { + $walker->walkDeleteClause($deleteClause); + } + } + + /** + * Walks down an UpdateClause AST node, thereby generating the appropriate SQL. + * + * @param UpdateClause + * @return string The SQL. + */ + public function walkUpdateClause($updateClause) + { + foreach ($this->_walkers as $walker) { + $walker->walkUpdateClause($updateClause); + } + } + + /** + * Walks down an UpdateItem AST node, thereby generating the appropriate SQL. + * + * @param UpdateItem + * @return string The SQL. + */ + public function walkUpdateItem($updateItem) + { + foreach ($this->_walkers as $walker) { + $walker->walkUpdateItem($updateItem); + } + } + + /** + * Walks down a WhereClause AST node, thereby generating the appropriate SQL. + * + * @param WhereClause + * @return string The SQL. + */ + public function walkWhereClause($whereClause) + { + foreach ($this->_walkers as $walker) { + $walker->walkWhereClause($whereClause); + } + } + + /** + * Walks down a ConditionalExpression AST node, thereby generating the appropriate SQL. + * + * @param ConditionalExpression + * @return string The SQL. + */ + public function walkConditionalExpression($condExpr) + { + foreach ($this->_walkers as $walker) { + $walker->walkConditionalExpression($condExpr); + } + } + + /** + * Walks down a ConditionalTerm AST node, thereby generating the appropriate SQL. + * + * @param ConditionalTerm + * @return string The SQL. + */ + public function walkConditionalTerm($condTerm) + { + foreach ($this->_walkers as $walker) { + $walker->walkConditionalTerm($condTerm); + } + } + + /** + * Walks down a ConditionalFactor AST node, thereby generating the appropriate SQL. + * + * @param ConditionalFactor + * @return string The SQL. + */ + public function walkConditionalFactor($factor) + { + foreach ($this->_walkers as $walker) { + $walker->walkConditionalFactor($factor); + } + } + + /** + * Walks down a ConditionalPrimary AST node, thereby generating the appropriate SQL. + * + * @param ConditionalPrimary + * @return string The SQL. + */ + public function walkConditionalPrimary($condPrimary) + { + foreach ($this->_walkers as $walker) { + $walker->walkConditionalPrimary($condPrimary); + } + } + + /** + * Walks down an ExistsExpression AST node, thereby generating the appropriate SQL. + * + * @param ExistsExpression + * @return string The SQL. + */ + public function walkExistsExpression($existsExpr) + { + foreach ($this->_walkers as $walker) { + $walker->walkExistsExpression($existsExpr); + } + } + + /** + * Walks down a CollectionMemberExpression AST node, thereby generating the appropriate SQL. + * + * @param CollectionMemberExpression + * @return string The SQL. + */ + public function walkCollectionMemberExpression($collMemberExpr) + { + foreach ($this->_walkers as $walker) { + $walker->walkCollectionMemberExpression($collMemberExpr); + } + } + + /** + * Walks down an EmptyCollectionComparisonExpression AST node, thereby generating the appropriate SQL. + * + * @param EmptyCollectionComparisonExpression + * @return string The SQL. + */ + public function walkEmptyCollectionComparisonExpression($emptyCollCompExpr) + { + foreach ($this->_walkers as $walker) { + $walker->walkEmptyCollectionComparisonExpression($emptyCollCompExpr); + } + } + + /** + * Walks down a NullComparisonExpression AST node, thereby generating the appropriate SQL. + * + * @param NullComparisonExpression + * @return string The SQL. + */ + public function walkNullComparisonExpression($nullCompExpr) + { + foreach ($this->_walkers as $walker) { + $walker->walkNullComparisonExpression($nullCompExpr); + } + } + + /** + * Walks down an InExpression AST node, thereby generating the appropriate SQL. + * + * @param InExpression + * @return string The SQL. + */ + public function walkInExpression($inExpr) + { + foreach ($this->_walkers as $walker) { + $walker->walkInExpression($inExpr); + } + } + + /** + * Walks down an InstanceOfExpression AST node, thereby generating the appropriate SQL. + * + * @param InstanceOfExpression + * @return string The SQL. + */ + function walkInstanceOfExpression($instanceOfExpr) + { + foreach ($this->_walkers as $walker) { + $walker->walkInstanceOfExpression($instanceOfExpr); + } + } + + /** + * Walks down a literal that represents an AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkLiteral($literal) + { + foreach ($this->_walkers as $walker) { + $walker->walkLiteral($literal); + } + } + + /** + * Walks down a BetweenExpression AST node, thereby generating the appropriate SQL. + * + * @param BetweenExpression + * @return string The SQL. + */ + public function walkBetweenExpression($betweenExpr) + { + foreach ($this->_walkers as $walker) { + $walker->walkBetweenExpression($betweenExpr); + } + } + + /** + * Walks down a LikeExpression AST node, thereby generating the appropriate SQL. + * + * @param LikeExpression + * @return string The SQL. + */ + public function walkLikeExpression($likeExpr) + { + foreach ($this->_walkers as $walker) { + $walker->walkLikeExpression($likeExpr); + } + } + + /** + * Walks down a StateFieldPathExpression AST node, thereby generating the appropriate SQL. + * + * @param StateFieldPathExpression + * @return string The SQL. + */ + public function walkStateFieldPathExpression($stateFieldPathExpression) + { + foreach ($this->_walkers as $walker) { + $walker->walkStateFieldPathExpression($stateFieldPathExpression); + } + } + + /** + * Walks down a ComparisonExpression AST node, thereby generating the appropriate SQL. + * + * @param ComparisonExpression + * @return string The SQL. + */ + public function walkComparisonExpression($compExpr) + { + foreach ($this->_walkers as $walker) { + $walker->walkComparisonExpression($compExpr); + } + } + + /** + * Walks down an InputParameter AST node, thereby generating the appropriate SQL. + * + * @param InputParameter + * @return string The SQL. + */ + public function walkInputParameter($inputParam) + { + foreach ($this->_walkers as $walker) { + $walker->walkInputParameter($inputParam); + } + } + + /** + * Walks down an ArithmeticExpression AST node, thereby generating the appropriate SQL. + * + * @param ArithmeticExpression + * @return string The SQL. + */ + public function walkArithmeticExpression($arithmeticExpr) + { + foreach ($this->_walkers as $walker) { + $walker->walkArithmeticExpression($arithmeticExpr); + } + } + + /** + * Walks down an ArithmeticTerm AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkArithmeticTerm($term) + { + foreach ($this->_walkers as $walker) { + $walker->walkArithmeticTerm($term); + } + } + + /** + * Walks down a StringPrimary that represents an AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkStringPrimary($stringPrimary) + { + foreach ($this->_walkers as $walker) { + $walker->walkStringPrimary($stringPrimary); + } + } + + /** + * Walks down an ArithmeticFactor that represents an AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkArithmeticFactor($factor) + { + foreach ($this->_walkers as $walker) { + $walker->walkArithmeticFactor($factor); + } + } + + /** + * Walks down an SimpleArithmeticExpression AST node, thereby generating the appropriate SQL. + * + * @param SimpleArithmeticExpression + * @return string The SQL. + */ + public function walkSimpleArithmeticExpression($simpleArithmeticExpr) + { + foreach ($this->_walkers as $walker) { + $walker->walkSimpleArithmeticExpression($simpleArithmeticExpr); + } + } + + /** + * Walks down an PathExpression AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkPathExpression($pathExpr) + { + foreach ($this->_walkers as $walker) { + $walker->walkPathExpression($pathExpr); + } + } + + /** + * Walks down an ResultVariable AST node, thereby generating the appropriate SQL. + * + * @param string $resultVariable + * @return string The SQL. + */ + public function walkResultVariable($resultVariable) + { + foreach ($this->_walkers as $walker) { + $walker->walkResultVariable($resultVariable); + } + } + + /** + * Gets an executor that can be used to execute the result of this walker. + * + * @return AbstractExecutor + */ + public function getExecutor($AST) + {} +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/QueryBuilder.php b/vendor/doctrine/orm/lib/Doctrine/ORM/QueryBuilder.php new file mode 100644 index 0000000..5212634 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/QueryBuilder.php @@ -0,0 +1,1115 @@ +. + */ + +namespace Doctrine\ORM; + +use Doctrine\ORM\Query\Expr; + +/** + * This class is responsible for building DQL query strings via an object oriented + * PHP interface. + * + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class QueryBuilder +{ + /* The query types. */ + const SELECT = 0; + const DELETE = 1; + const UPDATE = 2; + + /** The builder states. */ + const STATE_DIRTY = 0; + const STATE_CLEAN = 1; + + /** + * @var EntityManager The EntityManager used by this QueryBuilder. + */ + private $_em; + + /** + * @var array The array of DQL parts collected. + */ + private $_dqlParts = array( + 'distinct' => false, + 'select' => array(), + 'from' => array(), + 'join' => array(), + 'set' => array(), + 'where' => null, + 'groupBy' => array(), + 'having' => null, + 'orderBy' => array() + ); + + /** + * @var integer The type of query this is. Can be select, update or delete. + */ + private $_type = self::SELECT; + + /** + * @var integer The state of the query object. Can be dirty or clean. + */ + private $_state = self::STATE_CLEAN; + + /** + * @var string The complete DQL string for this query. + */ + private $_dql; + + /** + * @var array The query parameters. + */ + private $_params = array(); + + /** + * @var array The parameter type map of this query. + */ + private $_paramTypes = array(); + + /** + * @var integer The index of the first result to retrieve. + */ + private $_firstResult = null; + + /** + * @var integer The maximum number of results to retrieve. + */ + private $_maxResults = null; + + /** + * Initializes a new QueryBuilder that uses the given EntityManager. + * + * @param EntityManager $em The EntityManager to use. + */ + public function __construct(EntityManager $em) + { + $this->_em = $em; + } + + /** + * Gets an ExpressionBuilder used for object-oriented construction of query expressions. + * This producer method is intended for convenient inline usage. Example: + * + * + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->from('User', 'u') + * ->where($qb->expr()->eq('u.id', 1)); + * + * + * For more complex expression construction, consider storing the expression + * builder object in a local variable. + * + * @return Query\Expr + */ + public function expr() + { + return $this->_em->getExpressionBuilder(); + } + + /** + * Get the type of the currently built query. + * + * @return integer + */ + public function getType() + { + return $this->_type; + } + + /** + * Get the associated EntityManager for this query builder. + * + * @return EntityManager + */ + public function getEntityManager() + { + return $this->_em; + } + + /** + * Get the state of this query builder instance. + * + * @return integer Either QueryBuilder::STATE_DIRTY or QueryBuilder::STATE_CLEAN. + */ + public function getState() + { + return $this->_state; + } + + /** + * Get the complete DQL string formed by the current specifications of this QueryBuilder. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->from('User', 'u') + * echo $qb->getDql(); // SELECT u FROM User u + * + * + * @return string The DQL query string. + */ + public function getDQL() + { + if ($this->_dql !== null && $this->_state === self::STATE_CLEAN) { + return $this->_dql; + } + + $dql = ''; + + switch ($this->_type) { + case self::DELETE: + $dql = $this->_getDQLForDelete(); + break; + + case self::UPDATE: + $dql = $this->_getDQLForUpdate(); + break; + + case self::SELECT: + default: + $dql = $this->_getDQLForSelect(); + break; + } + + $this->_state = self::STATE_CLEAN; + $this->_dql = $dql; + + return $dql; + } + + /** + * Constructs a Query instance from the current specifications of the builder. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->from('User', 'u'); + * $q = $qb->getQuery(); + * $results = $q->execute(); + * + * + * @return Query + */ + public function getQuery() + { + return $this->_em->createQuery($this->getDQL()) + ->setParameters($this->_params, $this->_paramTypes) + ->setFirstResult($this->_firstResult) + ->setMaxResults($this->_maxResults); + } + + /** + * Gets the FIRST root alias of the query. This is the first entity alias involved + * in the construction of the query. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->from('User', 'u'); + * + * echo $qb->getRootAlias(); // u + * + * + * @deprecated Please use $qb->getRootAliases() instead. + * @return string $rootAlias + */ + public function getRootAlias() + { + $aliases = $this->getRootAliases(); + return $aliases[0]; + } + + /** + * Gets the root aliases of the query. This is the entity aliases involved + * in the construction of the query. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->from('User', 'u'); + * + * $qb->getRootAliases(); // array('u') + * + * + * @return array $rootAliases + */ + public function getRootAliases() + { + $aliases = array(); + + foreach ($this->_dqlParts['from'] as &$fromClause) { + if (is_string($fromClause)) { + $spacePos = strrpos($fromClause, ' '); + $from = substr($fromClause, 0, $spacePos); + $alias = substr($fromClause, $spacePos + 1); + + $fromClause = new Query\Expr\From($from, $alias); + } + + $aliases[] = $fromClause->getAlias(); + } + + return $aliases; + } + + /** + * Gets the root entities of the query. This is the entity aliases involved + * in the construction of the query. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->from('User', 'u'); + * + * $qb->getRootEntities(); // array('User') + * + * + * @return array $rootEntities + */ + public function getRootEntities() + { + $entities = array(); + + foreach ($this->_dqlParts['from'] as &$fromClause) { + if (is_string($fromClause)) { + $spacePos = strrpos($fromClause, ' '); + $from = substr($fromClause, 0, $spacePos); + $alias = substr($fromClause, $spacePos + 1); + + $fromClause = new Query\Expr\From($from, $alias); + } + + $entities[] = $fromClause->getFrom(); + } + + return $entities; + } + + /** + * Sets a query parameter for the query being constructed. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->from('User', 'u') + * ->where('u.id = :user_id') + * ->setParameter('user_id', 1); + * + * + * @param string|integer $key The parameter position or name. + * @param mixed $value The parameter value. + * @param string|null $type PDO::PARAM_* or \Doctrine\DBAL\Types\Type::* constant + * @return QueryBuilder This QueryBuilder instance. + */ + public function setParameter($key, $value, $type = null) + { + $key = trim($key, ':'); + + if ($type === null) { + $type = Query\ParameterTypeInferer::inferType($value); + } + + $this->_paramTypes[$key] = $type; + $this->_params[$key] = $value; + + return $this; + } + + /** + * Sets a collection of query parameters for the query being constructed. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->from('User', 'u') + * ->where('u.id = :user_id1 OR u.id = :user_id2') + * ->setParameters(array( + * 'user_id1' => 1, + * 'user_id2' => 2 + )); + * + * + * @param array $params The query parameters to set. + * @return QueryBuilder This QueryBuilder instance. + */ + public function setParameters(array $params, array $types = array()) + { + foreach ($params as $key => $value) { + $this->setParameter($key, $value, isset($types[$key]) ? $types[$key] : null); + } + + return $this; + } + + /** + * Gets all defined query parameters for the query being constructed. + * + * @return array The currently defined query parameters. + */ + public function getParameters() + { + return $this->_params; + } + + /** + * Gets a (previously set) query parameter of the query being constructed. + * + * @param mixed $key The key (index or name) of the bound parameter. + * @return mixed The value of the bound parameter. + */ + public function getParameter($key) + { + return isset($this->_params[$key]) ? $this->_params[$key] : null; + } + + /** + * Sets the position of the first result to retrieve (the "offset"). + * + * @param integer $firstResult The first result to return. + * @return QueryBuilder This QueryBuilder instance. + */ + public function setFirstResult($firstResult) + { + $this->_firstResult = $firstResult; + + return $this; + } + + /** + * Gets the position of the first result the query object was set to retrieve (the "offset"). + * Returns NULL if {@link setFirstResult} was not applied to this QueryBuilder. + * + * @return integer The position of the first result. + */ + public function getFirstResult() + { + return $this->_firstResult; + } + + /** + * Sets the maximum number of results to retrieve (the "limit"). + * + * @param integer $maxResults The maximum number of results to retrieve. + * @return QueryBuilder This QueryBuilder instance. + */ + public function setMaxResults($maxResults) + { + $this->_maxResults = $maxResults; + + return $this; + } + + /** + * Gets the maximum number of results the query object was set to retrieve (the "limit"). + * Returns NULL if {@link setMaxResults} was not applied to this query builder. + * + * @return integer Maximum number of results. + */ + public function getMaxResults() + { + return $this->_maxResults; + } + + /** + * Either appends to or replaces a single, generic query part. + * + * The available parts are: 'select', 'from', 'join', 'set', 'where', + * 'groupBy', 'having' and 'orderBy'. + * + * @param string $dqlPartName + * @param string $dqlPart + * @param string $append + * @return QueryBuilder This QueryBuilder instance. + */ + public function add($dqlPartName, $dqlPart, $append = false) + { + $isMultiple = is_array($this->_dqlParts[$dqlPartName]); + + // This is introduced for backwards compatibility reasons. + // TODO: Remove for 3.0 + if ($dqlPartName == 'join') { + $newDqlPart = array(); + foreach ($dqlPart AS $k => $v) { + if (is_numeric($k)) { + $newDqlPart[$this->getRootAlias()] = $v; + } else { + $newDqlPart[$k] = $v; + } + } + $dqlPart = $newDqlPart; + } + + if ($append && $isMultiple) { + if (is_array($dqlPart)) { + $key = key($dqlPart); + + $this->_dqlParts[$dqlPartName][$key][] = $dqlPart[$key]; + } else { + $this->_dqlParts[$dqlPartName][] = $dqlPart; + } + } else { + $this->_dqlParts[$dqlPartName] = ($isMultiple) ? array($dqlPart) : $dqlPart; + } + + $this->_state = self::STATE_DIRTY; + + return $this; + } + + /** + * Specifies an item that is to be returned in the query result. + * Replaces any previously specified selections, if any. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u', 'p') + * ->from('User', 'u') + * ->leftJoin('u.Phonenumbers', 'p'); + * + * + * @param mixed $select The selection expressions. + * @return QueryBuilder This QueryBuilder instance. + */ + public function select($select = null) + { + $this->_type = self::SELECT; + + if (empty($select)) { + return $this; + } + + $selects = is_array($select) ? $select : func_get_args(); + + return $this->add('select', new Expr\Select($selects), false); + } + + /** + * Add a DISTINCT flag to this query. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->distinct() + * ->from('User', 'u'); + * + * + * @param bool + * @return QueryBuilder + */ + public function distinct($flag = true) + { + $this->_dqlParts['distinct'] = (bool) $flag; + return $this; + } + + /** + * Adds an item that is to be returned in the query result. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->addSelect('p') + * ->from('User', 'u') + * ->leftJoin('u.Phonenumbers', 'p'); + * + * + * @param mixed $select The selection expression. + * @return QueryBuilder This QueryBuilder instance. + */ + public function addSelect($select = null) + { + $this->_type = self::SELECT; + + if (empty($select)) { + return $this; + } + + $selects = is_array($select) ? $select : func_get_args(); + + return $this->add('select', new Expr\Select($selects), true); + } + + /** + * Turns the query being built into a bulk delete query that ranges over + * a certain entity type. + * + * + * $qb = $em->createQueryBuilder() + * ->delete('User', 'u') + * ->where('u.id = :user_id'); + * ->setParameter('user_id', 1); + * + * + * @param string $delete The class/type whose instances are subject to the deletion. + * @param string $alias The class/type alias used in the constructed query. + * @return QueryBuilder This QueryBuilder instance. + */ + public function delete($delete = null, $alias = null) + { + $this->_type = self::DELETE; + + if ( ! $delete) { + return $this; + } + + return $this->add('from', new Expr\From($delete, $alias)); + } + + /** + * Turns the query being built into a bulk update query that ranges over + * a certain entity type. + * + * + * $qb = $em->createQueryBuilder() + * ->update('User', 'u') + * ->set('u.password', md5('password')) + * ->where('u.id = ?'); + * + * + * @param string $update The class/type whose instances are subject to the update. + * @param string $alias The class/type alias used in the constructed query. + * @return QueryBuilder This QueryBuilder instance. + */ + public function update($update = null, $alias = null) + { + $this->_type = self::UPDATE; + + if ( ! $update) { + return $this; + } + + return $this->add('from', new Expr\From($update, $alias)); + } + + /** + * Create and add a query root corresponding to the entity identified by the given alias, + * forming a cartesian product with any existing query roots. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->from('User', 'u') + * + * + * @param string $from The class name. + * @param string $alias The alias of the class. + * @param string $indexBy The index for the from. + * @return QueryBuilder This QueryBuilder instance. + */ + public function from($from, $alias, $indexBy = null) + { + return $this->add('from', new Expr\From($from, $alias, $indexBy), true); + } + + /** + * Creates and adds a join over an entity association to the query. + * + * The entities in the joined association will be fetched as part of the query + * result if the alias used for the joined association is placed in the select + * expressions. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->from('User', 'u') + * ->join('u.Phonenumbers', 'p', Expr\Join::WITH, 'p.is_primary = 1'); + * + * + * @param string $join The relationship to join + * @param string $alias The alias of the join + * @param string $conditionType The condition type constant. Either ON or WITH. + * @param string $condition The condition for the join + * @param string $indexBy The index for the join + * @return QueryBuilder This QueryBuilder instance. + */ + public function join($join, $alias, $conditionType = null, $condition = null, $indexBy = null) + { + return $this->innerJoin($join, $alias, $conditionType, $condition, $indexBy); + } + + /** + * Creates and adds a join over an entity association to the query. + * + * The entities in the joined association will be fetched as part of the query + * result if the alias used for the joined association is placed in the select + * expressions. + * + * [php] + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->from('User', 'u') + * ->innerJoin('u.Phonenumbers', 'p', Expr\Join::WITH, 'p.is_primary = 1'); + * + * @param string $join The relationship to join + * @param string $alias The alias of the join + * @param string $conditionType The condition type constant. Either ON or WITH. + * @param string $condition The condition for the join + * @param string $indexBy The index for the join + * @return QueryBuilder This QueryBuilder instance. + */ + public function innerJoin($join, $alias, $conditionType = null, $condition = null, $indexBy = null) + { + $rootAlias = substr($join, 0, strpos($join, '.')); + + if ( ! in_array($rootAlias, $this->getRootAliases())) { + $rootAlias = $this->getRootAlias(); + } + + $join = new Expr\Join( + Expr\Join::INNER_JOIN, $join, $alias, $conditionType, $condition, $indexBy + ); + + return $this->add('join', array($rootAlias => $join), true); + } + + /** + * Creates and adds a left join over an entity association to the query. + * + * The entities in the joined association will be fetched as part of the query + * result if the alias used for the joined association is placed in the select + * expressions. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->from('User', 'u') + * ->leftJoin('u.Phonenumbers', 'p', Expr\Join::WITH, 'p.is_primary = 1'); + * + * + * @param string $join The relationship to join + * @param string $alias The alias of the join + * @param string $conditionType The condition type constant. Either ON or WITH. + * @param string $condition The condition for the join + * @param string $indexBy The index for the join + * @return QueryBuilder This QueryBuilder instance. + */ + public function leftJoin($join, $alias, $conditionType = null, $condition = null, $indexBy = null) + { + $rootAlias = substr($join, 0, strpos($join, '.')); + + if ( ! in_array($rootAlias, $this->getRootAliases())) { + $rootAlias = $this->getRootAlias(); + } + + $join = new Expr\Join( + Expr\Join::LEFT_JOIN, $join, $alias, $conditionType, $condition, $indexBy + ); + + return $this->add('join', array($rootAlias => $join), true); + } + + /** + * Sets a new value for a field in a bulk update query. + * + * + * $qb = $em->createQueryBuilder() + * ->update('User', 'u') + * ->set('u.password', md5('password')) + * ->where('u.id = ?'); + * + * + * @param string $key The key/field to set. + * @param string $value The value, expression, placeholder, etc. + * @return QueryBuilder This QueryBuilder instance. + */ + public function set($key, $value) + { + return $this->add('set', new Expr\Comparison($key, Expr\Comparison::EQ, $value), true); + } + + /** + * Specifies one or more restrictions to the query result. + * Replaces any previously specified restrictions, if any. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->from('User', 'u') + * ->where('u.id = ?'); + * + * // You can optionally programatically build and/or expressions + * $qb = $em->createQueryBuilder(); + * + * $or = $qb->expr()->orx(); + * $or->add($qb->expr()->eq('u.id', 1)); + * $or->add($qb->expr()->eq('u.id', 2)); + * + * $qb->update('User', 'u') + * ->set('u.password', md5('password')) + * ->where($or); + * + * + * @param mixed $predicates The restriction predicates. + * @return QueryBuilder This QueryBuilder instance. + */ + public function where($predicates) + { + if ( ! (func_num_args() == 1 && $predicates instanceof Expr\Composite)) { + $predicates = new Expr\Andx(func_get_args()); + } + + return $this->add('where', $predicates); + } + + /** + * Adds one or more restrictions to the query results, forming a logical + * conjunction with any previously specified restrictions. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->from('User', 'u') + * ->where('u.username LIKE ?') + * ->andWhere('u.is_active = 1'); + * + * + * @param mixed $where The query restrictions. + * @return QueryBuilder This QueryBuilder instance. + * @see where() + */ + public function andWhere($where) + { + $where = $this->getDQLPart('where'); + $args = func_get_args(); + + if ($where instanceof Expr\Andx) { + $where->addMultiple($args); + } else { + array_unshift($args, $where); + $where = new Expr\Andx($args); + } + + return $this->add('where', $where, true); + } + + /** + * Adds one or more restrictions to the query results, forming a logical + * disjunction with any previously specified restrictions. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->from('User', 'u') + * ->where('u.id = 1') + * ->orWhere('u.id = 2'); + * + * + * @param mixed $where The WHERE statement + * @return QueryBuilder $qb + * @see where() + */ + public function orWhere($where) + { + $where = $this->getDqlPart('where'); + $args = func_get_args(); + + if ($where instanceof Expr\Orx) { + $where->addMultiple($args); + } else { + array_unshift($args, $where); + $where = new Expr\Orx($args); + } + + return $this->add('where', $where, true); + } + + /** + * Specifies a grouping over the results of the query. + * Replaces any previously specified groupings, if any. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->from('User', 'u') + * ->groupBy('u.id'); + * + * + * @param string $groupBy The grouping expression. + * @return QueryBuilder This QueryBuilder instance. + */ + public function groupBy($groupBy) + { + return $this->add('groupBy', new Expr\GroupBy(func_get_args())); + } + + + /** + * Adds a grouping expression to the query. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->from('User', 'u') + * ->groupBy('u.lastLogin'); + * ->addGroupBy('u.createdAt') + * + * + * @param string $groupBy The grouping expression. + * @return QueryBuilder This QueryBuilder instance. + */ + public function addGroupBy($groupBy) + { + return $this->add('groupBy', new Expr\GroupBy(func_get_args()), true); + } + + /** + * Specifies a restriction over the groups of the query. + * Replaces any previous having restrictions, if any. + * + * @param mixed $having The restriction over the groups. + * @return QueryBuilder This QueryBuilder instance. + */ + public function having($having) + { + if ( ! (func_num_args() == 1 && ($having instanceof Expr\Andx || $having instanceof Expr\Orx))) { + $having = new Expr\Andx(func_get_args()); + } + + return $this->add('having', $having); + } + + /** + * Adds a restriction over the groups of the query, forming a logical + * conjunction with any existing having restrictions. + * + * @param mixed $having The restriction to append. + * @return QueryBuilder This QueryBuilder instance. + */ + public function andHaving($having) + { + $having = $this->getDqlPart('having'); + $args = func_get_args(); + + if ($having instanceof Expr\Andx) { + $having->addMultiple($args); + } else { + array_unshift($args, $having); + $having = new Expr\Andx($args); + } + + return $this->add('having', $having); + } + + /** + * Adds a restriction over the groups of the query, forming a logical + * disjunction with any existing having restrictions. + * + * @param mixed $having The restriction to add. + * @return QueryBuilder This QueryBuilder instance. + */ + public function orHaving($having) + { + $having = $this->getDqlPart('having'); + $args = func_get_args(); + + if ($having instanceof Expr\Orx) { + $having->addMultiple($args); + } else { + array_unshift($args, $having); + $having = new Expr\Orx($args); + } + + return $this->add('having', $having); + } + + /** + * Specifies an ordering for the query results. + * Replaces any previously specified orderings, if any. + * + * @param string $sort The ordering expression. + * @param string $order The ordering direction. + * @return QueryBuilder This QueryBuilder instance. + */ + public function orderBy($sort, $order = null) + { + return $this->add('orderBy', $sort instanceof Expr\OrderBy ? $sort + : new Expr\OrderBy($sort, $order)); + } + + /** + * Adds an ordering to the query results. + * + * @param string $sort The ordering expression. + * @param string $order The ordering direction. + * @return QueryBuilder This QueryBuilder instance. + */ + public function addOrderBy($sort, $order = null) + { + return $this->add('orderBy', new Expr\OrderBy($sort, $order), true); + } + + /** + * Get a query part by its name. + * + * @param string $queryPartName + * @return mixed $queryPart + * @todo Rename: getQueryPart (or remove?) + */ + public function getDQLPart($queryPartName) + { + return $this->_dqlParts[$queryPartName]; + } + + /** + * Get all query parts. + * + * @return array $dqlParts + * @todo Rename: getQueryParts (or remove?) + */ + public function getDQLParts() + { + return $this->_dqlParts; + } + + private function _getDQLForDelete() + { + return 'DELETE' + . $this->_getReducedDQLQueryPart('from', array('pre' => ' ', 'separator' => ', ')) + . $this->_getReducedDQLQueryPart('where', array('pre' => ' WHERE ')) + . $this->_getReducedDQLQueryPart('orderBy', array('pre' => ' ORDER BY ', 'separator' => ', ')); + } + + private function _getDQLForUpdate() + { + return 'UPDATE' + . $this->_getReducedDQLQueryPart('from', array('pre' => ' ', 'separator' => ', ')) + . $this->_getReducedDQLQueryPart('set', array('pre' => ' SET ', 'separator' => ', ')) + . $this->_getReducedDQLQueryPart('where', array('pre' => ' WHERE ')) + . $this->_getReducedDQLQueryPart('orderBy', array('pre' => ' ORDER BY ', 'separator' => ', ')); + } + + private function _getDQLForSelect() + { + $dql = 'SELECT' + . ($this->_dqlParts['distinct']===true ? ' DISTINCT' : '') + . $this->_getReducedDQLQueryPart('select', array('pre' => ' ', 'separator' => ', ')); + + $fromParts = $this->getDQLPart('from'); + $joinParts = $this->getDQLPart('join'); + $fromClauses = array(); + + // Loop through all FROM clauses + if ( ! empty($fromParts)) { + $dql .= ' FROM '; + + foreach ($fromParts as $from) { + $fromClause = (string) $from; + + if ($from instanceof Expr\From && isset($joinParts[$from->getAlias()])) { + foreach ($joinParts[$from->getAlias()] as $join) { + $fromClause .= ' ' . ((string) $join); + } + } + + $fromClauses[] = $fromClause; + } + } + + $dql .= implode(', ', $fromClauses) + . $this->_getReducedDQLQueryPart('where', array('pre' => ' WHERE ')) + . $this->_getReducedDQLQueryPart('groupBy', array('pre' => ' GROUP BY ', 'separator' => ', ')) + . $this->_getReducedDQLQueryPart('having', array('pre' => ' HAVING ')) + . $this->_getReducedDQLQueryPart('orderBy', array('pre' => ' ORDER BY ', 'separator' => ', ')); + + return $dql; + } + + private function _getReducedDQLQueryPart($queryPartName, $options = array()) + { + $queryPart = $this->getDQLPart($queryPartName); + + if (empty($queryPart)) { + return (isset($options['empty']) ? $options['empty'] : ''); + } + + return (isset($options['pre']) ? $options['pre'] : '') + . (is_array($queryPart) ? implode($options['separator'], $queryPart) : $queryPart) + . (isset($options['post']) ? $options['post'] : ''); + } + + /** + * Reset DQL parts + * + * @param array $parts + * @return QueryBuilder + */ + public function resetDQLParts($parts = null) + { + if (is_null($parts)) { + $parts = array_keys($this->_dqlParts); + } + foreach ($parts as $part) { + $this->resetDQLPart($part); + } + return $this; + } + + /** + * Reset single DQL part + * + * @param string $part + * @return QueryBuilder; + */ + public function resetDQLPart($part) + { + if (is_array($this->_dqlParts[$part])) { + $this->_dqlParts[$part] = array(); + } else { + $this->_dqlParts[$part] = null; + } + $this->_state = self::STATE_DIRTY; + return $this; + } + + /** + * Gets a string representation of this QueryBuilder which corresponds to + * the final DQL query being constructed. + * + * @return string The string representation of this QueryBuilder. + */ + public function __toString() + { + return $this->getDQL(); + } + + /** + * Deep clone of all expression objects in the DQL parts. + * + * @return void + */ + public function __clone() + { + foreach ($this->_dqlParts AS $part => $elements) { + if (is_array($this->_dqlParts[$part])) { + foreach ($this->_dqlParts[$part] AS $idx => $element) { + if (is_object($element)) { + $this->_dqlParts[$part][$idx] = clone $element; + } + } + } else if (\is_object($elements)) { + $this->_dqlParts[$part] = clone $elements; + } + } + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/README.markdown b/vendor/doctrine/orm/lib/Doctrine/ORM/README.markdown new file mode 100644 index 0000000..e69de29 diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/MetadataCommand.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/MetadataCommand.php new file mode 100644 index 0000000..afff8db --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/MetadataCommand.php @@ -0,0 +1,104 @@ +. + */ + +namespace Doctrine\ORM\Tools\Console\Command\ClearCache; + +use Symfony\Component\Console\Input\InputArgument, + Symfony\Component\Console\Input\InputOption, + Symfony\Component\Console, + Doctrine\Common\Cache; + +/** + * Command to clear the metadata cache of the various cache drivers. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class MetadataCommand extends Console\Command\Command +{ + /** + * @see Console\Command\Command + */ + protected function configure() + { + $this + ->setName('orm:clear-cache:metadata') + ->setDescription('Clear all metadata cache of the various cache drivers.') + ->setDefinition(array( + new InputOption( + 'flush', null, InputOption::VALUE_NONE, + 'If defined, cache entries will be flushed instead of deleted/invalidated.' + ) + )); + + $fullName = $this->getName(); + $this->setHelp(<<$fullName command is meant to clear the metadata cache of associated Entity Manager. +It is possible to invalidate all cache entries at once - called delete -, or flushes the cache provider +instance completely. + +The execution type differ on how you execute the command. +If you want to invalidate the entries (and not delete from cache instance), this command would do the work: + +$fullName + +Alternatively, if you want to flush the cache provider using this command: + +$fullName --flush + +Finally, be aware that if --flush option is passed, not all cache providers are able to flush entries, +because of a limitation of its execution nature. +EOT + ); + } + + /** + * @see Console\Command\Command + */ + protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output) + { + $em = $this->getHelper('em')->getEntityManager(); + $cacheDriver = $em->getConfiguration()->getMetadataCacheImpl(); + + if ( ! $cacheDriver) { + throw new \InvalidArgumentException('No Metadata cache driver is configured on given EntityManager.'); + } + + if ($cacheDriver instanceof Cache\ApcCache) { + throw new \LogicException("Cannot clear APC Cache from Console, its shared in the Webserver memory and not accessible from the CLI."); + } + + $output->write('Clearing ALL Metadata cache entries' . PHP_EOL); + + $result = $cacheDriver->deleteAll(); + $message = ($result) ? 'Successfully deleted cache entries.' : 'No cache entries were deleted.'; + + if (true === $input->getOption('flush')) { + $result = $cacheDriver->flushAll(); + $message = ($result) ? 'Successfully flushed cache entries.' : $message; + } + + $output->write($message . PHP_EOL); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryCommand.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryCommand.php new file mode 100644 index 0000000..6ad75cd --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryCommand.php @@ -0,0 +1,104 @@ +. + */ + +namespace Doctrine\ORM\Tools\Console\Command\ClearCache; + +use Symfony\Component\Console\Input\InputArgument, + Symfony\Component\Console\Input\InputOption, + Symfony\Component\Console, + Doctrine\Common\Cache; + +/** + * Command to clear the query cache of the various cache drivers. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class QueryCommand extends Console\Command\Command +{ + /** + * @see Console\Command\Command + */ + protected function configure() + { + $this + ->setName('orm:clear-cache:query') + ->setDescription('Clear all query cache of the various cache drivers.') + ->setDefinition(array( + new InputOption( + 'flush', null, InputOption::VALUE_NONE, + 'If defined, cache entries will be flushed instead of deleted/invalidated.' + ) + )); + + $fullName = $this->getName(); + $this->setHelp(<<$fullName command is meant to clear the query cache of associated Entity Manager. +It is possible to invalidate all cache entries at once - called delete -, or flushes the cache provider +instance completely. + +The execution type differ on how you execute the command. +If you want to invalidate the entries (and not delete from cache instance), this command would do the work: + +$fullName + +Alternatively, if you want to flush the cache provider using this command: + +$fullName --flush + +Finally, be aware that if --flush option is passed, not all cache providers are able to flush entries, +because of a limitation of its execution nature. +EOT + ); + } + + /** + * @see Console\Command\Command + */ + protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output) + { + $em = $this->getHelper('em')->getEntityManager(); + $cacheDriver = $em->getConfiguration()->getQueryCacheImpl(); + + if ( ! $cacheDriver) { + throw new \InvalidArgumentException('No Query cache driver is configured on given EntityManager.'); + } + + if ($cacheDriver instanceof Cache\ApcCache) { + throw new \LogicException("Cannot clear APC Cache from Console, its shared in the Webserver memory and not accessible from the CLI."); + } + + $output->write('Clearing ALL Query cache entries' . PHP_EOL); + + $result = $cacheDriver->deleteAll(); + $message = ($result) ? 'Successfully deleted cache entries.' : 'No cache entries were deleted.'; + + if (true === $input->getOption('flush')) { + $result = $cacheDriver->flushAll(); + $message = ($result) ? 'Successfully flushed cache entries.' : $message; + } + + $output->write($message . PHP_EOL); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php new file mode 100644 index 0000000..5bb000c --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php @@ -0,0 +1,104 @@ +. + */ + +namespace Doctrine\ORM\Tools\Console\Command\ClearCache; + +use Symfony\Component\Console\Input\InputArgument, + Symfony\Component\Console\Input\InputOption, + Symfony\Component\Console, + Doctrine\Common\Cache; + +/** + * Command to clear the result cache of the various cache drivers. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class ResultCommand extends Console\Command\Command +{ + /** + * @see Console\Command\Command + */ + protected function configure() + { + $this + ->setName('orm:clear-cache:result') + ->setDescription('Clear all result cache of the various cache drivers.') + ->setDefinition(array( + new InputOption( + 'flush', null, InputOption::VALUE_NONE, + 'If defined, cache entries will be flushed instead of deleted/invalidated.' + ) + )); + + $fullName = $this->getName(); + $this->setHelp(<<$fullName command is meant to clear the result cache of associated Entity Manager. +It is possible to invalidate all cache entries at once - called delete -, or flushes the cache provider +instance completely. + +The execution type differ on how you execute the command. +If you want to invalidate the entries (and not delete from cache instance), this command would do the work: + +$fullName + +Alternatively, if you want to flush the cache provider using this command: + +$fullName --flush + +Finally, be aware that if --flush option is passed, not all cache providers are able to flush entries, +because of a limitation of its execution nature. +EOT + ); + } + + /** + * @see Console\Command\Command + */ + protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output) + { + $em = $this->getHelper('em')->getEntityManager(); + $cacheDriver = $em->getConfiguration()->getResultCacheImpl(); + + if ( ! $cacheDriver) { + throw new \InvalidArgumentException('No Result cache driver is configured on given EntityManager.'); + } + + if ($cacheDriver instanceof Cache\ApcCache) { + throw new \LogicException("Cannot clear APC Cache from Console, its shared in the Webserver memory and not accessible from the CLI."); + } + + $output->write('Clearing ALL Result cache entries' . PHP_EOL); + + $result = $cacheDriver->deleteAll(); + $message = ($result) ? 'Successfully deleted cache entries.' : 'No cache entries were deleted.'; + + if (true === $input->getOption('flush')) { + $result = $cacheDriver->flushAll(); + $message = ($result) ? 'Successfully flushed cache entries.' : $message; + } + + $output->write($message . PHP_EOL); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php new file mode 100644 index 0000000..c78920b --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php @@ -0,0 +1,223 @@ +. + */ + +namespace Doctrine\ORM\Tools\Console\Command; + +use Symfony\Component\Console\Input\InputArgument, + Symfony\Component\Console\Input\InputOption, + Symfony\Component\Console, + Doctrine\ORM\Tools\Export\ClassMetadataExporter, + Doctrine\ORM\Tools\ConvertDoctrine1Schema, + Doctrine\ORM\Tools\EntityGenerator; + +/** + * Command to convert a Doctrine 1 schema to a Doctrine 2 mapping file. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class ConvertDoctrine1SchemaCommand extends Console\Command\Command +{ + /** + * @var EntityGenerator + */ + private $entityGenerator = null; + + /** + * @var ClassMetadataExporter + */ + private $metadataExporter = null; + + /** + * @return EntityGenerator + */ + public function getEntityGenerator() + { + if ($this->entityGenerator == null) { + $this->entityGenerator = new EntityGenerator(); + } + + return $this->entityGenerator; + } + + /** + * @param EntityGenerator $entityGenerator + */ + public function setEntityGenerator(EntityGenerator $entityGenerator) + { + $this->entityGenerator = $entityGenerator; + } + + /** + * @return ClassMetadataExporter + */ + public function getMetadataExporter() + { + if ($this->metadataExporter == null) { + $this->metadataExporter = new ClassMetadataExporter(); + } + + return $this->metadataExporter; + } + + /** + * @param ClassMetadataExporter $metadataExporter + */ + public function setMetadataExporter(ClassMetadataExporter $metadataExporter) + { + $this->metadataExporter = $metadataExporter; + } + + /** + * @see Console\Command\Command + */ + protected function configure() + { + $this + ->setName('orm:convert-d1-schema') + ->setDescription('Converts Doctrine 1.X schema into a Doctrine 2.X schema.') + ->setDefinition(array( + new InputArgument( + 'from-path', InputArgument::REQUIRED, 'The path of Doctrine 1.X schema information.' + ), + new InputArgument( + 'to-type', InputArgument::REQUIRED, 'The destination Doctrine 2.X mapping type.' + ), + new InputArgument( + 'dest-path', InputArgument::REQUIRED, + 'The path to generate your Doctrine 2.X mapping information.' + ), + new InputOption( + 'from', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, + 'Optional paths of Doctrine 1.X schema information.', + array() + ), + new InputOption( + 'extend', null, InputOption::VALUE_OPTIONAL, + 'Defines a base class to be extended by generated entity classes.' + ), + new InputOption( + 'num-spaces', null, InputOption::VALUE_OPTIONAL, + 'Defines the number of indentation spaces', 4 + ) + )) + ->setHelp(<<getHelper('em')->getEntityManager(); + + // Process source directories + $fromPaths = array_merge(array($input->getArgument('from-path')), $input->getOption('from')); + + // Process destination directory + $destPath = realpath($input->getArgument('dest-path')); + + $toType = $input->getArgument('to-type'); + $extend = $input->getOption('extend'); + $numSpaces = $input->getOption('num-spaces'); + + $this->convertDoctrine1Schema($em, $fromPaths, $destPath, $toType, $numSpaces, $extend, $output); + } + + /** + * @param \Doctrine\ORM\EntityManager $em + * @param array $fromPaths + * @param string $destPath + * @param string $toType + * @param int $numSpaces + * @param string|null $extend + * @param Console\Output\OutputInterface $output + */ + public function convertDoctrine1Schema($em, $fromPaths, $destPath, $toType, $numSpaces, $extend, $output) + { + foreach ($fromPaths as &$dirName) { + $dirName = realpath($dirName); + + if ( ! file_exists($dirName)) { + throw new \InvalidArgumentException( + sprintf("Doctrine 1.X schema directory '%s' does not exist.", $dirName) + ); + } else if ( ! is_readable($dirName)) { + throw new \InvalidArgumentException( + sprintf("Doctrine 1.X schema directory '%s' does not have read permissions.", $dirName) + ); + } + } + + if ( ! file_exists($destPath)) { + throw new \InvalidArgumentException( + sprintf("Doctrine 2.X mapping destination directory '%s' does not exist.", $destPath) + ); + } else if ( ! is_writable($destPath)) { + throw new \InvalidArgumentException( + sprintf("Doctrine 2.X mapping destination directory '%s' does not have write permissions.", $destPath) + ); + } + + $cme = $this->getMetadataExporter(); + $exporter = $cme->getExporter($toType, $destPath); + + if (strtolower($toType) === 'annotation') { + $entityGenerator = $this->getEntityGenerator(); + $exporter->setEntityGenerator($entityGenerator); + + $entityGenerator->setNumSpaces($numSpaces); + + if ($extend !== null) { + $entityGenerator->setClassToExtend($extend); + } + } + + $converter = new ConvertDoctrine1Schema($fromPaths); + $metadata = $converter->getMetadata(); + + if ($metadata) { + $output->write(PHP_EOL); + + foreach ($metadata as $class) { + $output->write(sprintf('Processing entity "%s"', $class->name) . PHP_EOL); + } + + $exporter->setMetadata($metadata); + $exporter->export(); + + $output->write(PHP_EOL . sprintf( + 'Converting Doctrine 1.X schema to "%s" mapping type in "%s"', $toType, $destPath + )); + } else { + $output->write('No Metadata Classes to process.' . PHP_EOL); + } + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php new file mode 100644 index 0000000..03af43a --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php @@ -0,0 +1,186 @@ +. + */ + +namespace Doctrine\ORM\Tools\Console\Command; + +use Symfony\Component\Console\Input\InputArgument, + Symfony\Component\Console\Input\InputOption, + Symfony\Component\Console, + Doctrine\ORM\Tools\Console\MetadataFilter, + Doctrine\ORM\Tools\Export\ClassMetadataExporter, + Doctrine\ORM\Tools\EntityGenerator, + Doctrine\ORM\Tools\DisconnectedClassMetadataFactory; + +/** + * Command to convert your mapping information between the various formats. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class ConvertMappingCommand extends Console\Command\Command +{ + /** + * @see Console\Command\Command + */ + protected function configure() + { + $this + ->setName('orm:convert-mapping') + ->setDescription('Convert mapping information between supported formats.') + ->setDefinition(array( + new InputOption( + 'filter', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, + 'A string pattern used to match entities that should be processed.' + ), + new InputArgument( + 'to-type', InputArgument::REQUIRED, 'The mapping type to be converted.' + ), + new InputArgument( + 'dest-path', InputArgument::REQUIRED, + 'The path to generate your entities classes.' + ), + new InputOption( + 'force', null, InputOption::VALUE_NONE, + 'Force to overwrite existing mapping files.' + ), + new InputOption( + 'from-database', null, null, 'Whether or not to convert mapping information from existing database.' + ), + new InputOption( + 'extend', null, InputOption::VALUE_OPTIONAL, + 'Defines a base class to be extended by generated entity classes.' + ), + new InputOption( + 'num-spaces', null, InputOption::VALUE_OPTIONAL, + 'Defines the number of indentation spaces', 4 + ), + new InputOption( + 'namespace', null, InputOption::VALUE_OPTIONAL, + 'Defines a namespace for the generated entity classes, if converted from database.' + ), + )) + ->setHelp(<<one-time command. It should not be necessary for +you to call this method multiple times, escpecially when using the --from-database +flag. + +Converting an existing databsae schema into mapping files only solves about 70-80% +of the necessary mapping information. Additionally the detection from an existing +database cannot detect inverse associations, inheritance types, +entities with foreign keys as primary keys and many of the +semantical operations on associations such as cascade. + +Hint: There is no need to convert YAML or XML mapping files to annotations +every time you make changes. All mapping drivers are first class citizens +in Doctrine 2 and can be used as runtime mapping for the ORM. +EOT + ); + } + + /** + * @see Console\Command\Command + */ + protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output) + { + $em = $this->getHelper('em')->getEntityManager(); + + if ($input->getOption('from-database') === true) { + $databaseDriver = new \Doctrine\ORM\Mapping\Driver\DatabaseDriver( + $em->getConnection()->getSchemaManager() + ); + + $em->getConfiguration()->setMetadataDriverImpl( + $databaseDriver + ); + + if (($namespace = $input->getOption('namespace')) !== null) { + $databaseDriver->setNamespace($namespace); + } + } + + $cmf = new DisconnectedClassMetadataFactory(); + $cmf->setEntityManager($em); + $metadata = $cmf->getAllMetadata(); + $metadata = MetadataFilter::filter($metadata, $input->getOption('filter')); + + // Process destination directory + if ( ! is_dir($destPath = $input->getArgument('dest-path'))) { + mkdir($destPath, 0777, true); + } + $destPath = realpath($destPath); + + if ( ! file_exists($destPath)) { + throw new \InvalidArgumentException( + sprintf("Mapping destination directory '%s' does not exist.", $input->getArgument('dest-path')) + ); + } else if ( ! is_writable($destPath)) { + throw new \InvalidArgumentException( + sprintf("Mapping destination directory '%s' does not have write permissions.", $destPath) + ); + } + + $toType = strtolower($input->getArgument('to-type')); + + $exporter = $this->getExporter($toType, $destPath); + $exporter->setOverwriteExistingFiles( ($input->getOption('force') !== false) ); + + if ($toType == 'annotation') { + $entityGenerator = new EntityGenerator(); + $exporter->setEntityGenerator($entityGenerator); + + $entityGenerator->setNumSpaces($input->getOption('num-spaces')); + + if (($extend = $input->getOption('extend')) !== null) { + $entityGenerator->setClassToExtend($extend); + } + } + + if (count($metadata)) { + foreach ($metadata as $class) { + $output->write(sprintf('Processing entity "%s"', $class->name) . PHP_EOL); + } + + $exporter->setMetadata($metadata); + $exporter->export(); + + $output->write(PHP_EOL . sprintf( + 'Exporting "%s" mapping information to "%s"' . PHP_EOL, $toType, $destPath + )); + } else { + $output->write('No Metadata Classes to process.' . PHP_EOL); + } + } + + protected function getExporter($toType, $destPath) + { + $cme = new ClassMetadataExporter(); + + return $cme->getExporter($toType, $destPath); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/EnsureProductionSettingsCommand.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/EnsureProductionSettingsCommand.php new file mode 100644 index 0000000..d29bfce --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/EnsureProductionSettingsCommand.php @@ -0,0 +1,85 @@ +. + */ + +namespace Doctrine\ORM\Tools\Console\Command; + +use Symfony\Component\Console\Input\InputArgument, + Symfony\Component\Console\Input\InputOption, + Symfony\Component\Console; + +/** + * Command to ensure that Doctrine is properly configured for a production environment. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class EnsureProductionSettingsCommand extends Console\Command\Command +{ + /** + * @see Console\Command\Command + */ + protected function configure() + { + $this + ->setName('orm:ensure-production-settings') + ->setDescription('Verify that Doctrine is properly configured for a production environment.') + ->setDefinition(array( + new InputOption( + 'complete', null, InputOption::VALUE_NONE, + 'Flag to also inspect database connection existance.' + ) + )) + ->setHelp(<<getHelper('em')->getEntityManager(); + + $error = false; + try { + $em->getConfiguration()->ensureProductionSettings(); + + if ($input->getOption('complete') !== null) { + $em->getConnection()->connect(); + } + } catch (\Exception $e) { + $error = true; + $output->writeln('' . $e->getMessage() . ''); + } + + if ($error === false) { + $output->write('Environment is correctly configured for production.' . PHP_EOL); + } + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php new file mode 100644 index 0000000..f00e6d2 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php @@ -0,0 +1,163 @@ +. + */ + +namespace Doctrine\ORM\Tools\Console\Command; + +use Symfony\Component\Console\Input\InputArgument, + Symfony\Component\Console\Input\InputOption, + Symfony\Component\Console, + Doctrine\ORM\Tools\Console\MetadataFilter, + Doctrine\ORM\Tools\EntityGenerator, + Doctrine\ORM\Tools\DisconnectedClassMetadataFactory; + +/** + * Command to generate entity classes and method stubs from your mapping information. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class GenerateEntitiesCommand extends Console\Command\Command +{ + /** + * @see Console\Command\Command + */ + protected function configure() + { + $this + ->setName('orm:generate-entities') + ->setDescription('Generate entity classes and method stubs from your mapping information.') + ->setDefinition(array( + new InputOption( + 'filter', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, + 'A string pattern used to match entities that should be processed.' + ), + new InputArgument( + 'dest-path', InputArgument::REQUIRED, 'The path to generate your entity classes.' + ), + new InputOption( + 'generate-annotations', null, InputOption::VALUE_OPTIONAL, + 'Flag to define if generator should generate annotation metadata on entities.', false + ), + new InputOption( + 'generate-methods', null, InputOption::VALUE_OPTIONAL, + 'Flag to define if generator should generate stub methods on entities.', true + ), + new InputOption( + 'regenerate-entities', null, InputOption::VALUE_OPTIONAL, + 'Flag to define if generator should regenerate entity if it exists.', false + ), + new InputOption( + 'update-entities', null, InputOption::VALUE_OPTIONAL, + 'Flag to define if generator should only update entity if it exists.', true + ), + new InputOption( + 'extend', null, InputOption::VALUE_OPTIONAL, + 'Defines a base class to be extended by generated entity classes.' + ), + new InputOption( + 'num-spaces', null, InputOption::VALUE_OPTIONAL, + 'Defines the number of indentation spaces', 4 + ) + )) + ->setHelp(<<--update-entities or --regenerate-entities flags your exisiting +code gets overwritten. The EntityGenerator will only append new code to your +file and will not delete the old code. However this approach may still be prone +to error and we suggest you use code repositories such as GIT or SVN to make +backups of your code. + +It makes sense to generate the entity code if you are using entities as Data +Access Objects only and dont put much additional logic on them. If you are +however putting much more logic on the entities you should refrain from using +the entity-generator and code your entities manually. + +Important: Even if you specified Inheritance options in your +XML or YAML Mapping files the generator cannot generate the base and +child classes for you correctly, because it doesn't know which +class is supposed to extend which. You have to adjust the entity +code manually for inheritance to work! +EOT + ); + } + + /** + * @see Console\Command\Command + */ + protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output) + { + $em = $this->getHelper('em')->getEntityManager(); + + $cmf = new DisconnectedClassMetadataFactory(); + $cmf->setEntityManager($em); + $metadatas = $cmf->getAllMetadata(); + $metadatas = MetadataFilter::filter($metadatas, $input->getOption('filter')); + + // Process destination directory + $destPath = realpath($input->getArgument('dest-path')); + + if ( ! file_exists($destPath)) { + throw new \InvalidArgumentException( + sprintf("Entities destination directory '%s' does not exist.", $input->getArgument('dest-path')) + ); + } else if ( ! is_writable($destPath)) { + throw new \InvalidArgumentException( + sprintf("Entities destination directory '%s' does not have write permissions.", $destPath) + ); + } + + if (count($metadatas)) { + // Create EntityGenerator + $entityGenerator = new EntityGenerator(); + + $entityGenerator->setGenerateAnnotations($input->getOption('generate-annotations')); + $entityGenerator->setGenerateStubMethods($input->getOption('generate-methods')); + $entityGenerator->setRegenerateEntityIfExists($input->getOption('regenerate-entities')); + $entityGenerator->setUpdateEntityIfExists($input->getOption('update-entities')); + $entityGenerator->setNumSpaces($input->getOption('num-spaces')); + + if (($extend = $input->getOption('extend')) !== null) { + $entityGenerator->setClassToExtend($extend); + } + + foreach ($metadatas as $metadata) { + $output->write( + sprintf('Processing entity "%s"', $metadata->name) . PHP_EOL + ); + } + + // Generating Entities + $entityGenerator->generate($metadatas, $destPath); + + // Outputting information message + $output->write(PHP_EOL . sprintf('Entity classes generated to "%s"', $destPath) . PHP_EOL); + } else { + $output->write('No Metadata Classes to process.' . PHP_EOL); + } + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php new file mode 100644 index 0000000..7028d99 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php @@ -0,0 +1,115 @@ +. + */ + +namespace Doctrine\ORM\Tools\Console\Command; + +use Symfony\Component\Console\Input\InputArgument, + Symfony\Component\Console\Input\InputOption, + Symfony\Component\Console, + Doctrine\ORM\Tools\Console\MetadataFilter; + +/** + * Command to (re)generate the proxy classes used by doctrine. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class GenerateProxiesCommand extends Console\Command\Command +{ + /** + * @see Console\Command\Command + */ + protected function configure() + { + $this + ->setName('orm:generate-proxies') + ->setDescription('Generates proxy classes for entity classes.') + ->setDefinition(array( + new InputOption( + 'filter', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, + 'A string pattern used to match entities that should be processed.' + ), + new InputArgument( + 'dest-path', InputArgument::OPTIONAL, + 'The path to generate your proxy classes. If none is provided, it will attempt to grab from configuration.' + ), + )) + ->setHelp(<<getHelper('em')->getEntityManager(); + + $metadatas = $em->getMetadataFactory()->getAllMetadata(); + $metadatas = MetadataFilter::filter($metadatas, $input->getOption('filter')); + + // Process destination directory + if (($destPath = $input->getArgument('dest-path')) === null) { + $destPath = $em->getConfiguration()->getProxyDir(); + } + + if ( ! is_dir($destPath)) { + mkdir($destPath, 0777, true); + } + + $destPath = realpath($destPath); + + if ( ! file_exists($destPath)) { + throw new \InvalidArgumentException( + sprintf("Proxies destination directory '%s' does not exist.", $em->getConfiguration()->getProxyDir()) + ); + } else if ( ! is_writable($destPath)) { + throw new \InvalidArgumentException( + sprintf("Proxies destination directory '%s' does not have write permissions.", $destPath) + ); + } + + if ( count($metadatas)) { + foreach ($metadatas as $metadata) { + $output->write( + sprintf('Processing entity "%s"', $metadata->name) . PHP_EOL + ); + } + + // Generating Proxies + $em->getProxyFactory()->generateProxyClasses($metadatas, $destPath); + + // Outputting information message + $output->write(PHP_EOL . sprintf('Proxy classes generated to "%s"', $destPath) . PHP_EOL); + } else { + $output->write('No Metadata Classes to process.' . PHP_EOL); + } + + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php new file mode 100644 index 0000000..bb6fc9d --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php @@ -0,0 +1,116 @@ +. + */ + +namespace Doctrine\ORM\Tools\Console\Command; + +use Symfony\Component\Console\Input\InputArgument, + Symfony\Component\Console\Input\InputOption, + Symfony\Component\Console, + Doctrine\ORM\Tools\Console\MetadataFilter, + Doctrine\ORM\Tools\EntityRepositoryGenerator; + +/** + * Command to generate repository classes for mapping information. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class GenerateRepositoriesCommand extends Console\Command\Command +{ + /** + * @see Console\Command\Command + */ + protected function configure() + { + $this + ->setName('orm:generate-repositories') + ->setDescription('Generate repository classes from your mapping information.') + ->setDefinition(array( + new InputOption( + 'filter', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, + 'A string pattern used to match entities that should be processed.' + ), + new InputArgument( + 'dest-path', InputArgument::REQUIRED, 'The path to generate your repository classes.' + ) + )) + ->setHelp(<<getHelper('em')->getEntityManager(); + + $metadatas = $em->getMetadataFactory()->getAllMetadata(); + $metadatas = MetadataFilter::filter($metadatas, $input->getOption('filter')); + + // Process destination directory + $destPath = realpath($input->getArgument('dest-path')); + + if ( ! file_exists($destPath)) { + throw new \InvalidArgumentException( + sprintf("Entities destination directory '%s' does not exist.", $input->getArgument('dest-path')) + ); + } else if ( ! is_writable($destPath)) { + throw new \InvalidArgumentException( + sprintf("Entities destination directory '%s' does not have write permissions.", $destPath) + ); + } + + if (count($metadatas)) { + $numRepositories = 0; + $generator = new EntityRepositoryGenerator(); + + foreach ($metadatas as $metadata) { + if ($metadata->customRepositoryClassName) { + $output->write( + sprintf('Processing repository "%s"', $metadata->customRepositoryClassName) . PHP_EOL + ); + + $generator->writeEntityRepositoryClass($metadata->customRepositoryClassName, $destPath); + + $numRepositories++; + } + } + + if ($numRepositories) { + // Outputting information message + $output->write(PHP_EOL . sprintf('Repository classes generated to "%s"', $destPath) . PHP_EOL); + } else { + $output->write('No Repository classes were found to be processed.' . PHP_EOL); + } + } else { + $output->write('No Metadata Classes to process.' . PHP_EOL); + } + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/InfoCommand.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/InfoCommand.php new file mode 100644 index 0000000..77458cf --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/InfoCommand.php @@ -0,0 +1,80 @@ +. + */ + +namespace Doctrine\ORM\Tools\Console\Command; + +use Doctrine\ORM\Mapping\MappingException; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Command\Command; + +/** + * Show information about mapped entities + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.1 + * @author Benjamin Eberlei + */ +class InfoCommand extends Command +{ + protected function configure() + { + $this + ->setName('orm:info') + ->setDescription('Show basic information about all mapped entities') + ->setHelp(<<doctrine:mapping:info shows basic information about which +entities exist and possibly if their mapping information contains errors or +not. +EOT + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + /* @var $entityManager \Doctrine\ORM\EntityManager */ + $entityManager = $this->getHelper('em')->getEntityManager(); + + $entityClassNames = $entityManager->getConfiguration() + ->getMetadataDriverImpl() + ->getAllClassNames(); + + if (!$entityClassNames) { + throw new \Exception( + 'You do not have any mapped Doctrine ORM entities according to the current configuration. '. + 'If you have entities or mapping files you should check your mapping configuration for errors.' + ); + } + + $output->writeln(sprintf("Found %d mapped entities:", count($entityClassNames))); + + foreach ($entityClassNames as $entityClassName) { + try { + $cm = $entityManager->getClassMetadata($entityClassName); + $output->writeln(sprintf("[OK] %s", $entityClassName)); + } catch (MappingException $e) { + $output->writeln("[FAIL] ".$entityClassName); + $output->writeln(sprintf("%s", $e->getMessage())); + $output->writeln(''); + } + } + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php new file mode 100644 index 0000000..c794cb9 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php @@ -0,0 +1,124 @@ +. + */ + +namespace Doctrine\ORM\Tools\Console\Command; + +use Symfony\Component\Console\Input\InputArgument, + Symfony\Component\Console\Input\InputOption, + Symfony\Component\Console; + +/** + * Command to execute DQL queries in a given EntityManager. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class RunDqlCommand extends Console\Command\Command +{ + /** + * @see Console\Command\Command + */ + protected function configure() + { + $this + ->setName('orm:run-dql') + ->setDescription('Executes arbitrary DQL directly from the command line.') + ->setDefinition(array( + new InputArgument('dql', InputArgument::REQUIRED, 'The DQL to execute.'), + new InputOption( + 'hydrate', null, InputOption::VALUE_REQUIRED, + 'Hydration mode of result set. Should be either: object, array, scalar or single-scalar.', + 'object' + ), + new InputOption( + 'first-result', null, InputOption::VALUE_REQUIRED, + 'The first result in the result set.' + ), + new InputOption( + 'max-result', null, InputOption::VALUE_REQUIRED, + 'The maximum number of results in the result set.' + ), + new InputOption( + 'depth', null, InputOption::VALUE_REQUIRED, + 'Dumping depth of Entity graph.', 7 + ) + )) + ->setHelp(<<getHelper('em')->getEntityManager(); + + if (($dql = $input->getArgument('dql')) === null) { + throw new \RuntimeException("Argument 'DQL' is required in order to execute this command correctly."); + } + + $depth = $input->getOption('depth'); + + if ( ! is_numeric($depth)) { + throw new \LogicException("Option 'depth' must contains an integer value"); + } + + $hydrationModeName = $input->getOption('hydrate'); + $hydrationMode = 'Doctrine\ORM\Query::HYDRATE_' . strtoupper(str_replace('-', '_', $hydrationModeName)); + + if ( ! defined($hydrationMode)) { + throw new \RuntimeException( + "Hydration mode '$hydrationModeName' does not exist. It should be either: object. array, scalar or single-scalar." + ); + } + + $query = $em->createQuery($dql); + + if (($firstResult = $input->getOption('first-result')) !== null) { + if ( ! is_numeric($firstResult)) { + throw new \LogicException("Option 'first-result' must contains an integer value"); + } + + $query->setFirstResult((int) $firstResult); + } + + if (($maxResult = $input->getOption('max-result')) !== null) { + if ( ! is_numeric($maxResult)) { + throw new \LogicException("Option 'max-result' must contains an integer value"); + } + + $query->setMaxResults((int) $maxResult); + } + + $resultSet = $query->execute(array(), constant($hydrationMode)); + + \Doctrine\Common\Util\Debug::dump($resultSet, $input->getOption('depth')); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php new file mode 100644 index 0000000..cd53948 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php @@ -0,0 +1,64 @@ +. +*/ + +namespace Doctrine\ORM\Tools\Console\Command\SchemaTool; + +use Symfony\Component\Console\Input\InputArgument, + Symfony\Component\Console\Input\InputOption, + Symfony\Component\Console\Input\InputInterface, + Symfony\Component\Console\Output\OutputInterface, + Symfony\Component\Console\Command\Command, + Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper, + Doctrine\ORM\Tools\SchemaTool, + Doctrine\ORM\Mapping\Driver\AbstractFileDriver; + +abstract class AbstractCommand extends Command +{ + /** + * @param InputInterface $input + * @param OutputInterface $output + * @param SchemaTool $schemaTool + * @param array $metadatas + */ + abstract protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas); + + /** + * @see Console\Command\Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $emHelper = $this->getHelper('em'); + + /* @var $em \Doctrine\ORM\EntityManager */ + $em = $emHelper->getEntityManager(); + + $metadatas = $em->getMetadataFactory()->getAllMetadata(); + + if ( ! empty($metadatas)) { + // Create SchemaTool + $tool = new \Doctrine\ORM\Tools\SchemaTool($em); + + $this->executeSchemaCommand($input, $output, $tool, $metadatas); + } else { + $output->write('No Metadata Classes to process.' . PHP_EOL); + } + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php new file mode 100644 index 0000000..d0b8818 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php @@ -0,0 +1,79 @@ +. + */ + +namespace Doctrine\ORM\Tools\Console\Command\SchemaTool; + +use Symfony\Component\Console\Input\InputArgument, + Symfony\Component\Console\Input\InputOption, + Symfony\Component\Console\Input\InputInterface, + Symfony\Component\Console\Output\OutputInterface, + Doctrine\ORM\Tools\SchemaTool; + +/** + * Command to create the database schema for a set of classes based on their mappings. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class CreateCommand extends AbstractCommand +{ + /** + * @see Console\Command\Command + */ + protected function configure() + { + $this + ->setName('orm:schema-tool:create') + ->setDescription( + 'Processes the schema and either create it directly on EntityManager Storage Connection or generate the SQL output.' + ) + ->setDefinition(array( + new InputOption( + 'dump-sql', null, InputOption::VALUE_NONE, + 'Instead of try to apply generated SQLs into EntityManager Storage Connection, output them.' + ) + )) + ->setHelp(<<write('ATTENTION: This operation should not be executed in a production environment.' . PHP_EOL . PHP_EOL); + + if ($input->getOption('dump-sql') === true) { + $sqls = $schemaTool->getCreateSchemaSql($metadatas); + $output->write(implode(';' . PHP_EOL, $sqls) . PHP_EOL); + } else { + $output->write('Creating database schema...' . PHP_EOL); + $schemaTool->createSchema($metadatas); + $output->write('Database schema created successfully!' . PHP_EOL); + } + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php new file mode 100644 index 0000000..57243f2 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php @@ -0,0 +1,111 @@ +. + */ + +namespace Doctrine\ORM\Tools\Console\Command\SchemaTool; + +use Symfony\Component\Console\Input\InputArgument, + Symfony\Component\Console\Input\InputOption, + Symfony\Component\Console\Input\InputInterface, + Symfony\Component\Console\Output\OutputInterface, + Doctrine\ORM\Tools\SchemaTool; + +/** + * Command to drop the database schema for a set of classes based on their mappings. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class DropCommand extends AbstractCommand +{ + /** + * @see Console\Command\Command + */ + protected function configure() + { + $this + ->setName('orm:schema-tool:drop') + ->setDescription( + 'Drop the complete database schema of EntityManager Storage Connection or generate the corresponding SQL output.' + ) + ->setDefinition(array( + new InputOption( + 'dump-sql', null, InputOption::VALUE_NONE, + 'Instead of try to apply generated SQLs into EntityManager Storage Connection, output them.' + ), + new InputOption( + 'force', null, InputOption::VALUE_NONE, + "Don't ask for the deletion of the database, but force the operation to run." + ), + new InputOption( + 'full-database', null, InputOption::VALUE_NONE, + 'Instead of using the Class Metadata to detect the database table schema, drop ALL assets that the database contains.' + ), + )) + ->setHelp(<<getOption('full-database')); + + if ($input->getOption('dump-sql') === true) { + if ($isFullDatabaseDrop) { + $sqls = $schemaTool->getDropDatabaseSQL(); + } else { + $sqls = $schemaTool->getDropSchemaSQL($metadatas); + } + $output->write(implode(';' . PHP_EOL, $sqls) . PHP_EOL); + } else if ($input->getOption('force') === true) { + $output->write('Dropping database schema...' . PHP_EOL); + if ($isFullDatabaseDrop) { + $schemaTool->dropDatabase(); + } else { + $schemaTool->dropSchema($metadatas); + } + $output->write('Database schema dropped successfully!' . PHP_EOL); + } else { + $output->write('ATTENTION: This operation should not be executed in a production environment.' . PHP_EOL . PHP_EOL); + + if ($isFullDatabaseDrop) { + $sqls = $schemaTool->getDropDatabaseSQL(); + } else { + $sqls = $schemaTool->getDropSchemaSQL($metadatas); + } + + if (count($sqls)) { + $output->write('Schema-Tool would execute ' . count($sqls) . ' queries to drop the database.' . PHP_EOL); + $output->write('Please run the operation with --force to execute these queries or use --dump-sql to see them.' . PHP_EOL); + } else { + $output->write('Nothing to drop. The database is empty!' . PHP_EOL); + } + } + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php new file mode 100644 index 0000000..2b0fc0d --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php @@ -0,0 +1,135 @@ +. + */ + +namespace Doctrine\ORM\Tools\Console\Command\SchemaTool; + +use Symfony\Component\Console\Input\InputArgument, + Symfony\Component\Console\Input\InputOption, + Symfony\Component\Console\Input\InputInterface, + Symfony\Component\Console\Output\OutputInterface, + Doctrine\ORM\Tools\SchemaTool; + +/** + * Command to generate the SQL needed to update the database schema to match + * the current mapping information. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Ryan Weaver + */ +class UpdateCommand extends AbstractCommand +{ + protected $name = 'orm:schema-tool:update'; + + /** + * @see Console\Command\Command + */ + protected function configure() + { + $this + ->setName($this->name) + ->setDescription( + 'Executes (or dumps) the SQL needed to update the database schema to match the current mapping metadata.' + ) + ->setDefinition(array( + new InputOption( + 'complete', null, InputOption::VALUE_NONE, + 'If defined, all assets of the database which are not relevant to the current metadata will be dropped.' + ), + + new InputOption( + 'dump-sql', null, InputOption::VALUE_NONE, + 'Dumps the generated SQL statements to the screen (does not execute them).' + ), + new InputOption( + 'force', null, InputOption::VALUE_NONE, + 'Causes the generated SQL statements to be physically executed against your database.' + ), + )); + + $fullName = $this->getName(); + $this->setHelp(<<$fullName command generates the SQL needed to +synchronize the database schema with the current mapping metadata of the +default entity manager. + +For example, if you add metadata for a new column to an entity, this command +would generate and output the SQL needed to add the new column to the database: + +$fullName --dump-sql + +Alternatively, you can execute the generated queries: + +$fullName --force + +Finally, be aware that if the --complete option is passed, this +task will drop all database assets (e.g. tables, etc) that are *not* described +by the current metadata. In other words, without this option, this task leaves +untouched any "extra" tables that exist in the database, but which aren't +described by any metadata. +EOT + ); + } + + protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas) + { + // Defining if update is complete or not (--complete not defined means $saveMode = true) + $saveMode = ($input->getOption('complete') !== true); + + $sqls = $schemaTool->getUpdateSchemaSql($metadatas, $saveMode); + if (0 == count($sqls)) { + $output->writeln('Nothing to update - your database is already in sync with the current entity metadata.'); + + return; + } + + $dumpSql = (true === $input->getOption('dump-sql')); + $force = (true === $input->getOption('force')); + if ($dumpSql && $force) { + throw new \InvalidArgumentException('You can pass either the --dump-sql or the --force option (but not both simultaneously).'); + } + + if ($dumpSql) { + $output->writeln(implode(';' . PHP_EOL, $sqls)); + } else if ($force) { + $output->writeln('Updating database schema...'); + $schemaTool->updateSchema($metadatas, $saveMode); + $output->writeln(sprintf('Database schema updated successfully! "%s" queries were executed', count($sqls))); + } else { + $output->writeln('ATTENTION: This operation should not be executed in a production environment.'); + $output->writeln(' Use the incremental update to detect changes during development and use'); + $output->writeln(' the SQL DDL provided to manually update your database in production.'); + $output->writeln(''); + + $output->writeln(sprintf('The Schema-Tool would execute "%s" queries to update the database.', count($sqls))); + $output->writeln('Please run the operation by passing one of the following options:'); + + $output->writeln(sprintf(' %s --force to execute the command', $this->getName())); + $output->writeln(sprintf(' %s --dump-sql to dump the SQL statements to the screen', $this->getName())); + } + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php new file mode 100644 index 0000000..9381485 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php @@ -0,0 +1,89 @@ +. +*/ + +namespace Doctrine\ORM\Tools\Console\Command; + +use Symfony\Component\Console\Input\InputArgument, + Symfony\Component\Console\Input\InputOption, + Symfony\Component\Console; + +/** + * Validate that the current mapping is valid + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 1.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class ValidateSchemaCommand extends Console\Command\Command +{ + /** + * @see Console\Command\Command + */ + protected function configure() + { + $this + ->setName('orm:validate-schema') + ->setDescription('Validate the mapping files.') + ->setHelp(<<getHelper('em')->getEntityManager(); + + $validator = new \Doctrine\ORM\Tools\SchemaValidator($em); + $errors = $validator->validateMapping(); + + $exit = 0; + if ($errors) { + foreach ($errors AS $className => $errorMessages) { + $output->write("[Mapping] FAIL - The entity-class '" . $className . "' mapping is invalid:\n"); + foreach ($errorMessages AS $errorMessage) { + $output->write('* ' . $errorMessage . "\n"); + } + $output->write("\n"); + } + $exit += 1; + } else { + $output->write('[Mapping] OK - The mapping files are correct.' . "\n"); + } + + if (!$validator->schemaInSyncWithMetadata()) { + $output->write('[Database] FAIL - The database schema is not in sync with the current mapping file.' . "\n"); + $exit += 2; + } else { + $output->write('[Database] OK - The database schema is in sync with the mapping files.' . "\n"); + } + + return $exit; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php new file mode 100644 index 0000000..6907dde --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php @@ -0,0 +1,70 @@ +. + */ + +namespace Doctrine\ORM\Tools\Console; + +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Helper\HelperSet; + +class ConsoleRunner +{ + /** + * Run console with the given helperset. + * + * @param \Symfony\Component\Console\Helper\HelperSet $helperSet + * @return void + */ + static public function run(HelperSet $helperSet) + { + $cli = new Application('Doctrine Command Line Interface', \Doctrine\ORM\Version::VERSION); + $cli->setCatchExceptions(true); + $cli->setHelperSet($helperSet); + self::addCommands($cli); + $cli->run(); + } + + /** + * @param Application $cli + */ + static public function addCommands(Application $cli) + { + $cli->addCommands(array( + // DBAL Commands + new \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand(), + new \Doctrine\DBAL\Tools\Console\Command\ImportCommand(), + + // ORM Commands + new \Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand(), + new \Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand(), + new \Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand(), + new \Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand(), + new \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand(), + new \Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand(), + new \Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand(), + new \Doctrine\ORM\Tools\Console\Command\ConvertDoctrine1SchemaCommand(), + new \Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand(), + new \Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand(), + new \Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand(), + new \Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand(), + new \Doctrine\ORM\Tools\Console\Command\RunDqlCommand(), + new \Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand(), + new \Doctrine\ORM\Tools\Console\Command\InfoCommand() + )); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Helper/EntityManagerHelper.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Helper/EntityManagerHelper.php new file mode 100644 index 0000000..c28622e --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Helper/EntityManagerHelper.php @@ -0,0 +1,74 @@ +. + */ + +namespace Doctrine\ORM\Tools\Console\Helper; + +use Symfony\Component\Console\Helper\Helper, + Doctrine\ORM\EntityManager; + +/** + * Doctrine CLI Connection Helper. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class EntityManagerHelper extends Helper +{ + /** + * Doctrine ORM EntityManager + * @var EntityManager + */ + protected $_em; + + /** + * Constructor + * + * @param Connection $connection Doctrine Database Connection + */ + public function __construct(EntityManager $em) + { + $this->_em = $em; + } + + /** + * Retrieves Doctrine ORM EntityManager + * + * @return EntityManager + */ + public function getEntityManager() + { + return $this->_em; + } + + /** + * @see Helper + */ + public function getName() + { + return 'entityManager'; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/MetadataFilter.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/MetadataFilter.php new file mode 100644 index 0000000..2f69d89 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/MetadataFilter.php @@ -0,0 +1,80 @@ +. +*/ + +namespace Doctrine\ORM\Tools\Console; + +/** + * Used by CLI Tools to restrict entity-based commands to given patterns. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 1.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class MetadataFilter extends \FilterIterator implements \Countable +{ + /** + * Filter Metadatas by one or more filter options. + * + * @param array $metadatas + * @param array|string $filter + * @return array + */ + static public function filter(array $metadatas, $filter) + { + $metadatas = new MetadataFilter(new \ArrayIterator($metadatas), $filter); + return iterator_to_array($metadatas); + } + + private $_filter = array(); + + public function __construct(\ArrayIterator $metadata, $filter) + { + $this->_filter = (array)$filter; + parent::__construct($metadata); + } + + public function accept() + { + if (count($this->_filter) == 0) { + return true; + } + + $it = $this->getInnerIterator(); + $metadata = $it->current(); + + foreach ($this->_filter AS $filter) { + if (strpos($metadata->name, $filter) !== false) { + return true; + } + } + return false; + } + + public function count() + { + return count($this->getInnerIterator()); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ConvertDoctrine1Schema.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ConvertDoctrine1Schema.php new file mode 100644 index 0000000..93edebb --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ConvertDoctrine1Schema.php @@ -0,0 +1,274 @@ +. + */ + +namespace Doctrine\ORM\Tools; + +use Doctrine\ORM\Mapping\ClassMetadataInfo, + Doctrine\ORM\Tools\Export\Driver\AbstractExporter, + Doctrine\Common\Util\Inflector; + +/** + * Class to help with converting Doctrine 1 schema files to Doctrine 2 mapping files + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class ConvertDoctrine1Schema +{ + private $_legacyTypeMap = array( + // TODO: This list may need to be updated + 'clob' => 'text', + 'timestamp' => 'datetime', + 'enum' => 'string' + ); + + /** + * Constructor passes the directory or array of directories + * to convert the Doctrine 1 schema files from + * + * @param array $from + * @author Jonathan Wage + */ + public function __construct($from) + { + $this->_from = (array) $from; + } + + /** + * Get an array of ClassMetadataInfo instances from the passed + * Doctrine 1 schema + * + * @return array $metadatas An array of ClassMetadataInfo instances + */ + public function getMetadata() + { + $schema = array(); + foreach ($this->_from as $path) { + if (is_dir($path)) { + $files = glob($path . '/*.yml'); + foreach ($files as $file) { + $schema = array_merge($schema, (array) \Symfony\Component\Yaml\Yaml::parse($file)); + } + } else { + $schema = array_merge($schema, (array) \Symfony\Component\Yaml\Yaml::parse($path)); + } + } + + $metadatas = array(); + foreach ($schema as $className => $mappingInformation) { + $metadatas[] = $this->_convertToClassMetadataInfo($className, $mappingInformation); + } + + return $metadatas; + } + + private function _convertToClassMetadataInfo($className, $mappingInformation) + { + $metadata = new ClassMetadataInfo($className); + + $this->_convertTableName($className, $mappingInformation, $metadata); + $this->_convertColumns($className, $mappingInformation, $metadata); + $this->_convertIndexes($className, $mappingInformation, $metadata); + $this->_convertRelations($className, $mappingInformation, $metadata); + + return $metadata; + } + + private function _convertTableName($className, array $model, ClassMetadataInfo $metadata) + { + if (isset($model['tableName']) && $model['tableName']) { + $e = explode('.', $model['tableName']); + + if (count($e) > 1) { + $metadata->table['schema'] = $e[0]; + $metadata->table['name'] = $e[1]; + } else { + $metadata->table['name'] = $e[0]; + } + } + } + + private function _convertColumns($className, array $model, ClassMetadataInfo $metadata) + { + $id = false; + + if (isset($model['columns']) && $model['columns']) { + foreach ($model['columns'] as $name => $column) { + $fieldMapping = $this->_convertColumn($className, $name, $column, $metadata); + + if (isset($fieldMapping['id']) && $fieldMapping['id']) { + $id = true; + } + } + } + + if ( ! $id) { + $fieldMapping = array( + 'fieldName' => 'id', + 'columnName' => 'id', + 'type' => 'integer', + 'id' => true + ); + $metadata->mapField($fieldMapping); + $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO); + } + } + + private function _convertColumn($className, $name, $column, ClassMetadataInfo $metadata) + { + if (is_string($column)) { + $string = $column; + $column = array(); + $column['type'] = $string; + } + if ( ! isset($column['name'])) { + $column['name'] = $name; + } + // check if a column alias was used (column_name as field_name) + if (preg_match("/(\w+)\sas\s(\w+)/i", $column['name'], $matches)) { + $name = $matches[1]; + $column['name'] = $name; + $column['alias'] = $matches[2]; + } + if (preg_match("/([a-zA-Z]+)\(([0-9]+)\)/", $column['type'], $matches)) { + $column['type'] = $matches[1]; + $column['length'] = $matches[2]; + } + $column['type'] = strtolower($column['type']); + // check if legacy column type (1.x) needs to be mapped to a 2.0 one + if (isset($this->_legacyTypeMap[$column['type']])) { + $column['type'] = $this->_legacyTypeMap[$column['type']]; + } + if ( ! \Doctrine\DBAL\Types\Type::hasType($column['type'])) { + throw ToolsException::couldNotMapDoctrine1Type($column['type']); + } + + $fieldMapping = array(); + if (isset($column['primary'])) { + $fieldMapping['id'] = true; + } + $fieldMapping['fieldName'] = isset($column['alias']) ? $column['alias'] : $name; + $fieldMapping['columnName'] = $column['name']; + $fieldMapping['type'] = $column['type']; + if (isset($column['length'])) { + $fieldMapping['length'] = $column['length']; + } + $allowed = array('precision', 'scale', 'unique', 'options', 'notnull', 'version'); + foreach ($column as $key => $value) { + if (in_array($key, $allowed)) { + $fieldMapping[$key] = $value; + } + } + + $metadata->mapField($fieldMapping); + + if (isset($column['autoincrement'])) { + $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO); + } else if (isset($column['sequence'])) { + $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE); + $definition = array( + 'sequenceName' => is_array($column['sequence']) ? $column['sequence']['name']:$column['sequence'] + ); + if (isset($column['sequence']['size'])) { + $definition['allocationSize'] = $column['sequence']['size']; + } + if (isset($column['sequence']['value'])) { + $definition['initialValue'] = $column['sequence']['value']; + } + $metadata->setSequenceGeneratorDefinition($definition); + } + return $fieldMapping; + } + + private function _convertIndexes($className, array $model, ClassMetadataInfo $metadata) + { + if (isset($model['indexes']) && $model['indexes']) { + foreach ($model['indexes'] as $name => $index) { + $type = (isset($index['type']) && $index['type'] == 'unique') + ? 'uniqueConstraints' : 'indexes'; + + $metadata->table[$type][$name] = array( + 'columns' => $index['fields'] + ); + } + } + } + + private function _convertRelations($className, array $model, ClassMetadataInfo $metadata) + { + if (isset($model['relations']) && $model['relations']) { + foreach ($model['relations'] as $name => $relation) { + if ( ! isset($relation['alias'])) { + $relation['alias'] = $name; + } + if ( ! isset($relation['class'])) { + $relation['class'] = $name; + } + if ( ! isset($relation['local'])) { + $relation['local'] = Inflector::tableize($relation['class']); + } + if ( ! isset($relation['foreign'])) { + $relation['foreign'] = 'id'; + } + if ( ! isset($relation['foreignAlias'])) { + $relation['foreignAlias'] = $className; + } + + if (isset($relation['refClass'])) { + $type = 'many'; + $foreignType = 'many'; + $joinColumns = array(); + } else { + $type = isset($relation['type']) ? $relation['type'] : 'one'; + $foreignType = isset($relation['foreignType']) ? $relation['foreignType'] : 'many'; + $joinColumns = array( + array( + 'name' => $relation['local'], + 'referencedColumnName' => $relation['foreign'], + 'onDelete' => isset($relation['onDelete']) ? $relation['onDelete'] : null, + ) + ); + } + + if ($type == 'one' && $foreignType == 'one') { + $method = 'mapOneToOne'; + } else if ($type == 'many' && $foreignType == 'many') { + $method = 'mapManyToMany'; + } else { + $method = 'mapOneToMany'; + } + + $associationMapping = array(); + $associationMapping['fieldName'] = $relation['alias']; + $associationMapping['targetEntity'] = $relation['class']; + $associationMapping['mappedBy'] = $relation['foreignAlias']; + $associationMapping['joinColumns'] = $joinColumns; + + $metadata->$method($associationMapping); + } + } + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/DebugUnitOfWorkListener.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/DebugUnitOfWorkListener.php new file mode 100644 index 0000000..0548b96 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/DebugUnitOfWorkListener.php @@ -0,0 +1,151 @@ +. + */ + +namespace Doctrine\ORM\Tools; + +use Doctrine\ORM\Event\OnFlushEventArgs; +use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\ORM\PersistentCollection; +use Doctrine\ORM\UnitOfWork; + +/** + * Use this logger to dump the identity map during the onFlush event. This is useful for debugging + * weird UnitOfWork behavior with complex operations. + */ +class DebugUnitOfWorkListener +{ + private $file; + private $context; + + /** + * Pass a stream and contet information for the debugging session. + * + * The stream can be php://output to print to the screen. + * + * @param string $file + * @param string $context + */ + public function __construct($file = 'php://output', $context = '') + { + $this->file = $file; + $this->context = $context; + } + + public function onFlush(OnFlushEventArgs $args) + { + $this->dumpIdentityMap($args->getEntityManager()); + } + + /** + * Dump the contents of the identity map into a stream. + * + * @param EntityManager $em + * @return void + */ + public function dumpIdentityMap(EntityManager $em) + { + $uow = $em->getUnitOfWork(); + $identityMap = $uow->getIdentityMap(); + + $fh = fopen($this->file, "x+"); + if (count($identityMap) == 0) { + fwrite($fh, "Flush Operation [".$this->context."] - Empty identity map.\n"); + return; + } + + fwrite($fh, "Flush Operation [".$this->context."] - Dumping identity map:\n"); + foreach ($identityMap AS $className => $map) { + fwrite($fh, "Class: ". $className . "\n"); + foreach ($map AS $idHash => $entity) { + fwrite($fh, " Entity: " . $this->getIdString($entity, $uow) . " " . spl_object_hash($entity)."\n"); + fwrite($fh, " Associations:\n"); + + $cm = $em->getClassMetadata($className); + foreach ($cm->associationMappings AS $field => $assoc) { + fwrite($fh, " " . $field . " "); + $value = $cm->reflFields[$field]->getValue($entity); + + if ($assoc['type'] & ClassMetadata::TO_ONE) { + if ($value === null) { + fwrite($fh, " NULL\n"); + } else { + if ($value instanceof Proxy && !$value->__isInitialized__) { + fwrite($fh, "[PROXY] "); + } + + fwrite($fh, $this->getIdString($value, $uow) . " " . spl_object_hash($value) . "\n"); + } + } else { + $initialized = !($value instanceof PersistentCollection) || $value->isInitialized(); + if ($value === null) { + fwrite($fh, " NULL\n"); + } else if ($initialized) { + fwrite($fh, "[INITIALIZED] " . $this->getType($value). " " . count($value) . " elements\n"); + foreach ($value AS $obj) { + fwrite($fh, " " . $this->getIdString($obj, $uow) . " " . spl_object_hash($obj)."\n"); + } + } else { + fwrite($fh, "[PROXY] " . $this->getType($value) . " unknown element size\n"); + foreach ($value->unwrap() AS $obj) { + fwrite($fh, " " . $this->getIdString($obj, $uow) . " " . spl_object_hash($obj)."\n"); + } + } + } + } + } + } + fclose($fh); + } + + private function getType($var) + { + if (is_object($var)) { + $refl = new \ReflectionObject($var); + return $refl->getShortname(); + } else { + return gettype($var); + } + } + + private function getIdString($entity, $uow) + { + if ($uow->isInIdentityMap($entity)) { + $ids = $uow->getEntityIdentifier($entity); + $idstring = ""; + foreach ($ids AS $k => $v) { + $idstring .= $k."=".$v; + } + } else { + $idstring = "NEWOBJECT "; + } + + $state = $uow->getEntityState($entity); + if ($state == UnitOfWork::STATE_NEW) { + $idstring .= " [NEW]"; + } else if ($state == UnitOfWork::STATE_REMOVED) { + $idstring .= " [REMOVED]"; + } else if ($state == UnitOfWork::STATE_MANAGED) { + $idstring .= " [MANAGED]"; + } else if ($state == UnitOfwork::STATE_DETACHED) { + $idstring .= " [DETACHED]"; + } + + return $idstring; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/DisconnectedClassMetadataFactory.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/DisconnectedClassMetadataFactory.php new file mode 100644 index 0000000..2603c22 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/DisconnectedClassMetadataFactory.php @@ -0,0 +1,45 @@ +. + */ + +namespace Doctrine\ORM\Tools; + +use Doctrine\ORM\Mapping\ClassMetadataFactory; +use Doctrine\ORM\Mapping\ClassMetadataInfo; + +/** + * The DisconnectedClassMetadataFactory is used to create ClassMetadataInfo objects + * that do not require the entity class actually exist. This allows us to + * load some mapping information and use it to do things like generate code + * from the mapping information. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class DisconnectedClassMetadataFactory extends ClassMetadataFactory +{ + public function getReflectionService() + { + return new \Doctrine\Common\Persistence\Mapping\StaticReflectionService; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/EntityGenerator.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/EntityGenerator.php new file mode 100644 index 0000000..bbfcc13 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/EntityGenerator.php @@ -0,0 +1,1129 @@ +. + */ + +namespace Doctrine\ORM\Tools; + +use Doctrine\ORM\Mapping\ClassMetadataInfo, + Doctrine\ORM\Mapping\AssociationMapping, + Doctrine\Common\Util\Inflector; + +/** + * Generic class used to generate PHP5 entity classes from ClassMetadataInfo instances + * + * [php] + * $classes = $em->getClassMetadataFactory()->getAllMetadata(); + * + * $generator = new \Doctrine\ORM\Tools\EntityGenerator(); + * $generator->setGenerateAnnotations(true); + * $generator->setGenerateStubMethods(true); + * $generator->setRegenerateEntityIfExists(false); + * $generator->setUpdateEntityIfExists(true); + * $generator->generate($classes, '/path/to/generate/entities'); + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class EntityGenerator +{ + /** + * @var bool + */ + private $_backupExisting = true; + + /** The extension to use for written php files */ + private $_extension = '.php'; + + /** Whether or not the current ClassMetadataInfo instance is new or old */ + private $_isNew = true; + + private $_staticReflection = array(); + + /** Number of spaces to use for indention in generated code */ + private $_numSpaces = 4; + + /** The actual spaces to use for indention */ + private $_spaces = ' '; + + /** The class all generated entities should extend */ + private $_classToExtend; + + /** Whether or not to generation annotations */ + private $_generateAnnotations = false; + + /** + * @var string + */ + private $_annotationsPrefix = ''; + + /** Whether or not to generated sub methods */ + private $_generateEntityStubMethods = false; + + /** Whether or not to update the entity class if it exists already */ + private $_updateEntityIfExists = false; + + /** Whether or not to re-generate entity class if it exists already */ + private $_regenerateEntityIfExists = false; + + private static $_classTemplate = +' + +use Doctrine\ORM\Mapping as ORM; + + + +{ + +}'; + + private static $_getMethodTemplate = +'/** + * + * + * @return + */ +public function () +{ +return $this->; +}'; + + private static $_setMethodTemplate = +'/** + * + * + * @param $ + * @return + */ +public function ($) +{ +$this-> = $; +return $this; +}'; + + private static $_addMethodTemplate = +'/** + * + * + * @param $ + * @return + */ +public function ($) +{ +$this->[] = $; +return $this; +}'; + + private static $_lifecycleCallbackMethodTemplate = +'/** + * @ + */ +public function () +{ +// Add your code here +}'; + + private static $_constructorMethodTemplate = +'public function __construct() +{ + +} +'; + + public function __construct() + { + if (version_compare(\Doctrine\Common\Version::VERSION, '2.2.0-DEV', '>=')) { + $this->_annotationsPrefix = 'ORM\\'; + } + } + + /** + * Generate and write entity classes for the given array of ClassMetadataInfo instances + * + * @param array $metadatas + * @param string $outputDirectory + * @return void + */ + public function generate(array $metadatas, $outputDirectory) + { + foreach ($metadatas as $metadata) { + $this->writeEntityClass($metadata, $outputDirectory); + } + } + + /** + * Generated and write entity class to disk for the given ClassMetadataInfo instance + * + * @param ClassMetadataInfo $metadata + * @param string $outputDirectory + * @return void + */ + public function writeEntityClass(ClassMetadataInfo $metadata, $outputDirectory) + { + $path = $outputDirectory . '/' . str_replace('\\', DIRECTORY_SEPARATOR, $metadata->name) . $this->_extension; + $dir = dirname($path); + + if ( ! is_dir($dir)) { + mkdir($dir, 0777, true); + } + + $this->_isNew = !file_exists($path) || (file_exists($path) && $this->_regenerateEntityIfExists); + + if ( ! $this->_isNew) { + $this->_parseTokensInEntityFile(file_get_contents($path)); + } else { + $this->_staticReflection[$metadata->name] = array('properties' => array(), 'methods' => array()); + } + + if ($this->_backupExisting && file_exists($path)) { + $backupPath = dirname($path) . DIRECTORY_SEPARATOR . basename($path) . "~"; + if (!copy($path, $backupPath)) { + throw new \RuntimeException("Attempt to backup overwritten entity file but copy operation failed."); + } + } + + // If entity doesn't exist or we're re-generating the entities entirely + if ($this->_isNew) { + file_put_contents($path, $this->generateEntityClass($metadata)); + // If entity exists and we're allowed to update the entity class + } else if ( ! $this->_isNew && $this->_updateEntityIfExists) { + file_put_contents($path, $this->generateUpdatedEntityClass($metadata, $path)); + } + } + + /** + * Generate a PHP5 Doctrine 2 entity class from the given ClassMetadataInfo instance + * + * @param ClassMetadataInfo $metadata + * @return string $code + */ + public function generateEntityClass(ClassMetadataInfo $metadata) + { + $placeHolders = array( + '', + '', + '', + '' + ); + + $replacements = array( + $this->_generateEntityNamespace($metadata), + $this->_generateEntityDocBlock($metadata), + $this->_generateEntityClassName($metadata), + $this->_generateEntityBody($metadata) + ); + + $code = str_replace($placeHolders, $replacements, self::$_classTemplate); + return str_replace('', $this->_spaces, $code); + } + + /** + * Generate the updated code for the given ClassMetadataInfo and entity at path + * + * @param ClassMetadataInfo $metadata + * @param string $path + * @return string $code; + */ + public function generateUpdatedEntityClass(ClassMetadataInfo $metadata, $path) + { + $currentCode = file_get_contents($path); + + $body = $this->_generateEntityBody($metadata); + $body = str_replace('', $this->_spaces, $body); + $last = strrpos($currentCode, '}'); + + return substr($currentCode, 0, $last) . $body . (strlen($body) > 0 ? "\n" : ''). "}"; + } + + /** + * Set the number of spaces the exported class should have + * + * @param integer $numSpaces + * @return void + */ + public function setNumSpaces($numSpaces) + { + $this->_spaces = str_repeat(' ', $numSpaces); + $this->_numSpaces = $numSpaces; + } + + /** + * Set the extension to use when writing php files to disk + * + * @param string $extension + * @return void + */ + public function setExtension($extension) + { + $this->_extension = $extension; + } + + /** + * Set the name of the class the generated classes should extend from + * + * @return void + */ + public function setClassToExtend($classToExtend) + { + $this->_classToExtend = $classToExtend; + } + + /** + * Set whether or not to generate annotations for the entity + * + * @param bool $bool + * @return void + */ + public function setGenerateAnnotations($bool) + { + $this->_generateAnnotations = $bool; + } + + /** + * Set an annotation prefix. + * + * @param string $prefix + */ + public function setAnnotationPrefix($prefix) + { + $this->_annotationsPrefix = $prefix; + } + + /** + * Set whether or not to try and update the entity if it already exists + * + * @param bool $bool + * @return void + */ + public function setUpdateEntityIfExists($bool) + { + $this->_updateEntityIfExists = $bool; + } + + /** + * Set whether or not to regenerate the entity if it exists + * + * @param bool $bool + * @return void + */ + public function setRegenerateEntityIfExists($bool) + { + $this->_regenerateEntityIfExists = $bool; + } + + /** + * Set whether or not to generate stub methods for the entity + * + * @param bool $bool + * @return void + */ + public function setGenerateStubMethods($bool) + { + $this->_generateEntityStubMethods = $bool; + } + + /** + * Should an existing entity be backed up if it already exists? + */ + public function setBackupExisting($bool) + { + $this->_backupExisting = $bool; + } + + private function _generateEntityNamespace(ClassMetadataInfo $metadata) + { + if ($this->_hasNamespace($metadata)) { + return 'namespace ' . $this->_getNamespace($metadata) .';'; + } + } + + private function _generateEntityClassName(ClassMetadataInfo $metadata) + { + return 'class ' . $this->_getClassName($metadata) . + ($this->_extendsClass() ? ' extends ' . $this->_getClassToExtendName() : null); + } + + private function _generateEntityBody(ClassMetadataInfo $metadata) + { + $fieldMappingProperties = $this->_generateEntityFieldMappingProperties($metadata); + $associationMappingProperties = $this->_generateEntityAssociationMappingProperties($metadata); + $stubMethods = $this->_generateEntityStubMethods ? $this->_generateEntityStubMethods($metadata) : null; + $lifecycleCallbackMethods = $this->_generateEntityLifecycleCallbackMethods($metadata); + + $code = array(); + + if ($fieldMappingProperties) { + $code[] = $fieldMappingProperties; + } + + if ($associationMappingProperties) { + $code[] = $associationMappingProperties; + } + + $code[] = $this->_generateEntityConstructor($metadata); + + if ($stubMethods) { + $code[] = $stubMethods; + } + + if ($lifecycleCallbackMethods) { + $code[] = $lifecycleCallbackMethods; + } + + return implode("\n", $code); + } + + private function _generateEntityConstructor(ClassMetadataInfo $metadata) + { + if ($this->_hasMethod('__construct', $metadata)) { + return ''; + } + + $collections = array(); + + foreach ($metadata->associationMappings AS $mapping) { + if ($mapping['type'] & ClassMetadataInfo::TO_MANY) { + $collections[] = '$this->'.$mapping['fieldName'].' = new \Doctrine\Common\Collections\ArrayCollection();'; + } + } + + if ($collections) { + return $this->_prefixCodeWithSpaces(str_replace("", implode("\n".$this->_spaces, $collections), self::$_constructorMethodTemplate)); + } + + return ''; + } + + /** + * @todo this won't work if there is a namespace in brackets and a class outside of it. + * @param string $src + */ + private function _parseTokensInEntityFile($src) + { + $tokens = token_get_all($src); + $lastSeenNamespace = ""; + $lastSeenClass = false; + + $inNamespace = false; + $inClass = false; + for ($i = 0; $i < count($tokens); $i++) { + $token = $tokens[$i]; + if (in_array($token[0], array(T_WHITESPACE, T_COMMENT, T_DOC_COMMENT))) { + continue; + } + + if ($inNamespace) { + if ($token[0] == T_NS_SEPARATOR || $token[0] == T_STRING) { + $lastSeenNamespace .= $token[1]; + } else if (is_string($token) && in_array($token, array(';', '{'))) { + $inNamespace = false; + } + } + + if ($inClass) { + $inClass = false; + $lastSeenClass = $lastSeenNamespace . ($lastSeenNamespace ? '\\' : '') . $token[1]; + $this->_staticReflection[$lastSeenClass]['properties'] = array(); + $this->_staticReflection[$lastSeenClass]['methods'] = array(); + } + + if ($token[0] == T_NAMESPACE) { + $lastSeenNamespace = ""; + $inNamespace = true; + } else if ($token[0] == T_CLASS) { + $inClass = true; + } else if ($token[0] == T_FUNCTION) { + if ($tokens[$i+2][0] == T_STRING) { + $this->_staticReflection[$lastSeenClass]['methods'][] = $tokens[$i+2][1]; + } else if ($tokens[$i+2] == "&" && $tokens[$i+3][0] == T_STRING) { + $this->_staticReflection[$lastSeenClass]['methods'][] = $tokens[$i+3][1]; + } + } else if (in_array($token[0], array(T_VAR, T_PUBLIC, T_PRIVATE, T_PROTECTED)) && $tokens[$i+2][0] != T_FUNCTION) { + $this->_staticReflection[$lastSeenClass]['properties'][] = substr($tokens[$i+2][1], 1); + } + } + } + + private function _hasProperty($property, ClassMetadataInfo $metadata) + { + if ($this->_extendsClass()) { + // don't generate property if its already on the base class. + $reflClass = new \ReflectionClass($this->_getClassToExtend()); + if ($reflClass->hasProperty($property)) { + return true; + } + } + + return ( + isset($this->_staticReflection[$metadata->name]) && + in_array($property, $this->_staticReflection[$metadata->name]['properties']) + ); + } + + private function _hasMethod($method, ClassMetadataInfo $metadata) + { + if ($this->_extendsClass()) { + // don't generate method if its already on the base class. + $reflClass = new \ReflectionClass($this->_getClassToExtend()); + if ($reflClass->hasMethod($method)) { + return true; + } + } + + return ( + isset($this->_staticReflection[$metadata->name]) && + in_array($method, $this->_staticReflection[$metadata->name]['methods']) + ); + } + + private function _hasNamespace(ClassMetadataInfo $metadata) + { + return strpos($metadata->name, '\\') ? true : false; + } + + private function _extendsClass() + { + return $this->_classToExtend ? true : false; + } + + private function _getClassToExtend() + { + return $this->_classToExtend; + } + + private function _getClassToExtendName() + { + $refl = new \ReflectionClass($this->_getClassToExtend()); + + return '\\' . $refl->getName(); + } + + private function _getClassName(ClassMetadataInfo $metadata) + { + return ($pos = strrpos($metadata->name, '\\')) + ? substr($metadata->name, $pos + 1, strlen($metadata->name)) : $metadata->name; + } + + private function _getNamespace(ClassMetadataInfo $metadata) + { + return substr($metadata->name, 0, strrpos($metadata->name, '\\')); + } + + private function _generateEntityDocBlock(ClassMetadataInfo $metadata) + { + $lines = array(); + $lines[] = '/**'; + $lines[] = ' * '.$metadata->name; + + if ($this->_generateAnnotations) { + $lines[] = ' *'; + + $methods = array( + '_generateTableAnnotation', + '_generateInheritanceAnnotation', + '_generateDiscriminatorColumnAnnotation', + '_generateDiscriminatorMapAnnotation' + ); + + foreach ($methods as $method) { + if ($code = $this->$method($metadata)) { + $lines[] = ' * ' . $code; + } + } + + if ($metadata->isMappedSuperclass) { + $lines[] = ' * @' . $this->_annotationsPrefix . 'MappedSuperClass'; + } else { + $lines[] = ' * @' . $this->_annotationsPrefix . 'Entity'; + } + + if ($metadata->customRepositoryClassName) { + $lines[count($lines) - 1] .= '(repositoryClass="' . $metadata->customRepositoryClassName . '")'; + } + + if (isset($metadata->lifecycleCallbacks) && $metadata->lifecycleCallbacks) { + $lines[] = ' * @' . $this->_annotationsPrefix . 'HasLifecycleCallbacks'; + } + } + + $lines[] = ' */'; + + return implode("\n", $lines); + } + + private function _generateTableAnnotation($metadata) + { + $table = array(); + + if (isset($metadata->table['schema'])) { + $table[] = 'schema="' . $metadata->table['schema'] . '"'; + } + + if (isset($metadata->table['name'])) { + $table[] = 'name="' . $metadata->table['name'] . '"'; + } + + if (isset($metadata->table['uniqueConstraints']) && $metadata->table['uniqueConstraints']) { + $constraints = $this->_generateTableConstraints('UniqueConstraint', $metadata->table['uniqueConstraints']); + $table[] = 'uniqueConstraints={' . $constraints . '}'; + } + + if (isset($metadata->table['indexes']) && $metadata->table['indexes']) { + $constraints = $this->_generateTableConstraints('Index', $metadata->table['indexes']); + $table[] = 'indexes={' . $constraints . '}'; + } + + return '@' . $this->_annotationsPrefix . 'Table(' . implode(', ', $table) . ')'; + } + + private function _generateTableConstraints($constraintName, $constraints) + { + $annotations = array(); + foreach ($constraints as $name => $constraint) { + $columns = array(); + foreach ($constraint['columns'] as $column) { + $columns[] = '"' . $column . '"'; + } + $annotations[] = '@' . $this->_annotationsPrefix . $constraintName . '(name="' . $name . '", columns={' . implode(', ', $columns) . '})'; + } + return implode(', ', $annotations); + } + + private function _generateInheritanceAnnotation($metadata) + { + if ($metadata->inheritanceType != ClassMetadataInfo::INHERITANCE_TYPE_NONE) { + return '@' . $this->_annotationsPrefix . 'InheritanceType("'.$this->_getInheritanceTypeString($metadata->inheritanceType).'")'; + } + } + + private function _generateDiscriminatorColumnAnnotation($metadata) + { + if ($metadata->inheritanceType != ClassMetadataInfo::INHERITANCE_TYPE_NONE) { + $discrColumn = $metadata->discriminatorValue; + $columnDefinition = 'name="' . $discrColumn['name'] + . '", type="' . $discrColumn['type'] + . '", length=' . $discrColumn['length']; + + return '@' . $this->_annotationsPrefix . 'DiscriminatorColumn(' . $columnDefinition . ')'; + } + } + + private function _generateDiscriminatorMapAnnotation($metadata) + { + if ($metadata->inheritanceType != ClassMetadataInfo::INHERITANCE_TYPE_NONE) { + $inheritanceClassMap = array(); + + foreach ($metadata->discriminatorMap as $type => $class) { + $inheritanceClassMap[] .= '"' . $type . '" = "' . $class . '"'; + } + + return '@' . $this->_annotationsPrefix . 'DiscriminatorMap({' . implode(', ', $inheritanceClassMap) . '})'; + } + } + + private function _generateEntityStubMethods(ClassMetadataInfo $metadata) + { + $methods = array(); + + foreach ($metadata->fieldMappings as $fieldMapping) { + if ( ! isset($fieldMapping['id']) || ! $fieldMapping['id'] || $metadata->generatorType == ClassMetadataInfo::GENERATOR_TYPE_NONE) { + if ($code = $this->_generateEntityStubMethod($metadata, 'set', $fieldMapping['fieldName'], $fieldMapping['type'])) { + $methods[] = $code; + } + } + + if ($code = $this->_generateEntityStubMethod($metadata, 'get', $fieldMapping['fieldName'], $fieldMapping['type'])) { + $methods[] = $code; + } + } + + foreach ($metadata->associationMappings as $associationMapping) { + if ($associationMapping['type'] & ClassMetadataInfo::TO_ONE) { + $nullable = $this->_isAssociationIsNullable($associationMapping) ? 'null' : null; + if ($code = $this->_generateEntityStubMethod($metadata, 'set', $associationMapping['fieldName'], $associationMapping['targetEntity'], $nullable)) { + $methods[] = $code; + } + if ($code = $this->_generateEntityStubMethod($metadata, 'get', $associationMapping['fieldName'], $associationMapping['targetEntity'])) { + $methods[] = $code; + } + } else if ($associationMapping['type'] & ClassMetadataInfo::TO_MANY) { + if ($code = $this->_generateEntityStubMethod($metadata, 'add', $associationMapping['fieldName'], $associationMapping['targetEntity'])) { + $methods[] = $code; + } + if ($code = $this->_generateEntityStubMethod($metadata, 'get', $associationMapping['fieldName'], 'Doctrine\Common\Collections\Collection')) { + $methods[] = $code; + } + } + } + + return implode("\n\n", $methods); + } + + private function _isAssociationIsNullable($associationMapping) + { + if (isset($associationMapping['id']) && $associationMapping['id']) { + return false; + } + if (isset($associationMapping['joinColumns'])) { + $joinColumns = $associationMapping['joinColumns']; + } else { + //@todo thereis no way to retreive targetEntity metadata + $joinColumns = array(); + } + foreach ($joinColumns as $joinColumn) { + if(isset($joinColumn['nullable']) && !$joinColumn['nullable']) { + return false; + } + } + return true; + } + + private function _generateEntityLifecycleCallbackMethods(ClassMetadataInfo $metadata) + { + if (isset($metadata->lifecycleCallbacks) && $metadata->lifecycleCallbacks) { + $methods = array(); + + foreach ($metadata->lifecycleCallbacks as $name => $callbacks) { + foreach ($callbacks as $callback) { + if ($code = $this->_generateLifecycleCallbackMethod($name, $callback, $metadata)) { + $methods[] = $code; + } + } + } + + return implode("\n\n", $methods); + } + + return ""; + } + + private function _generateEntityAssociationMappingProperties(ClassMetadataInfo $metadata) + { + $lines = array(); + + foreach ($metadata->associationMappings as $associationMapping) { + if ($this->_hasProperty($associationMapping['fieldName'], $metadata)) { + continue; + } + + $lines[] = $this->_generateAssociationMappingPropertyDocBlock($associationMapping, $metadata); + $lines[] = $this->_spaces . 'private $' . $associationMapping['fieldName'] + . ($associationMapping['type'] == 'manyToMany' ? ' = array()' : null) . ";\n"; + } + + return implode("\n", $lines); + } + + private function _generateEntityFieldMappingProperties(ClassMetadataInfo $metadata) + { + $lines = array(); + + foreach ($metadata->fieldMappings as $fieldMapping) { + if ($this->_hasProperty($fieldMapping['fieldName'], $metadata) || + $metadata->isInheritedField($fieldMapping['fieldName'])) { + continue; + } + + $lines[] = $this->_generateFieldMappingPropertyDocBlock($fieldMapping, $metadata); + $lines[] = $this->_spaces . 'private $' . $fieldMapping['fieldName'] + . (isset($fieldMapping['default']) ? ' = ' . var_export($fieldMapping['default'], true) : null) . ";\n"; + } + + return implode("\n", $lines); + } + + private function _generateEntityStubMethod(ClassMetadataInfo $metadata, $type, $fieldName, $typeHint = null, $defaultValue = null) + { + if ($type == "add") { + $addMethod = explode("\\", $typeHint); + $addMethod = end($addMethod); + $methodName = $type . $addMethod; + } else { + $methodName = $type . Inflector::classify($fieldName); + } + + if ($this->_hasMethod($methodName, $metadata)) { + return; + } + $this->_staticReflection[$metadata->name]['methods'][] = $methodName; + + $var = sprintf('_%sMethodTemplate', $type); + $template = self::$$var; + + $variableType = $typeHint ? $typeHint . ' ' : null; + + $types = \Doctrine\DBAL\Types\Type::getTypesMap(); + $methodTypeHint = $typeHint && ! isset($types[$typeHint]) ? '\\' . $typeHint . ' ' : null; + + $replacements = array( + '' => ucfirst($type) . ' ' . $fieldName, + '' => $methodTypeHint, + '' => $variableType, + '' => Inflector::camelize($fieldName), + '' => $methodName, + '' => $fieldName, + '' => ($defaultValue !== null ) ? (' = '.$defaultValue) : '', + '' => $this->_getClassName($metadata) + ); + + $method = str_replace( + array_keys($replacements), + array_values($replacements), + $template + ); + + return $this->_prefixCodeWithSpaces($method); + } + + private function _generateLifecycleCallbackMethod($name, $methodName, $metadata) + { + if ($this->_hasMethod($methodName, $metadata)) { + return; + } + $this->_staticReflection[$metadata->name]['methods'][] = $methodName; + + $replacements = array( + '' => $this->_annotationsPrefix . ucfirst($name), + '' => $methodName, + ); + + $method = str_replace( + array_keys($replacements), + array_values($replacements), + self::$_lifecycleCallbackMethodTemplate + ); + + return $this->_prefixCodeWithSpaces($method); + } + + private function _generateJoinColumnAnnotation(array $joinColumn) + { + $joinColumnAnnot = array(); + + if (isset($joinColumn['name'])) { + $joinColumnAnnot[] = 'name="' . $joinColumn['name'] . '"'; + } + + if (isset($joinColumn['referencedColumnName'])) { + $joinColumnAnnot[] = 'referencedColumnName="' . $joinColumn['referencedColumnName'] . '"'; + } + + if (isset($joinColumn['unique']) && $joinColumn['unique']) { + $joinColumnAnnot[] = 'unique=' . ($joinColumn['unique'] ? 'true' : 'false'); + } + + if (isset($joinColumn['nullable'])) { + $joinColumnAnnot[] = 'nullable=' . ($joinColumn['nullable'] ? 'true' : 'false'); + } + + if (isset($joinColumn['onDelete'])) { + $joinColumnAnnot[] = 'onDelete="' . ($joinColumn['onDelete'] . '"'); + } + + if (isset($joinColumn['columnDefinition'])) { + $joinColumnAnnot[] = 'columnDefinition="' . $joinColumn['columnDefinition'] . '"'; + } + + return '@' . $this->_annotationsPrefix . 'JoinColumn(' . implode(', ', $joinColumnAnnot) . ')'; + } + + private function _generateAssociationMappingPropertyDocBlock(array $associationMapping, ClassMetadataInfo $metadata) + { + $lines = array(); + $lines[] = $this->_spaces . '/**'; + + if ($associationMapping['type'] & ClassMetadataInfo::TO_MANY) { + $lines[] = $this->_spaces . ' * @var \Doctrine\Common\Collections\ArrayCollection'; + } else { + $lines[] = $this->_spaces . ' * @var ' . $associationMapping['targetEntity']; + } + + if ($this->_generateAnnotations) { + $lines[] = $this->_spaces . ' *'; + + if (isset($associationMapping['id']) && $associationMapping['id']) { + $lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . 'Id'; + + if ($generatorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) { + $lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . 'GeneratedValue(strategy="' . $generatorType . '")'; + } + } + + $type = null; + switch ($associationMapping['type']) { + case ClassMetadataInfo::ONE_TO_ONE: + $type = 'OneToOne'; + break; + case ClassMetadataInfo::MANY_TO_ONE: + $type = 'ManyToOne'; + break; + case ClassMetadataInfo::ONE_TO_MANY: + $type = 'OneToMany'; + break; + case ClassMetadataInfo::MANY_TO_MANY: + $type = 'ManyToMany'; + break; + } + $typeOptions = array(); + + if (isset($associationMapping['targetEntity'])) { + $typeOptions[] = 'targetEntity="' . $associationMapping['targetEntity'] . '"'; + } + + if (isset($associationMapping['inversedBy'])) { + $typeOptions[] = 'inversedBy="' . $associationMapping['inversedBy'] . '"'; + } + + if (isset($associationMapping['mappedBy'])) { + $typeOptions[] = 'mappedBy="' . $associationMapping['mappedBy'] . '"'; + } + + if ($associationMapping['cascade']) { + $cascades = array(); + + if ($associationMapping['isCascadePersist']) $cascades[] = '"persist"'; + if ($associationMapping['isCascadeRemove']) $cascades[] = '"remove"'; + if ($associationMapping['isCascadeDetach']) $cascades[] = '"detach"'; + if ($associationMapping['isCascadeMerge']) $cascades[] = '"merge"'; + if ($associationMapping['isCascadeRefresh']) $cascades[] = '"refresh"'; + + $typeOptions[] = 'cascade={' . implode(',', $cascades) . '}'; + } + + if (isset($associationMapping['orphanRemoval']) && $associationMapping['orphanRemoval']) { + $typeOptions[] = 'orphanRemoval=' . ($associationMapping['orphanRemoval'] ? 'true' : 'false'); + } + + $lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . '' . $type . '(' . implode(', ', $typeOptions) . ')'; + + if (isset($associationMapping['joinColumns']) && $associationMapping['joinColumns']) { + $lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . 'JoinColumns({'; + + $joinColumnsLines = array(); + + foreach ($associationMapping['joinColumns'] as $joinColumn) { + if ($joinColumnAnnot = $this->_generateJoinColumnAnnotation($joinColumn)) { + $joinColumnsLines[] = $this->_spaces . ' * ' . $joinColumnAnnot; + } + } + + $lines[] = implode(",\n", $joinColumnsLines); + $lines[] = $this->_spaces . ' * })'; + } + + if (isset($associationMapping['joinTable']) && $associationMapping['joinTable']) { + $joinTable = array(); + $joinTable[] = 'name="' . $associationMapping['joinTable']['name'] . '"'; + + if (isset($associationMapping['joinTable']['schema'])) { + $joinTable[] = 'schema="' . $associationMapping['joinTable']['schema'] . '"'; + } + + $lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . 'JoinTable(' . implode(', ', $joinTable) . ','; + $lines[] = $this->_spaces . ' * joinColumns={'; + + foreach ($associationMapping['joinTable']['joinColumns'] as $joinColumn) { + $lines[] = $this->_spaces . ' * ' . $this->_generateJoinColumnAnnotation($joinColumn); + } + + $lines[] = $this->_spaces . ' * },'; + $lines[] = $this->_spaces . ' * inverseJoinColumns={'; + + foreach ($associationMapping['joinTable']['inverseJoinColumns'] as $joinColumn) { + $lines[] = $this->_spaces . ' * ' . $this->_generateJoinColumnAnnotation($joinColumn); + } + + $lines[] = $this->_spaces . ' * }'; + $lines[] = $this->_spaces . ' * )'; + } + + if (isset($associationMapping['orderBy'])) { + $lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . 'OrderBy({'; + + foreach ($associationMapping['orderBy'] as $name => $direction) { + $lines[] = $this->_spaces . ' * "' . $name . '"="' . $direction . '",'; + } + + $lines[count($lines) - 1] = substr($lines[count($lines) - 1], 0, strlen($lines[count($lines) - 1]) - 1); + $lines[] = $this->_spaces . ' * })'; + } + } + + $lines[] = $this->_spaces . ' */'; + + return implode("\n", $lines); + } + + private function _generateFieldMappingPropertyDocBlock(array $fieldMapping, ClassMetadataInfo $metadata) + { + $lines = array(); + $lines[] = $this->_spaces . '/**'; + $lines[] = $this->_spaces . ' * @var ' . $fieldMapping['type'] . ' $' . $fieldMapping['fieldName']; + + if ($this->_generateAnnotations) { + $lines[] = $this->_spaces . ' *'; + + $column = array(); + if (isset($fieldMapping['columnName'])) { + $column[] = 'name="' . $fieldMapping['columnName'] . '"'; + } + + if (isset($fieldMapping['type'])) { + $column[] = 'type="' . $fieldMapping['type'] . '"'; + } + + if (isset($fieldMapping['length'])) { + $column[] = 'length=' . $fieldMapping['length']; + } + + if (isset($fieldMapping['precision'])) { + $column[] = 'precision=' . $fieldMapping['precision']; + } + + if (isset($fieldMapping['scale'])) { + $column[] = 'scale=' . $fieldMapping['scale']; + } + + if (isset($fieldMapping['nullable'])) { + $column[] = 'nullable=' . var_export($fieldMapping['nullable'], true); + } + + if (isset($fieldMapping['columnDefinition'])) { + $column[] = 'columnDefinition="' . $fieldMapping['columnDefinition'] . '"'; + } + + if (isset($fieldMapping['unique'])) { + $column[] = 'unique=' . var_export($fieldMapping['unique'], true); + } + + $lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . 'Column(' . implode(', ', $column) . ')'; + + if (isset($fieldMapping['id']) && $fieldMapping['id']) { + $lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . 'Id'; + + if ($generatorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) { + $lines[] = $this->_spaces.' * @' . $this->_annotationsPrefix . 'GeneratedValue(strategy="' . $generatorType . '")'; + } + + if ($metadata->sequenceGeneratorDefinition) { + $sequenceGenerator = array(); + + if (isset($metadata->sequenceGeneratorDefinition['sequenceName'])) { + $sequenceGenerator[] = 'sequenceName="' . $metadata->sequenceGeneratorDefinition['sequenceName'] . '"'; + } + + if (isset($metadata->sequenceGeneratorDefinition['allocationSize'])) { + $sequenceGenerator[] = 'allocationSize=' . $metadata->sequenceGeneratorDefinition['allocationSize']; + } + + if (isset($metadata->sequenceGeneratorDefinition['initialValue'])) { + $sequenceGenerator[] = 'initialValue=' . $metadata->sequenceGeneratorDefinition['initialValue']; + } + + $lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . 'SequenceGenerator(' . implode(', ', $sequenceGenerator) . ')'; + } + } + + if (isset($fieldMapping['version']) && $fieldMapping['version']) { + $lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . 'Version'; + } + } + + $lines[] = $this->_spaces . ' */'; + + return implode("\n", $lines); + } + + private function _prefixCodeWithSpaces($code, $num = 1) + { + $lines = explode("\n", $code); + + foreach ($lines as $key => $value) { + $lines[$key] = str_repeat($this->_spaces, $num) . $lines[$key]; + } + + return implode("\n", $lines); + } + + private function _getInheritanceTypeString($type) + { + switch ($type) { + case ClassMetadataInfo::INHERITANCE_TYPE_NONE: + return 'NONE'; + + case ClassMetadataInfo::INHERITANCE_TYPE_JOINED: + return 'JOINED'; + + case ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_TABLE: + return 'SINGLE_TABLE'; + + case ClassMetadataInfo::INHERITANCE_TYPE_TABLE_PER_CLASS: + return 'PER_CLASS'; + + default: + throw new \InvalidArgumentException('Invalid provided InheritanceType: ' . $type); + } + } + + private function _getChangeTrackingPolicyString($policy) + { + switch ($policy) { + case ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT: + return 'DEFERRED_IMPLICIT'; + + case ClassMetadataInfo::CHANGETRACKING_DEFERRED_EXPLICIT: + return 'DEFERRED_EXPLICIT'; + + case ClassMetadataInfo::CHANGETRACKING_NOTIFY: + return 'NOTIFY'; + + default: + throw new \InvalidArgumentException('Invalid provided ChangeTrackingPolicy: ' . $policy); + } + } + + private function _getIdGeneratorTypeString($type) + { + switch ($type) { + case ClassMetadataInfo::GENERATOR_TYPE_AUTO: + return 'AUTO'; + + case ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE: + return 'SEQUENCE'; + + case ClassMetadataInfo::GENERATOR_TYPE_TABLE: + return 'TABLE'; + + case ClassMetadataInfo::GENERATOR_TYPE_IDENTITY: + return 'IDENTITY'; + + case ClassMetadataInfo::GENERATOR_TYPE_NONE: + return 'NONE'; + + default: + throw new \InvalidArgumentException('Invalid provided IdGeneratorType: ' . $type); + } + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/EntityRepositoryGenerator.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/EntityRepositoryGenerator.php new file mode 100644 index 0000000..74740db --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/EntityRepositoryGenerator.php @@ -0,0 +1,83 @@ +. + */ + +namespace Doctrine\ORM\Tools; + +/** + * Class to generate entity repository classes + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class EntityRepositoryGenerator +{ + protected static $_template = +'; + +use Doctrine\ORM\EntityRepository; + +/** + * + * + * This class was generated by the Doctrine ORM. Add your own custom + * repository methods below. + */ +class extends EntityRepository +{ +}'; + + public function generateEntityRepositoryClass($fullClassName) + { + $namespace = substr($fullClassName, 0, strrpos($fullClassName, '\\')); + $className = substr($fullClassName, strrpos($fullClassName, '\\') + 1, strlen($fullClassName)); + + $variables = array( + '' => $namespace, + '' => $className + ); + return str_replace(array_keys($variables), array_values($variables), self::$_template); + } + + public function writeEntityRepositoryClass($fullClassName, $outputDirectory) + { + $code = $this->generateEntityRepositoryClass($fullClassName); + + $path = $outputDirectory . DIRECTORY_SEPARATOR + . str_replace('\\', \DIRECTORY_SEPARATOR, $fullClassName) . '.php'; + $dir = dirname($path); + + if ( ! is_dir($dir)) { + mkdir($dir, 0777, true); + } + + if ( ! file_exists($path)) { + file_put_contents($path, $code); + } + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Event/GenerateSchemaEventArgs.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Event/GenerateSchemaEventArgs.php new file mode 100644 index 0000000..02d04a2 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Event/GenerateSchemaEventArgs.php @@ -0,0 +1,65 @@ +. +*/ + +namespace Doctrine\ORM\Tools\Event; + +use Doctrine\DBAL\Schema\Schema; +use Doctrine\ORM\EntityManager; + +/** + * Event Args used for the Events::postGenerateSchema event. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 1.0 + * @version $Revision$ + * @author Benjamin Eberlei + */ +class GenerateSchemaEventArgs extends \Doctrine\Common\EventArgs +{ + private $_em = null; + private $_schema = null; + + /** + * @param ClassMetadata $classMetadata + * @param Schema $schema + * @param Table $classTable + */ + public function __construct(EntityManager $em, Schema $schema) + { + $this->_em = $em; + $this->_schema = $schema; + } + + /** + * @return EntityManager + */ + public function getEntityManager() { + return $this->_em; + } + + /** + * @return Schema + */ + public function getSchema() { + return $this->_schema; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Event/GenerateSchemaTableEventArgs.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Event/GenerateSchemaTableEventArgs.php new file mode 100644 index 0000000..54aa6e7 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Event/GenerateSchemaTableEventArgs.php @@ -0,0 +1,75 @@ +. +*/ + +namespace Doctrine\ORM\Tools\Event; + +use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\DBAL\Schema\Schema; +use Doctrine\DBAL\Schema\Table; + +/** + * Event Args used for the Events::postGenerateSchemaTable event. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 1.0 + * @version $Revision$ + * @author Benjamin Eberlei + */ +class GenerateSchemaTableEventArgs extends \Doctrine\Common\EventArgs +{ + private $_classMetadata = null; + private $_schema = null; + private $_classTable = null; + + /** + * @param ClassMetadata $classMetadata + * @param Schema $schema + * @param Table $classTable + */ + public function __construct(ClassMetadata $classMetadata, Schema $schema, Table $classTable) + { + $this->_classMetadata = $classMetadata; + $this->_schema = $schema; + $this->_classTable = $classTable; + } + + /** + * @return ClassMetadata + */ + public function getClassMetadata() { + return $this->_classMetadata; + } + + /** + * @return Schema + */ + public function getSchema() { + return $this->_schema; + } + + /** + * @return Table + */ + public function getClassTable() { + return $this->_classTable; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/ClassMetadataExporter.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/ClassMetadataExporter.php new file mode 100644 index 0000000..2b528a2 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/ClassMetadataExporter.php @@ -0,0 +1,76 @@ +. + */ + +namespace Doctrine\ORM\Tools\Export; + +use Doctrine\ORM\Tools\Export\ExportException, + Doctrine\ORM\EntityManager; + +/** + * Class used for converting your mapping information between the + * supported formats: yaml, xml, and php/annotation. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Jonathan Wage + */ +class ClassMetadataExporter +{ + private static $_exporterDrivers = array( + 'xml' => 'Doctrine\ORM\Tools\Export\Driver\XmlExporter', + 'yaml' => 'Doctrine\ORM\Tools\Export\Driver\YamlExporter', + 'yml' => 'Doctrine\ORM\Tools\Export\Driver\YamlExporter', + 'php' => 'Doctrine\ORM\Tools\Export\Driver\PhpExporter', + 'annotation' => 'Doctrine\ORM\Tools\Export\Driver\AnnotationExporter' + ); + + /** + * Register a new exporter driver class under a specified name + * + * @param string $name + * @param string $class + */ + public static function registerExportDriver($name, $class) + { + self::$_exporterDrivers[$name] = $class; + } + + /** + * Get a exporter driver instance + * + * @param string $type The type to get (yml, xml, etc.) + * @param string $source The directory where the exporter will export to + * @return AbstractExporter $exporter + */ + public function getExporter($type, $dest = null) + { + if ( ! isset(self::$_exporterDrivers[$type])) { + throw ExportException::invalidExporterDriverType($type); + } + + $class = self::$_exporterDrivers[$type]; + + return new $class($dest); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php new file mode 100644 index 0000000..41ec6fd --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php @@ -0,0 +1,217 @@ +. + */ + +namespace Doctrine\ORM\Tools\Export\Driver; + +use Doctrine\ORM\Mapping\ClassMetadataInfo; +use Doctrine\ORM\Tools\Export\ExportException; + +/** + * Abstract base class which is to be used for the Exporter drivers + * which can be found in \Doctrine\ORM\Tools\Export\Driver + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Jonathan Wage + */ +abstract class AbstractExporter +{ + protected $_metadata = array(); + protected $_outputDir; + protected $_extension; + protected $_overwriteExistingFiles = false; + + public function __construct($dir = null) + { + $this->_outputDir = $dir; + } + + public function setOverwriteExistingFiles($overwrite) + { + $this->_overwriteExistingFiles = $overwrite; + } + + /** + * Converts a single ClassMetadata instance to the exported format + * and returns it + * + * @param ClassMetadataInfo $metadata + * @return mixed $exported + */ + abstract public function exportClassMetadata(ClassMetadataInfo $metadata); + + /** + * Set the array of ClassMetadataInfo instances to export + * + * @param array $metadata + * @return void + */ + public function setMetadata(array $metadata) + { + $this->_metadata = $metadata; + } + + /** + * Get the extension used to generated the path to a class + * + * @return string $extension + */ + public function getExtension() + { + return $this->_extension; + } + + /** + * Set the directory to output the mapping files to + * + * [php] + * $exporter = new YamlExporter($metadata); + * $exporter->setOutputDir(__DIR__ . '/yaml'); + * $exporter->export(); + * + * @param string $dir + * @return void + */ + public function setOutputDir($dir) + { + $this->_outputDir = $dir; + } + + /** + * Export each ClassMetadata instance to a single Doctrine Mapping file + * named after the entity + * + * @return void + */ + public function export() + { + if ( ! is_dir($this->_outputDir)) { + mkdir($this->_outputDir, 0777, true); + } + + foreach ($this->_metadata as $metadata) { + //In case output is returned, write it to a file, skip otherwise + if($output = $this->exportClassMetadata($metadata)){ + $path = $this->_generateOutputPath($metadata); + $dir = dirname($path); + if ( ! is_dir($dir)) { + mkdir($dir, 0777, true); + } + if (file_exists($path) && !$this->_overwriteExistingFiles) { + throw ExportException::attemptOverwriteExistingFile($path); + } + file_put_contents($path, $output); + } + } + } + + /** + * Generate the path to write the class for the given ClassMetadataInfo instance + * + * @param ClassMetadataInfo $metadata + * @return string $path + */ + protected function _generateOutputPath(ClassMetadataInfo $metadata) + { + return $this->_outputDir . '/' . str_replace('\\', '.', $metadata->name) . $this->_extension; + } + + /** + * Set the directory to output the mapping files to + * + * [php] + * $exporter = new YamlExporter($metadata, __DIR__ . '/yaml'); + * $exporter->setExtension('.yml'); + * $exporter->export(); + * + * @param string $extension + * @return void + */ + public function setExtension($extension) + { + $this->_extension = $extension; + } + + protected function _getInheritanceTypeString($type) + { + switch ($type) + { + case ClassMetadataInfo::INHERITANCE_TYPE_NONE: + return 'NONE'; + break; + + case ClassMetadataInfo::INHERITANCE_TYPE_JOINED: + return 'JOINED'; + break; + + case ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_TABLE: + return 'SINGLE_TABLE'; + break; + + case ClassMetadataInfo::INHERITANCE_TYPE_TABLE_PER_CLASS: + return 'PER_CLASS'; + break; + } + } + + protected function _getChangeTrackingPolicyString($policy) + { + switch ($policy) + { + case ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT: + return 'DEFERRED_IMPLICIT'; + break; + + case ClassMetadataInfo::CHANGETRACKING_DEFERRED_EXPLICIT: + return 'DEFERRED_EXPLICIT'; + break; + + case ClassMetadataInfo::CHANGETRACKING_NOTIFY: + return 'NOTIFY'; + break; + } + } + + protected function _getIdGeneratorTypeString($type) + { + switch ($type) + { + case ClassMetadataInfo::GENERATOR_TYPE_AUTO: + return 'AUTO'; + break; + + case ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE: + return 'SEQUENCE'; + break; + + case ClassMetadataInfo::GENERATOR_TYPE_TABLE: + return 'TABLE'; + break; + + case ClassMetadataInfo::GENERATOR_TYPE_IDENTITY: + return 'IDENTITY'; + break; + } + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php new file mode 100644 index 0000000..5053290 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php @@ -0,0 +1,72 @@ +. + */ + +namespace Doctrine\ORM\Tools\Export\Driver; + +use Doctrine\ORM\Mapping\ClassMetadataInfo, + Doctrine\ORM\Mapping\AssociationMapping, + Doctrine\ORM\Tools\EntityGenerator; + +/** + * ClassMetadata exporter for PHP classes with annotations + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Jonathan Wage + */ +class AnnotationExporter extends AbstractExporter +{ + protected $_extension = '.php'; + private $_entityGenerator; + + /** + * Converts a single ClassMetadata instance to the exported format + * and returns it + * + * @param ClassMetadataInfo $metadata + * @return string $exported + */ + public function exportClassMetadata(ClassMetadataInfo $metadata) + { + if ( ! $this->_entityGenerator) { + throw new \RuntimeException('For the AnnotationExporter you must set an EntityGenerator instance with the setEntityGenerator() method.'); + } + $this->_entityGenerator->setGenerateAnnotations(true); + $this->_entityGenerator->setGenerateStubMethods(false); + $this->_entityGenerator->setRegenerateEntityIfExists(false); + $this->_entityGenerator->setUpdateEntityIfExists(false); + + return $this->_entityGenerator->generateEntityClass($metadata); + } + + protected function _generateOutputPath(ClassMetadataInfo $metadata) + { + return $this->_outputDir . '/' . str_replace('\\', '/', $metadata->name) . $this->_extension; + } + + public function setEntityGenerator(EntityGenerator $entityGenerator) + { + $this->_entityGenerator = $entityGenerator; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php new file mode 100644 index 0000000..5332edb --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php @@ -0,0 +1,169 @@ +. + */ + +namespace Doctrine\ORM\Tools\Export\Driver; + +use Doctrine\ORM\Mapping\ClassMetadataInfo; + +/** + * ClassMetadata exporter for PHP code + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Jonathan Wage + */ +class PhpExporter extends AbstractExporter +{ + protected $_extension = '.php'; + + /** + * Converts a single ClassMetadata instance to the exported format + * and returns it + * + * @param ClassMetadataInfo $metadata + * @return mixed $exported + */ + public function exportClassMetadata(ClassMetadataInfo $metadata) + { + $lines = array(); + $lines[] = 'isMappedSuperclass) { + $lines[] = '$metadata->isMappedSuperclass = true;'; + } + + if ($metadata->inheritanceType) { + $lines[] = '$metadata->setInheritanceType(ClassMetadataInfo::INHERITANCE_TYPE_' . $this->_getInheritanceTypeString($metadata->inheritanceType) . ');'; + } + + if ($metadata->customRepositoryClassName) { + $lines[] = "\$metadata->customRepositoryClassName = '" . $metadata->customRepositoryClassName . "';"; + } + + if ($metadata->table) { + $lines[] = '$metadata->setPrimaryTable(' . $this->_varExport($metadata->table) . ');'; + } + + if ($metadata->discriminatorColumn) { + $lines[] = '$metadata->setDiscriminatorColumn(' . $this->_varExport($metadata->discriminatorColumn) . ');'; + } + + if ($metadata->discriminatorMap) { + $lines[] = '$metadata->setDiscriminatorMap(' . $this->_varExport($metadata->discriminatorMap) . ');'; + } + + if ($metadata->changeTrackingPolicy) { + $lines[] = '$metadata->setChangeTrackingPolicy(ClassMetadataInfo::CHANGETRACKING_' . $this->_getChangeTrackingPolicyString($metadata->changeTrackingPolicy) . ');'; + } + + if ($metadata->lifecycleCallbacks) { + foreach ($metadata->lifecycleCallbacks as $event => $callbacks) { + foreach ($callbacks as $callback) { + $lines[] = "\$metadata->addLifecycleCallback('$callback', '$event');"; + } + } + } + + foreach ($metadata->fieldMappings as $fieldMapping) { + $lines[] = '$metadata->mapField(' . $this->_varExport($fieldMapping) . ');'; + } + + if ( ! $metadata->isIdentifierComposite && $generatorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) { + $lines[] = '$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_' . $generatorType . ');'; + } + + foreach ($metadata->associationMappings as $associationMapping) { + $cascade = array('remove', 'persist', 'refresh', 'merge', 'detach'); + foreach ($cascade as $key => $value) { + if ( ! $associationMapping['isCascade'.ucfirst($value)]) { + unset($cascade[$key]); + } + } + $associationMappingArray = array( + 'fieldName' => $associationMapping['fieldName'], + 'targetEntity' => $associationMapping['targetEntity'], + 'cascade' => $cascade, + ); + + if ($associationMapping['type'] & ClassMetadataInfo::TO_ONE) { + $method = 'mapOneToOne'; + $oneToOneMappingArray = array( + 'mappedBy' => $associationMapping['mappedBy'], + 'inversedBy' => $associationMapping['inversedBy'], + 'joinColumns' => $associationMapping['joinColumns'], + 'orphanRemoval' => $associationMapping['orphanRemoval'], + ); + + $associationMappingArray = array_merge($associationMappingArray, $oneToOneMappingArray); + } else if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) { + $method = 'mapOneToMany'; + $potentialAssociationMappingIndexes = array( + 'mappedBy', + 'orphanRemoval', + 'orderBy', + ); + foreach ($potentialAssociationMappingIndexes as $index) { + if (isset($associationMapping[$index])) { + $oneToManyMappingArray[$index] = $associationMapping[$index]; + } + } + $associationMappingArray = array_merge($associationMappingArray, $oneToManyMappingArray); + } else if ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) { + $method = 'mapManyToMany'; + $potentialAssociationMappingIndexes = array( + 'mappedBy', + 'joinTable', + 'orderBy', + ); + foreach ($potentialAssociationMappingIndexes as $index) { + if (isset($associationMapping[$index])) { + $manyToManyMappingArray[$index] = $associationMapping[$index]; + } + } + $associationMappingArray = array_merge($associationMappingArray, $manyToManyMappingArray); + } + + $lines[] = '$metadata->' . $method . '(' . $this->_varExport($associationMappingArray) . ');'; + } + + return implode("\n", $lines); + } + + protected function _varExport($var) + { + $export = var_export($var, true); + $export = str_replace("\n", PHP_EOL . str_repeat(' ', 8), $export); + $export = str_replace(' ', ' ', $export); + $export = str_replace('array (', 'array(', $export); + $export = str_replace('array( ', 'array(', $export); + $export = str_replace(',)', ')', $export); + $export = str_replace(', )', ')', $export); + $export = str_replace(' ', ' ', $export); + + return $export; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php new file mode 100644 index 0000000..2cad8a4 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php @@ -0,0 +1,320 @@ +. + */ + +namespace Doctrine\ORM\Tools\Export\Driver; + +use Doctrine\ORM\Mapping\ClassMetadataInfo; + +/** + * ClassMetadata exporter for Doctrine XML mapping files + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Jonathan Wage + */ +class XmlExporter extends AbstractExporter +{ + protected $_extension = '.dcm.xml'; + + /** + * Converts a single ClassMetadata instance to the exported format + * and returns it + * + * @param ClassMetadataInfo $metadata + * @return mixed $exported + */ + public function exportClassMetadata(ClassMetadataInfo $metadata) + { + $xml = new \SimpleXmlElement(""); + + /*$xml->addAttribute('xmlns', 'http://doctrine-project.org/schemas/orm/doctrine-mapping'); + $xml->addAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); + $xml->addAttribute('xsi:schemaLocation', 'http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd');*/ + + if ($metadata->isMappedSuperclass) { + $root = $xml->addChild('mapped-superclass'); + } else { + $root = $xml->addChild('entity'); + } + + if ($metadata->customRepositoryClassName) { + $root->addAttribute('repository-class', $metadata->customRepositoryClassName); + } + + $root->addAttribute('name', $metadata->name); + + if (isset($metadata->table['name'])) { + $root->addAttribute('table', $metadata->table['name']); + } + + if (isset($metadata->table['schema'])) { + $root->addAttribute('schema', $metadata->table['schema']); + } + + if (isset($metadata->table['inheritance-type'])) { + $root->addAttribute('inheritance-type', $metadata->table['inheritance-type']); + } + + if ($metadata->discriminatorColumn) { + $discriminatorColumnXml = $root->addChild('discriminiator-column'); + $discriminatorColumnXml->addAttribute('name', $metadata->discriminatorColumn['name']); + $discriminatorColumnXml->addAttribute('type', $metadata->discriminatorColumn['type']); + $discriminatorColumnXml->addAttribute('length', $metadata->discriminatorColumn['length']); + } + + if ($metadata->discriminatorMap) { + $discriminatorMapXml = $root->addChild('discriminator-map'); + foreach ($metadata->discriminatorMap as $value => $className) { + $discriminatorMappingXml = $discriminatorMapXml->addChild('discriminator-mapping'); + $discriminatorMappingXml->addAttribute('value', $value); + $discriminatorMappingXml->addAttribute('class', $className); + } + } + + $root->addChild('change-tracking-policy', $this->_getChangeTrackingPolicyString($metadata->changeTrackingPolicy)); + + if (isset($metadata->table['indexes'])) { + $indexesXml = $root->addChild('indexes'); + + foreach ($metadata->table['indexes'] as $name => $index) { + $indexXml = $indexesXml->addChild('index'); + $indexXml->addAttribute('name', $name); + $indexXml->addAttribute('columns', implode(',', $index['columns'])); + } + } + + if (isset($metadata->table['uniqueConstraints'])) { + $uniqueConstraintsXml = $root->addChild('unique-constraints'); + + foreach ($metadata->table['uniqueConstraints'] as $unique) { + $uniqueConstraintXml = $uniqueConstraintsXml->addChild('unique-constraint'); + $uniqueConstraintXml->addAttribute('name', $unique['name']); + $uniqueConstraintXml->addAttribute('columns', implode(',', $unique['columns'])); + } + } + + $fields = $metadata->fieldMappings; + + $id = array(); + foreach ($fields as $name => $field) { + if (isset($field['id']) && $field['id']) { + $id[$name] = $field; + unset($fields[$name]); + } + } + + if ( ! $metadata->isIdentifierComposite && $idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) { + $id[$metadata->getSingleIdentifierFieldName()]['generator']['strategy'] = $idGeneratorType; + } + + if ($id) { + foreach ($id as $field) { + $idXml = $root->addChild('id'); + $idXml->addAttribute('name', $field['fieldName']); + $idXml->addAttribute('type', $field['type']); + if (isset($field['columnName'])) { + $idXml->addAttribute('column', $field['columnName']); + } + if (isset($field['associationKey']) && $field['associationKey']) { + $idXml->addAttribute('association-key', 'true'); + } + if ($idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) { + $generatorXml = $idXml->addChild('generator'); + $generatorXml->addAttribute('strategy', $idGeneratorType); + } + } + } + + if ($fields) { + foreach ($fields as $field) { + $fieldXml = $root->addChild('field'); + $fieldXml->addAttribute('name', $field['fieldName']); + $fieldXml->addAttribute('type', $field['type']); + if (isset($field['columnName'])) { + $fieldXml->addAttribute('column', $field['columnName']); + } + if (isset($field['length'])) { + $fieldXml->addAttribute('length', $field['length']); + } + if (isset($field['precision'])) { + $fieldXml->addAttribute('precision', $field['precision']); + } + if (isset($field['scale'])) { + $fieldXml->addAttribute('scale', $field['scale']); + } + if (isset($field['unique']) && $field['unique']) { + $fieldXml->addAttribute('unique', $field['unique']); + } + if (isset($field['options'])) { + $optionsXml = $fieldXml->addChild('options'); + foreach ($field['options'] as $key => $value) { + $optionsXml->addAttribute($key, $value); + } + } + if (isset($field['version'])) { + $fieldXml->addAttribute('version', $field['version']); + } + if (isset($field['columnDefinition'])) { + $fieldXml->addAttribute('column-definition', $field['columnDefinition']); + } + } + } + + foreach ($metadata->associationMappings as $name => $associationMapping) { + if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_ONE) { + $associationMappingXml = $root->addChild('one-to-one'); + } else if ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_ONE) { + $associationMappingXml = $root->addChild('many-to-one'); + } else if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) { + $associationMappingXml = $root->addChild('one-to-many'); + } else if ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) { + $associationMappingXml = $root->addChild('many-to-many'); + } + + $associationMappingXml->addAttribute('field', $associationMapping['fieldName']); + $associationMappingXml->addAttribute('target-entity', $associationMapping['targetEntity']); + + if (isset($associationMapping['mappedBy'])) { + $associationMappingXml->addAttribute('mapped-by', $associationMapping['mappedBy']); + } + if (isset($associationMapping['inversedBy'])) { + $associationMappingXml->addAttribute('inversed-by', $associationMapping['inversedBy']); + } + if (isset($associationMapping['orphanRemoval'])) { + $associationMappingXml->addAttribute('orphan-removal', $associationMapping['orphanRemoval']); + } + if (isset($associationMapping['joinTable']) && $associationMapping['joinTable']) { + $joinTableXml = $associationMappingXml->addChild('join-table'); + $joinTableXml->addAttribute('name', $associationMapping['joinTable']['name']); + $joinColumnsXml = $joinTableXml->addChild('join-columns'); + foreach ($associationMapping['joinTable']['joinColumns'] as $joinColumn) { + $joinColumnXml = $joinColumnsXml->addChild('join-column'); + $joinColumnXml->addAttribute('name', $joinColumn['name']); + $joinColumnXml->addAttribute('referenced-column-name', $joinColumn['referencedColumnName']); + if (isset($joinColumn['onDelete'])) { + $joinColumnXml->addAttribute('on-delete', $joinColumn['onDelete']); + } + } + $inverseJoinColumnsXml = $joinTableXml->addChild('inverse-join-columns'); + foreach ($associationMapping['joinTable']['inverseJoinColumns'] as $inverseJoinColumn) { + $inverseJoinColumnXml = $inverseJoinColumnsXml->addChild('join-column'); + $inverseJoinColumnXml->addAttribute('name', $inverseJoinColumn['name']); + $inverseJoinColumnXml->addAttribute('referenced-column-name', $inverseJoinColumn['referencedColumnName']); + if (isset($inverseJoinColumn['onDelete'])) { + $inverseJoinColumnXml->addAttribute('on-delete', $inverseJoinColumn['onDelete']); + } + if (isset($inverseJoinColumn['columnDefinition'])) { + $inverseJoinColumnXml->addAttribute('column-definition', $inverseJoinColumn['columnDefinition']); + } + if (isset($inverseJoinColumn['nullable'])) { + $inverseJoinColumnXml->addAttribute('nullable', $inverseJoinColumn['nullable']); + } + if (isset($inverseJoinColumn['orderBy'])) { + $inverseJoinColumnXml->addAttribute('order-by', $inverseJoinColumn['orderBy']); + } + } + } + if (isset($associationMapping['joinColumns'])) { + $joinColumnsXml = $associationMappingXml->addChild('join-columns'); + foreach ($associationMapping['joinColumns'] as $joinColumn) { + $joinColumnXml = $joinColumnsXml->addChild('join-column'); + $joinColumnXml->addAttribute('name', $joinColumn['name']); + $joinColumnXml->addAttribute('referenced-column-name', $joinColumn['referencedColumnName']); + if (isset($joinColumn['onDelete'])) { + $joinColumnXml->addAttribute('on-delete', $joinColumn['onDelete']); + } + if (isset($joinColumn['columnDefinition'])) { + $joinColumnXml->addAttribute('column-definition', $joinColumn['columnDefinition']); + } + if (isset($joinColumn['nullable'])) { + $joinColumnXml->addAttribute('nullable', $joinColumn['nullable']); + } + } + } + if (isset($associationMapping['orderBy'])) { + $orderByXml = $associationMappingXml->addChild('order-by'); + foreach ($associationMapping['orderBy'] as $name => $direction) { + $orderByFieldXml = $orderByXml->addChild('order-by-field'); + $orderByFieldXml->addAttribute('name', $name); + $orderByFieldXml->addAttribute('direction', $direction); + } + } + $cascade = array(); + if ($associationMapping['isCascadeRemove']) { + $cascade[] = 'cascade-remove'; + } + if ($associationMapping['isCascadePersist']) { + $cascade[] = 'cascade-persist'; + } + if ($associationMapping['isCascadeRefresh']) { + $cascade[] = 'cascade-refresh'; + } + if ($associationMapping['isCascadeMerge']) { + $cascade[] = 'cascade-merge'; + } + if ($associationMapping['isCascadeDetach']) { + $cascade[] = 'cascade-detach'; + } + if (count($cascade) === 5) { + $cascade = array('cascade-all'); + } + if ($cascade) { + $cascadeXml = $associationMappingXml->addChild('cascade'); + foreach ($cascade as $type) { + $cascadeXml->addChild($type); + } + } + } + + if (isset($metadata->lifecycleCallbacks)) { + $lifecycleCallbacksXml = $root->addChild('lifecycle-callbacks'); + foreach ($metadata->lifecycleCallbacks as $name => $methods) { + foreach ($methods as $method) { + $lifecycleCallbackXml = $lifecycleCallbacksXml->addChild('lifecycle-callback'); + $lifecycleCallbackXml->addAttribute('type', $name); + $lifecycleCallbackXml->addAttribute('method', $method); + } + } + } + + return $this->_asXml($xml); + } + + /** + * @param \SimpleXMLElement $simpleXml + * @return string $xml + */ + private function _asXml($simpleXml) + { + $dom = new \DOMDocument('1.0', 'UTF-8'); + $dom->loadXML($simpleXml->asXML()); + $dom->formatOutput = true; + + $result = $dom->saveXML(); + return $result; + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php new file mode 100644 index 0000000..525f5f4 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php @@ -0,0 +1,210 @@ +. + */ + +namespace Doctrine\ORM\Tools\Export\Driver; + +use Doctrine\ORM\Mapping\ClassMetadataInfo; + +/** + * ClassMetadata exporter for Doctrine YAML mapping files + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Jonathan Wage + */ +class YamlExporter extends AbstractExporter +{ + protected $_extension = '.dcm.yml'; + + /** + * Converts a single ClassMetadata instance to the exported format + * and returns it + * + * TODO: Should this code be pulled out in to a toArray() method in ClassMetadata + * + * @param ClassMetadataInfo $metadata + * @return mixed $exported + */ + public function exportClassMetadata(ClassMetadataInfo $metadata) + { + $array = array(); + + if ($metadata->isMappedSuperclass) { + $array['type'] = 'mappedSuperclass'; + } else { + $array['type'] = 'entity'; + } + + $array['table'] = $metadata->table['name']; + + if (isset($metadata->table['schema'])) { + $array['schema'] = $metadata->table['schema']; + } + + $inheritanceType = $metadata->inheritanceType; + if ($inheritanceType !== ClassMetadataInfo::INHERITANCE_TYPE_NONE) { + $array['inheritanceType'] = $this->_getInheritanceTypeString($inheritanceType); + } + + if ($column = $metadata->discriminatorColumn) { + $array['discriminatorColumn'] = $column; + } + + if ($map = $metadata->discriminatorMap) { + $array['discriminatorMap'] = $map; + } + + if ($metadata->changeTrackingPolicy !== ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT) { + $array['changeTrackingPolicy'] = $this->_getChangeTrackingPolicyString($metadata->changeTrackingPolicy); + } + + if (isset($metadata->table['indexes'])) { + $array['indexes'] = $metadata->table['indexes']; + } + + if ($metadata->customRepositoryClassName) { + $array['repositoryClass'] = $metadata->customRepositoryClassName; + } + + if (isset($metadata->table['uniqueConstraints'])) { + $array['uniqueConstraints'] = $metadata->table['uniqueConstraints']; + } + + $fieldMappings = $metadata->fieldMappings; + + $ids = array(); + foreach ($fieldMappings as $name => $fieldMapping) { + $fieldMapping['column'] = $fieldMapping['columnName']; + unset( + $fieldMapping['columnName'], + $fieldMapping['fieldName'] + ); + + if ($fieldMapping['column'] == $name) { + unset($fieldMapping['column']); + } + + if (isset($fieldMapping['id']) && $fieldMapping['id']) { + $ids[$name] = $fieldMapping; + unset($fieldMappings[$name]); + continue; + } + + $fieldMappings[$name] = $fieldMapping; + } + + if ( ! $metadata->isIdentifierComposite && $idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) { + $ids[$metadata->getSingleIdentifierFieldName()]['generator']['strategy'] = $idGeneratorType; + } + + if ($ids) { + $array['fields'] = $ids; + } + + if ($fieldMappings) { + if ( ! isset($array['fields'])) { + $array['fields'] = array(); + } + $array['fields'] = array_merge($array['fields'], $fieldMappings); + } + + $associations = array(); + foreach ($metadata->associationMappings as $name => $associationMapping) { + $cascade = array(); + if ($associationMapping['isCascadeRemove']) { + $cascade[] = 'remove'; + } + if ($associationMapping['isCascadePersist']) { + $cascade[] = 'persist'; + } + if ($associationMapping['isCascadeRefresh']) { + $cascade[] = 'refresh'; + } + if ($associationMapping['isCascadeMerge']) { + $cascade[] = 'merge'; + } + if ($associationMapping['isCascadeDetach']) { + $cascade[] = 'detach'; + } + if (count($cascade) === 5) { + $cascade = array('all'); + } + $associationMappingArray = array( + 'targetEntity' => $associationMapping['targetEntity'], + 'cascade' => $cascade, + ); + + if ($associationMapping['type'] & ClassMetadataInfo::TO_ONE) { + $joinColumns = $associationMapping['joinColumns']; + $newJoinColumns = array(); + foreach ($joinColumns as $joinColumn) { + $newJoinColumns[$joinColumn['name']]['referencedColumnName'] = $joinColumn['referencedColumnName']; + if (isset($joinColumn['onDelete'])) { + $newJoinColumns[$joinColumn['name']]['onDelete'] = $joinColumn['onDelete']; + } + } + $oneToOneMappingArray = array( + 'mappedBy' => $associationMapping['mappedBy'], + 'inversedBy' => $associationMapping['inversedBy'], + 'joinColumns' => $newJoinColumns, + 'orphanRemoval' => $associationMapping['orphanRemoval'], + ); + + $associationMappingArray = array_merge($associationMappingArray, $oneToOneMappingArray); + + if ($associationMapping['type'] & ClassMetadataInfo::ONE_TO_ONE) { + $array['oneToOne'][$name] = $associationMappingArray; + } else { + $array['manyToOne'][$name] = $associationMappingArray; + } + + } else if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) { + $oneToManyMappingArray = array( + 'mappedBy' => $associationMapping['mappedBy'], + 'inversedBy' => $associationMapping['inversedBy'], + 'orphanRemoval' => $associationMapping['orphanRemoval'], + 'orderBy' => isset($associationMapping['orderBy']) ? $associationMapping['orderBy'] : null + ); + + $associationMappingArray = array_merge($associationMappingArray, $oneToManyMappingArray); + $array['oneToMany'][$name] = $associationMappingArray; + } else if ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) { + $manyToManyMappingArray = array( + 'mappedBy' => $associationMapping['mappedBy'], + 'inversedBy' => $associationMapping['inversedBy'], + 'joinTable' => isset($associationMapping['joinTable']) ? $associationMapping['joinTable'] : null, + 'orderBy' => isset($associationMapping['orderBy']) ? $associationMapping['orderBy'] : null + ); + + $associationMappingArray = array_merge($associationMappingArray, $manyToManyMappingArray); + $array['manyToMany'][$name] = $associationMappingArray; + } + } + if (isset($metadata->lifecycleCallbacks)) { + $array['lifecycleCallbacks'] = $metadata->lifecycleCallbacks; + } + + return \Symfony\Component\Yaml\Yaml::dump(array($metadata->name => $array), 10); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/ExportException.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/ExportException.php new file mode 100644 index 0000000..5ba8bd2 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/ExportException.php @@ -0,0 +1,23 @@ + + * @copyright Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/) + * @license http://hobodave.com/license.txt New BSD License + */ +class CountWalker extends TreeWalkerAdapter +{ + /** + * Distinct mode hint name + */ + const HINT_DISTINCT = 'doctrine_paginator.distinct'; + + /** + * Walks down a SelectStatement AST node, modifying it to retrieve a COUNT + * + * @param SelectStatement $AST + * @return void + */ + public function walkSelectStatement(SelectStatement $AST) + { + $rootComponents = array(); + foreach ($this->_getQueryComponents() AS $dqlAlias => $qComp) { + $isParent = array_key_exists('parent', $qComp) + && $qComp['parent'] === null + && $qComp['nestingLevel'] == 0 + ; + if ($isParent) { + $rootComponents[] = array($dqlAlias => $qComp); + } + } + if (count($rootComponents) > 1) { + throw new \RuntimeException("Cannot count query which selects two FROM components, cannot make distinction"); + } + $root = reset($rootComponents); + $parentName = key($root); + $parent = current($root); + + $pathExpression = new PathExpression( + PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, $parentName, + $parent['metadata']->getSingleIdentifierFieldName() + ); + $pathExpression->type = PathExpression::TYPE_STATE_FIELD; + + $distinct = $this->_getQuery()->getHint(self::HINT_DISTINCT); + $AST->selectClause->selectExpressions = array( + new SelectExpression( + new AggregateExpression('count', $pathExpression, $distinct), null + ) + ); + + // ORDER BY is not needed, only increases query execution through unnecessary sorting. + $AST->orderByClause = null; + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php new file mode 100644 index 0000000..97ed5ba --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php @@ -0,0 +1,115 @@ + + * @copyright Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/) + * @license http://hobodave.com/license.txt New BSD License + */ + +namespace Doctrine\ORM\Tools\Pagination; + +use Doctrine\DBAL\Types\Type, + Doctrine\ORM\Query\TreeWalkerAdapter, + Doctrine\ORM\Query\AST\SelectStatement, + Doctrine\ORM\Query\AST\SelectExpression, + Doctrine\ORM\Query\AST\PathExpression, + Doctrine\ORM\Query\AST\AggregateExpression; + +/** + * Replaces the selectClause of the AST with a SELECT DISTINCT root.id equivalent + * + * @category DoctrineExtensions + * @package DoctrineExtensions\Paginate + * @author David Abdemoulaie + * @copyright Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/) + * @license http://hobodave.com/license.txt New BSD License + */ +class LimitSubqueryWalker extends TreeWalkerAdapter +{ + /** + * ID type hint + */ + const IDENTIFIER_TYPE = 'doctrine_paginator.id.type'; + + /** + * @var int Counter for generating unique order column aliases + */ + private $_aliasCounter = 0; + + /** + * Walks down a SelectStatement AST node, modifying it to retrieve DISTINCT ids + * of the root Entity + * + * @param SelectStatement $AST + * @return void + */ + public function walkSelectStatement(SelectStatement $AST) + { + $parent = null; + $parentName = null; + $selectExpressions = array(); + + foreach ($this->_getQueryComponents() AS $dqlAlias => $qComp) { + // preserve mixed data in query for ordering + if (isset($qComp['resultVariable'])) { + $selectExpressions[] = new SelectExpression($qComp['resultVariable'], $dqlAlias); + continue; + } + + if ($qComp['parent'] === null && $qComp['nestingLevel'] == 0) { + $parent = $qComp; + $parentName = $dqlAlias; + continue; + } + } + + $identifier = $parent['metadata']->getSingleIdentifierFieldName(); + $this->_getQuery()->setHint( + self::IDENTIFIER_TYPE, + Type::getType($parent['metadata']->getTypeOfField($identifier)) + ); + + $pathExpression = new PathExpression( + PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, + $parentName, + $identifier + ); + $pathExpression->type = PathExpression::TYPE_STATE_FIELD; + + array_unshift($selectExpressions, new SelectExpression($pathExpression, '_dctrn_id')); + $AST->selectClause->selectExpressions = $selectExpressions; + + if (isset($AST->orderByClause)) { + foreach ($AST->orderByClause->orderByItems as $item) { + if ($item->expression instanceof PathExpression) { + $pathExpression = new PathExpression( + PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, + $item->expression->identificationVariable, + $item->expression->field + ); + $pathExpression->type = PathExpression::TYPE_STATE_FIELD; + $AST->selectClause->selectExpressions[] = new SelectExpression( + $pathExpression, + '_dctrn_ord' . $this->_aliasCounter++ + ); + } + } + } + + $AST->selectClause->isDistinct = true; + } + +} + + + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/Paginator.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/Paginator.php new file mode 100644 index 0000000..760d7de --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/Paginator.php @@ -0,0 +1,180 @@ +. + */ + +namespace Doctrine\ORM\Tools\Pagination; + +use Doctrine\ORM\QueryBuilder; +use Doctrine\ORM\Query; +use Doctrine\ORM\NoResultException; +use Doctrine\ORM\Tools\Pagination\WhereInWalker; +use Doctrine\ORM\Tools\Pagination\CountWalker; +use Countable; +use IteratorAggregate; +use ArrayIterator; + +/** + * Paginator + * + * The paginator can handle various complex scenarios with DQL. + * + * @author Pablo Díez + * @author Benjamin Eberlei + * @license New BSD + */ +class Paginator implements \Countable, \IteratorAggregate +{ + /** + * @var Query + */ + private $query; + + /** + * @var bool + */ + private $fetchJoinCollection; + + /** + * @var int + */ + private $count; + + /** + * Constructor. + * + * @param Query|QueryBuilder $query A Doctrine ORM query or query builder. + * @param Boolean $fetchJoinCollection Whether the query joins a collection (true by default). + */ + public function __construct($query, $fetchJoinCollection = true) + { + if ($query instanceof QueryBuilder) { + $query = $query->getQuery(); + } + + $this->query = $query; + $this->fetchJoinCollection = (Boolean) $fetchJoinCollection; + } + + /** + * Returns the query + * + * @return Query + */ + public function getQuery() + { + return $this->query; + } + + /** + * Returns whether the query joins a collection. + * + * @return Boolean Whether the query joins a collection. + */ + public function getFetchJoinCollection() + { + return $this->fetchJoinCollection; + } + + /** + * {@inheritdoc} + */ + public function count() + { + if ($this->count === null) { + /* @var $countQuery Query */ + $countQuery = $this->cloneQuery($this->query); + + if ( ! $countQuery->getHint(CountWalker::HINT_DISTINCT)) { + $countQuery->setHint(CountWalker::HINT_DISTINCT, true); + } + + $countQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\CountWalker')); + $countQuery->setFirstResult(null)->setMaxResults(null); + + try { + $data = $countQuery->getScalarResult(); + $data = array_map('current', $data); + $this->count = array_sum($data); + } catch(NoResultException $e) { + $this->count = 0; + } + } + return $this->count; + } + + /** + * {@inheritdoc} + */ + public function getIterator() + { + $offset = $this->query->getFirstResult(); + $length = $this->query->getMaxResults(); + + if ($this->fetchJoinCollection) { + $subQuery = $this->cloneQuery($this->query); + $subQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker')) + ->setFirstResult($offset) + ->setMaxResults($length); + + $ids = array_map('current', $subQuery->getScalarResult()); + + $whereInQuery = $this->cloneQuery($this->query); + // don't do this for an empty id array + if (count($ids) > 0) { + $namespace = WhereInWalker::PAGINATOR_ID_ALIAS; + + $whereInQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\WhereInWalker')); + $whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, count($ids)); + $whereInQuery->setFirstResult(null)->setMaxResults(null); + foreach ($ids as $i => $id) { + $i++; + $whereInQuery->setParameter("{$namespace}_{$i}", $id); + } + } + + $result = $whereInQuery->getResult($this->query->getHydrationMode()); + } else { + $result = $this->cloneQuery($this->query) + ->setMaxResults($length) + ->setFirstResult($offset) + ->getResult($this->query->getHydrationMode()) + ; + } + return new \ArrayIterator($result); + } + + /** + * Clones a query. + * + * @param Query $query The query. + * + * @return Query The cloned query. + */ + private function cloneQuery(Query $query) + { + /* @var $cloneQuery Query */ + $cloneQuery = clone $query; + $cloneQuery->setParameters($query->getParameters()); + foreach ($query->getHints() as $name => $value) { + $cloneQuery->setHint($name, $value); + } + + return $cloneQuery; + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/WhereInWalker.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/WhereInWalker.php new file mode 100644 index 0000000..5400ef2 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/WhereInWalker.php @@ -0,0 +1,142 @@ + + * @copyright Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/) + * @license http://hobodave.com/license.txt New BSD License + */ + +namespace Doctrine\ORM\Tools\Pagination; + +use Doctrine\ORM\Query\AST\ArithmeticExpression, + Doctrine\ORM\Query\AST\SimpleArithmeticExpression, + Doctrine\ORM\Query\TreeWalkerAdapter, + Doctrine\ORM\Query\AST\SelectStatement, + Doctrine\ORM\Query\AST\PathExpression, + Doctrine\ORM\Query\AST\InExpression, + Doctrine\ORM\Query\AST\NullComparisonExpression, + Doctrine\ORM\Query\AST\InputParameter, + Doctrine\ORM\Query\AST\ConditionalPrimary, + Doctrine\ORM\Query\AST\ConditionalTerm, + Doctrine\ORM\Query\AST\ConditionalExpression, + Doctrine\ORM\Query\AST\ConditionalFactor, + Doctrine\ORM\Query\AST\WhereClause; + +/** + * Replaces the whereClause of the AST with a WHERE id IN (:foo_1, :foo_2) equivalent + * + * @category DoctrineExtensions + * @package DoctrineExtensions\Paginate + * @author David Abdemoulaie + * @copyright Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/) + * @license http://hobodave.com/license.txt New BSD License + */ +class WhereInWalker extends TreeWalkerAdapter +{ + /** + * ID Count hint name + */ + const HINT_PAGINATOR_ID_COUNT = 'doctrine.id.count'; + + /** + * Primary key alias for query + */ + const PAGINATOR_ID_ALIAS = 'dpid'; + + /** + * Replaces the whereClause in the AST + * + * Generates a clause equivalent to WHERE IN (:dpid_1, :dpid_2, ...) + * + * The parameter namespace (dpid) is defined by + * the PAGINATOR_ID_ALIAS + * + * The total number of parameters is retrieved from + * the HINT_PAGINATOR_ID_COUNT query hint + * + * @param SelectStatement $AST + * @return void + */ + public function walkSelectStatement(SelectStatement $AST) + { + $rootComponents = array(); + foreach ($this->_getQueryComponents() AS $dqlAlias => $qComp) { + $isParent = array_key_exists('parent', $qComp) + && $qComp['parent'] === null + && $qComp['nestingLevel'] == 0 + ; + if ($isParent) { + $rootComponents[] = array($dqlAlias => $qComp); + } + } + if (count($rootComponents) > 1) { + throw new \RuntimeException("Cannot count query which selects two FROM components, cannot make distinction"); + } + $root = reset($rootComponents); + $parentName = key($root); + $parent = current($root); + + $pathExpression = new PathExpression( + PathExpression::TYPE_STATE_FIELD, $parentName, $parent['metadata']->getSingleIdentifierFieldName() + ); + $pathExpression->type = PathExpression::TYPE_STATE_FIELD; + + $count = $this->_getQuery()->getHint(self::HINT_PAGINATOR_ID_COUNT); + + if ($count > 0) { + $arithmeticExpression = new ArithmeticExpression(); + $arithmeticExpression->simpleArithmeticExpression = new SimpleArithmeticExpression( + array($pathExpression) + ); + $expression = new InExpression($arithmeticExpression); + $ns = self::PAGINATOR_ID_ALIAS; + + for ($i = 1; $i <= $count; $i++) { + $expression->literals[] = new InputParameter(":{$ns}_$i"); + } + } else { + $expression = new NullComparisonExpression($pathExpression); + $expression->not = false; + } + + $conditionalPrimary = new ConditionalPrimary; + $conditionalPrimary->simpleConditionalExpression = $expression; + if ($AST->whereClause) { + if ($AST->whereClause->conditionalExpression instanceof ConditionalTerm) { + $AST->whereClause->conditionalExpression->conditionalFactors[] = $conditionalPrimary; + } elseif ($AST->whereClause->conditionalExpression instanceof ConditionalPrimary) { + $AST->whereClause->conditionalExpression = new ConditionalExpression(array( + new ConditionalTerm(array( + $AST->whereClause->conditionalExpression, + $conditionalPrimary + )) + )); + } elseif ($AST->whereClause->conditionalExpression instanceof ConditionalExpression) { + $tmpPrimary = new ConditionalPrimary; + $tmpPrimary->conditionalExpression = $AST->whereClause->conditionalExpression; + $AST->whereClause->conditionalExpression = new ConditionalTerm(array( + $tmpPrimary, + $conditionalPrimary + )); + } + } else { + $AST->whereClause = new WhereClause( + new ConditionalExpression(array( + new ConditionalTerm(array( + $conditionalPrimary + )) + )) + ); + } + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ResolveTargetEntityListener.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ResolveTargetEntityListener.php new file mode 100644 index 0000000..621214f --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ResolveTargetEntityListener.php @@ -0,0 +1,94 @@ +. + */ + +namespace Doctrine\ORM\Tools; + +use Doctrine\ORM\Event\LoadClassMetadataEventArgs; +use Doctrine\ORM\Mapping\ClassMetadata; + +/** + * ResolveTargetEntityListener + * + * Mechanism to overwrite interfaces or classes specified as association + * targets. + * + * @author Benjamin Eberlei + * @since 2.2 + */ +class ResolveTargetEntityListener +{ + /** + * @var array + */ + private $resolveTargetEntities = array(); + + /** + * Add a target-entity class name to resolve to a new class name. + * + * @param string $originalEntity + * @param string $newEntity + * @param array $mapping + * @return void + */ + public function addResolveTargetEntity($originalEntity, $newEntity, array $mapping) + { + $mapping['targetEntity'] = ltrim($newEntity, "\\"); + $this->resolveTargetEntities[ltrim($originalEntity, "\\")] = $mapping; + } + + /** + * Process event and resolve new target entity names. + * + * @param LoadClassMetadataEventArgs $args + * @return void + */ + public function loadClassMetadata(LoadClassMetadataEventArgs $args) + { + $cm = $args->getClassMetadata(); + foreach ($cm->associationMappings as $assocName => $mapping) { + if (isset($this->resolveTargetEntities[$mapping['targetEntity']])) { + $this->remapAssociation($cm, $mapping); + } + } + } + + private function remapAssociation($classMetadata, $mapping) + { + $newMapping = $this->resolveTargetEntities[$mapping['targetEntity']]; + $newMapping = array_replace_recursive($mapping, $newMapping); + $newMapping['fieldName'] = $mapping['fieldName']; + unset($classMetadata->associationMappings[$mapping['fieldName']]); + + switch ($mapping['type']) { + case ClassMetadata::MANY_TO_MANY: + $classMetadata->mapManyToMany($newMapping); + break; + case ClassMetadata::MANY_TO_ONE: + $classMetadata->mapManyToOne($newMapping); + break; + case ClassMetadata::ONE_TO_MANY: + $classMetadata->mapOneToMany($newMapping); + break; + case ClassMetadata::ONE_TO_ONE: + $classMetadata->mapOneToOne($newMapping); + break; + } + } +} + diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/SchemaTool.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/SchemaTool.php new file mode 100644 index 0000000..efe7f7b --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/SchemaTool.php @@ -0,0 +1,701 @@ +. + */ + +namespace Doctrine\ORM\Tools; + +use Doctrine\ORM\ORMException, + Doctrine\DBAL\Types\Type, + Doctrine\DBAL\Schema\Schema, + Doctrine\DBAL\Schema\Visitor\RemoveNamespacedAssets, + Doctrine\ORM\EntityManager, + Doctrine\ORM\Mapping\ClassMetadata, + Doctrine\ORM\Internal\CommitOrderCalculator, + Doctrine\ORM\Tools\Event\GenerateSchemaTableEventArgs, + Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs; + +/** + * The SchemaTool is a tool to create/drop/update database schemas based on + * ClassMetadata class descriptors. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class SchemaTool +{ + /** + * @var \Doctrine\ORM\EntityManager + */ + private $_em; + + /** + * @var \Doctrine\DBAL\Platforms\AbstractPlatform + */ + private $_platform; + + /** + * Initializes a new SchemaTool instance that uses the connection of the + * provided EntityManager. + * + * @param \Doctrine\ORM\EntityManager $em + */ + public function __construct(EntityManager $em) + { + $this->_em = $em; + $this->_platform = $em->getConnection()->getDatabasePlatform(); + } + + /** + * Creates the database schema for the given array of ClassMetadata instances. + * + * @throws ToolsException + * @param array $classes + * @return void + */ + public function createSchema(array $classes) + { + $createSchemaSql = $this->getCreateSchemaSql($classes); + $conn = $this->_em->getConnection(); + + foreach ($createSchemaSql as $sql) { + try { + $conn->executeQuery($sql); + } catch(\Exception $e) { + throw ToolsException::schemaToolFailure($sql, $e); + } + } + } + + /** + * Gets the list of DDL statements that are required to create the database schema for + * the given list of ClassMetadata instances. + * + * @param array $classes + * @return array $sql The SQL statements needed to create the schema for the classes. + */ + public function getCreateSchemaSql(array $classes) + { + $schema = $this->getSchemaFromMetadata($classes); + return $schema->toSql($this->_platform); + } + + /** + * Some instances of ClassMetadata don't need to be processed in the SchemaTool context. This method detects them. + * + * @param ClassMetadata $class + * @param array $processedClasses + * @return bool + */ + private function processingNotRequired($class, array $processedClasses) + { + return ( + isset($processedClasses[$class->name]) || + $class->isMappedSuperclass || + ($class->isInheritanceTypeSingleTable() && $class->name != $class->rootEntityName) + ); + } + + /** + * From a given set of metadata classes this method creates a Schema instance. + * + * @param array $classes + * @return Schema + */ + public function getSchemaFromMetadata(array $classes) + { + $processedClasses = array(); // Reminder for processed classes, used for hierarchies + + $sm = $this->_em->getConnection()->getSchemaManager(); + $metadataSchemaConfig = $sm->createSchemaConfig(); + $metadataSchemaConfig->setExplicitForeignKeyIndexes(false); + $schema = new Schema(array(), array(), $metadataSchemaConfig); + + $evm = $this->_em->getEventManager(); + + foreach ($classes as $class) { + if ($this->processingNotRequired($class, $processedClasses)) { + continue; + } + + $table = $schema->createTable($class->getQuotedTableName($this->_platform)); + + $columns = array(); // table columns + + if ($class->isInheritanceTypeSingleTable()) { + $columns = $this->_gatherColumns($class, $table); + $this->_gatherRelationsSql($class, $table, $schema); + + // Add the discriminator column + $this->addDiscriminatorColumnDefinition($class, $table); + + // Aggregate all the information from all classes in the hierarchy + foreach ($class->parentClasses as $parentClassName) { + // Parent class information is already contained in this class + $processedClasses[$parentClassName] = true; + } + + foreach ($class->subClasses as $subClassName) { + $subClass = $this->_em->getClassMetadata($subClassName); + $this->_gatherColumns($subClass, $table); + $this->_gatherRelationsSql($subClass, $table, $schema); + $processedClasses[$subClassName] = true; + } + } else if ($class->isInheritanceTypeJoined()) { + // Add all non-inherited fields as columns + $pkColumns = array(); + foreach ($class->fieldMappings as $fieldName => $mapping) { + if ( ! isset($mapping['inherited'])) { + $columnName = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform); + $this->_gatherColumn($class, $mapping, $table); + + if ($class->isIdentifier($fieldName)) { + $pkColumns[] = $columnName; + } + } + } + + $this->_gatherRelationsSql($class, $table, $schema); + + // Add the discriminator column only to the root table + if ($class->name == $class->rootEntityName) { + $this->addDiscriminatorColumnDefinition($class, $table); + } else { + // Add an ID FK column to child tables + /* @var \Doctrine\ORM\Mapping\ClassMetadata $class */ + $idMapping = $class->fieldMappings[$class->identifier[0]]; + $this->_gatherColumn($class, $idMapping, $table); + $columnName = $class->getQuotedColumnName($class->identifier[0], $this->_platform); + // TODO: This seems rather hackish, can we optimize it? + $table->getColumn($columnName)->setAutoincrement(false); + + $pkColumns[] = $columnName; + + // Add a FK constraint on the ID column + $table->addUnnamedForeignKeyConstraint( + $this->_em->getClassMetadata($class->rootEntityName)->getQuotedTableName($this->_platform), + array($columnName), array($columnName), array('onDelete' => 'CASCADE') + ); + } + + $table->setPrimaryKey($pkColumns); + + } else if ($class->isInheritanceTypeTablePerClass()) { + throw ORMException::notSupported(); + } else { + $this->_gatherColumns($class, $table); + $this->_gatherRelationsSql($class, $table, $schema); + } + + $pkColumns = array(); + foreach ($class->identifier AS $identifierField) { + if (isset($class->fieldMappings[$identifierField])) { + $pkColumns[] = $class->getQuotedColumnName($identifierField, $this->_platform); + } else if (isset($class->associationMappings[$identifierField])) { + /* @var $assoc \Doctrine\ORM\Mapping\OneToOne */ + $assoc = $class->associationMappings[$identifierField]; + foreach ($assoc['joinColumns'] AS $joinColumn) { + $pkColumns[] = $joinColumn['name']; + } + } + } + if (!$table->hasIndex('primary')) { + $table->setPrimaryKey($pkColumns); + } + + if (isset($class->table['indexes'])) { + foreach ($class->table['indexes'] AS $indexName => $indexData) { + $table->addIndex($indexData['columns'], is_numeric($indexName) ? null : $indexName); + } + } + + if (isset($class->table['uniqueConstraints'])) { + foreach ($class->table['uniqueConstraints'] AS $indexName => $indexData) { + $table->addUniqueIndex($indexData['columns'], is_numeric($indexName) ? null : $indexName); + } + } + + $processedClasses[$class->name] = true; + + if ($class->isIdGeneratorSequence() && $class->name == $class->rootEntityName) { + $seqDef = $class->sequenceGeneratorDefinition; + + if (!$schema->hasSequence($seqDef['sequenceName'])) { + $schema->createSequence( + $seqDef['sequenceName'], + $seqDef['allocationSize'], + $seqDef['initialValue'] + ); + } + } + + if ($evm->hasListeners(ToolEvents::postGenerateSchemaTable)) { + $evm->dispatchEvent(ToolEvents::postGenerateSchemaTable, new GenerateSchemaTableEventArgs($class, $schema, $table)); + } + } + + if ( ! $this->_platform->supportsSchemas() && ! $this->_platform->canEmulateSchemas() ) { + $schema->visit(new RemoveNamespacedAssets()); + } + + if ($evm->hasListeners(ToolEvents::postGenerateSchema)) { + $evm->dispatchEvent(ToolEvents::postGenerateSchema, new GenerateSchemaEventArgs($this->_em, $schema)); + } + + return $schema; + } + + /** + * Gets a portable column definition as required by the DBAL for the discriminator + * column of a class. + * + * @param ClassMetadata $class + * @return array The portable column definition of the discriminator column as required by + * the DBAL. + */ + private function addDiscriminatorColumnDefinition($class, $table) + { + $discrColumn = $class->discriminatorColumn; + + if (!isset($discrColumn['type']) || (strtolower($discrColumn['type']) == 'string' && $discrColumn['length'] === null)) { + $discrColumn['type'] = 'string'; + $discrColumn['length'] = 255; + } + + $table->addColumn( + $discrColumn['name'], + $discrColumn['type'], + array('length' => $discrColumn['length'], 'notnull' => true) + ); + } + + /** + * Gathers the column definitions as required by the DBAL of all field mappings + * found in the given class. + * + * @param ClassMetadata $class + * @param Table $table + * @return array The list of portable column definitions as required by the DBAL. + */ + private function _gatherColumns($class, $table) + { + $columns = array(); + $pkColumns = array(); + + foreach ($class->fieldMappings as $fieldName => $mapping) { + if ($class->isInheritanceTypeSingleTable() && isset($mapping['inherited'])) { + continue; + } + + $column = $this->_gatherColumn($class, $mapping, $table); + + if ($class->isIdentifier($mapping['fieldName'])) { + $pkColumns[] = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform); + } + } + + // For now, this is a hack required for single table inheritence, since this method is called + // twice by single table inheritence relations + if(!$table->hasIndex('primary')) { + //$table->setPrimaryKey($pkColumns); + } + + return $columns; + } + + /** + * Creates a column definition as required by the DBAL from an ORM field mapping definition. + * + * @param ClassMetadata $class The class that owns the field mapping. + * @param array $mapping The field mapping. + * @param Table $table + * @return array The portable column definition as required by the DBAL. + */ + private function _gatherColumn($class, array $mapping, $table) + { + $columnName = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform); + $columnType = $mapping['type']; + + $options = array(); + $options['length'] = isset($mapping['length']) ? $mapping['length'] : null; + $options['notnull'] = isset($mapping['nullable']) ? ! $mapping['nullable'] : true; + if ($class->isInheritanceTypeSingleTable() && count($class->parentClasses) > 0) { + $options['notnull'] = false; + } + + $options['platformOptions'] = array(); + $options['platformOptions']['version'] = $class->isVersioned && $class->versionField == $mapping['fieldName'] ? true : false; + + if(strtolower($columnType) == 'string' && $options['length'] === null) { + $options['length'] = 255; + } + + if (isset($mapping['precision'])) { + $options['precision'] = $mapping['precision']; + } + + if (isset($mapping['scale'])) { + $options['scale'] = $mapping['scale']; + } + + if (isset($mapping['default'])) { + $options['default'] = $mapping['default']; + } + + if (isset($mapping['columnDefinition'])) { + $options['columnDefinition'] = $mapping['columnDefinition']; + } + + if (isset($mapping['options'])) { + $options['customSchemaOptions'] = $mapping['options']; + } + + if ($class->isIdGeneratorIdentity() && $class->getIdentifierFieldNames() == array($mapping['fieldName'])) { + $options['autoincrement'] = true; + } + if ($class->isInheritanceTypeJoined() && $class->name != $class->rootEntityName) { + $options['autoincrement'] = false; + } + + if ($table->hasColumn($columnName)) { + // required in some inheritance scenarios + $table->changeColumn($columnName, $options); + } else { + $table->addColumn($columnName, $columnType, $options); + } + + $isUnique = isset($mapping['unique']) ? $mapping['unique'] : false; + if ($isUnique) { + $table->addUniqueIndex(array($columnName)); + } + } + + /** + * Gathers the SQL for properly setting up the relations of the given class. + * This includes the SQL for foreign key constraints and join tables. + * + * @param ClassMetadata $class + * @param \Doctrine\DBAL\Schema\Table $table + * @param \Doctrine\DBAL\Schema\Schema $schema + * @return void + */ + private function _gatherRelationsSql($class, $table, $schema) + { + foreach ($class->associationMappings as $fieldName => $mapping) { + if (isset($mapping['inherited'])) { + continue; + } + + $foreignClass = $this->_em->getClassMetadata($mapping['targetEntity']); + + if ($mapping['type'] & ClassMetadata::TO_ONE && $mapping['isOwningSide']) { + $primaryKeyColumns = $uniqueConstraints = array(); // PK is unnecessary for this relation-type + + $this->_gatherRelationJoinColumns($mapping['joinColumns'], $table, $foreignClass, $mapping, $primaryKeyColumns, $uniqueConstraints); + + foreach($uniqueConstraints AS $indexName => $unique) { + $table->addUniqueIndex($unique['columns'], is_numeric($indexName) ? null : $indexName); + } + } else if ($mapping['type'] == ClassMetadata::ONE_TO_MANY && $mapping['isOwningSide']) { + //... create join table, one-many through join table supported later + throw ORMException::notSupported(); + } else if ($mapping['type'] == ClassMetadata::MANY_TO_MANY && $mapping['isOwningSide']) { + // create join table + $joinTable = $mapping['joinTable']; + + $theJoinTable = $schema->createTable($foreignClass->getQuotedJoinTableName($mapping, $this->_platform)); + + $primaryKeyColumns = $uniqueConstraints = array(); + + // Build first FK constraint (relation table => source table) + $this->_gatherRelationJoinColumns($joinTable['joinColumns'], $theJoinTable, $class, $mapping, $primaryKeyColumns, $uniqueConstraints); + + // Build second FK constraint (relation table => target table) + $this->_gatherRelationJoinColumns($joinTable['inverseJoinColumns'], $theJoinTable, $foreignClass, $mapping, $primaryKeyColumns, $uniqueConstraints); + + $theJoinTable->setPrimaryKey($primaryKeyColumns); + + foreach($uniqueConstraints AS $indexName => $unique) { + $theJoinTable->addUniqueIndex($unique['columns'], is_numeric($indexName) ? null : $indexName); + } + } + } + } + + /** + * Get the class metadata that is responsible for the definition of the referenced column name. + * + * Previously this was a simple task, but with DDC-117 this problem is actually recursive. If its + * not a simple field, go through all identifier field names that are associations recursivly and + * find that referenced column name. + * + * TODO: Is there any way to make this code more pleasing? + * + * @param ClassMetadata $class + * @param string $referencedColumnName + * @return array(ClassMetadata, referencedFieldName) + */ + private function getDefiningClass($class, $referencedColumnName) + { + $referencedFieldName = $class->getFieldName($referencedColumnName); + + if ($class->hasField($referencedFieldName)) { + return array($class, $referencedFieldName); + } else if (in_array($referencedColumnName, $class->getIdentifierColumnNames())) { + // it seems to be an entity as foreign key + foreach ($class->getIdentifierFieldNames() AS $fieldName) { + if ($class->hasAssociation($fieldName) && $class->getSingleAssociationJoinColumnName($fieldName) == $referencedColumnName) { + return $this->getDefiningClass( + $this->_em->getClassMetadata($class->associationMappings[$fieldName]['targetEntity']), + $class->getSingleAssociationReferencedJoinColumnName($fieldName) + ); + } + } + } + + return null; + } + + /** + * Gather columns and fk constraints that are required for one part of relationship. + * + * @param array $joinColumns + * @param \Doctrine\DBAL\Schema\Table $theJoinTable + * @param ClassMetadata $class + * @param array $mapping + * @param array $primaryKeyColumns + * @param array $uniqueConstraints + */ + private function _gatherRelationJoinColumns($joinColumns, $theJoinTable, $class, $mapping, &$primaryKeyColumns, &$uniqueConstraints) + { + $localColumns = array(); + $foreignColumns = array(); + $fkOptions = array(); + $foreignTableName = $class->getQuotedTableName($this->_platform); + + foreach ($joinColumns as $joinColumn) { + $columnName = $joinColumn['name']; + list($definingClass, $referencedFieldName) = $this->getDefiningClass($class, $joinColumn['referencedColumnName']); + + if (!$definingClass) { + throw new \Doctrine\ORM\ORMException( + "Column name `".$joinColumn['referencedColumnName']."` referenced for relation from ". + $mapping['sourceEntity'] . " towards ". $mapping['targetEntity'] . " does not exist." + ); + } + + $primaryKeyColumns[] = $columnName; + $localColumns[] = $columnName; + $foreignColumns[] = $joinColumn['referencedColumnName']; + + if ( ! $theJoinTable->hasColumn($joinColumn['name'])) { + // Only add the column to the table if it does not exist already. + // It might exist already if the foreign key is mapped into a regular + // property as well. + + $fieldMapping = $definingClass->getFieldMapping($referencedFieldName); + + $columnDef = null; + if (isset($joinColumn['columnDefinition'])) { + $columnDef = $joinColumn['columnDefinition']; + } else if (isset($fieldMapping['columnDefinition'])) { + $columnDef = $fieldMapping['columnDefinition']; + } + $columnOptions = array('notnull' => false, 'columnDefinition' => $columnDef); + if (isset($joinColumn['nullable'])) { + $columnOptions['notnull'] = !$joinColumn['nullable']; + } + if ($fieldMapping['type'] == "string" && isset($fieldMapping['length'])) { + $columnOptions['length'] = $fieldMapping['length']; + } else if ($fieldMapping['type'] == "decimal") { + $columnOptions['scale'] = $fieldMapping['scale']; + $columnOptions['precision'] = $fieldMapping['precision']; + } + + $theJoinTable->addColumn($columnName, $fieldMapping['type'], $columnOptions); + } + + if (isset($joinColumn['unique']) && $joinColumn['unique'] == true) { + $uniqueConstraints[] = array('columns' => array($columnName)); + } + + if (isset($joinColumn['onDelete'])) { + $fkOptions['onDelete'] = $joinColumn['onDelete']; + } + } + + $theJoinTable->addUnnamedForeignKeyConstraint( + $foreignTableName, $localColumns, $foreignColumns, $fkOptions + ); + } + + /** + * Drops the database schema for the given classes. + * + * In any way when an exception is thrown it is supressed since drop was + * issued for all classes of the schema and some probably just don't exist. + * + * @param array $classes + * @return void + */ + public function dropSchema(array $classes) + { + $dropSchemaSql = $this->getDropSchemaSQL($classes); + $conn = $this->_em->getConnection(); + + foreach ($dropSchemaSql as $sql) { + try { + $conn->executeQuery($sql); + } catch(\Exception $e) { + + } + } + } + + /** + * Drops all elements in the database of the current connection. + * + * @return void + */ + public function dropDatabase() + { + $dropSchemaSql = $this->getDropDatabaseSQL(); + $conn = $this->_em->getConnection(); + + foreach ($dropSchemaSql as $sql) { + $conn->executeQuery($sql); + } + } + + /** + * Gets the SQL needed to drop the database schema for the connections database. + * + * @return array + */ + public function getDropDatabaseSQL() + { + $sm = $this->_em->getConnection()->getSchemaManager(); + $schema = $sm->createSchema(); + + $visitor = new \Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector($this->_platform); + /* @var $schema \Doctrine\DBAL\Schema\Schema */ + $schema->visit($visitor); + return $visitor->getQueries(); + } + + /** + * Get SQL to drop the tables defined by the passed classes. + * + * @param array $classes + * @return array + */ + public function getDropSchemaSQL(array $classes) + { + $visitor = new \Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector($this->_platform); + $schema = $this->getSchemaFromMetadata($classes); + + $sm = $this->_em->getConnection()->getSchemaManager(); + $fullSchema = $sm->createSchema(); + foreach ($fullSchema->getTables() AS $table) { + if (!$schema->hasTable($table->getName())) { + foreach ($table->getForeignKeys() AS $foreignKey) { + /* @var $foreignKey \Doctrine\DBAL\Schema\ForeignKeyConstraint */ + if ($schema->hasTable($foreignKey->getForeignTableName())) { + $visitor->acceptForeignKey($table, $foreignKey); + } + } + } else { + $visitor->acceptTable($table); + foreach ($table->getForeignKeys() AS $foreignKey) { + $visitor->acceptForeignKey($table, $foreignKey); + } + } + } + + if ($this->_platform->supportsSequences()) { + foreach ($schema->getSequences() AS $sequence) { + $visitor->acceptSequence($sequence); + } + foreach ($schema->getTables() AS $table) { + /* @var $sequence Table */ + if ($table->hasPrimaryKey()) { + $columns = $table->getPrimaryKey()->getColumns(); + if (count($columns) == 1) { + $checkSequence = $table->getName() . "_" . $columns[0] . "_seq"; + if ($fullSchema->hasSequence($checkSequence)) { + $visitor->acceptSequence($fullSchema->getSequence($checkSequence)); + } + } + } + } + } + + return $visitor->getQueries(); + } + + /** + * Updates the database schema of the given classes by comparing the ClassMetadata + * instances to the current database schema that is inspected. If $saveMode is set + * to true the command is executed in the Database, else SQL is returned. + * + * @param array $classes + * @param boolean $saveMode + * @return void + */ + public function updateSchema(array $classes, $saveMode=false) + { + $updateSchemaSql = $this->getUpdateSchemaSql($classes, $saveMode); + $conn = $this->_em->getConnection(); + + foreach ($updateSchemaSql as $sql) { + $conn->executeQuery($sql); + } + } + + /** + * Gets the sequence of SQL statements that need to be performed in order + * to bring the given class mappings in-synch with the relational schema. + * If $saveMode is set to true the command is executed in the Database, + * else SQL is returned. + * + * @param array $classes The classes to consider. + * @param boolean $saveMode True for writing to DB, false for SQL string + * @return array The sequence of SQL statements. + */ + public function getUpdateSchemaSql(array $classes, $saveMode=false) + { + $sm = $this->_em->getConnection()->getSchemaManager(); + + $fromSchema = $sm->createSchema(); + $toSchema = $this->getSchemaFromMetadata($classes); + + $comparator = new \Doctrine\DBAL\Schema\Comparator(); + $schemaDiff = $comparator->compare($fromSchema, $toSchema); + + if ($saveMode) { + return $schemaDiff->toSaveSql($this->_platform); + } else { + return $schemaDiff->toSql($this->_platform); + } + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/SchemaValidator.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/SchemaValidator.php new file mode 100644 index 0000000..0932f09 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/SchemaValidator.php @@ -0,0 +1,267 @@ +. +*/ + +namespace Doctrine\ORM\Tools; + +use Doctrine\ORM\EntityManager; +use Doctrine\ORM\Mapping\ClassMetadataInfo; +use Doctrine\DBAL\Types\Type; + +/** + * Performs strict validation of the mapping schema + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 1.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class SchemaValidator +{ + /** + * @var EntityManager + */ + private $em; + + /** + * @param EntityManager $em + */ + public function __construct(EntityManager $em) + { + $this->em = $em; + } + + /** + * Checks the internal consistency of all mapping files. + * + * There are several checks that can't be done at runtime or are too expensive, which can be verified + * with this command. For example: + * + * 1. Check if a relation with "mappedBy" is actually connected to that specified field. + * 2. Check if "mappedBy" and "inversedBy" are consistent to each other. + * 3. Check if "referencedColumnName" attributes are really pointing to primary key columns. + * 4. Check if there are public properties that might cause problems with lazy loading. + * + * @return array + */ + public function validateMapping() + { + $errors = array(); + $cmf = $this->em->getMetadataFactory(); + $classes = $cmf->getAllMetadata(); + + foreach ($classes AS $class) { + if ($ce = $this->validateClass($class)) { + $errors[$class->name] = $ce; + } + } + + return $errors; + } + + /** + * Validate a single class of the current + * + * @param ClassMetadataInfo $class + * @return array + */ + public function validateClass(ClassMetadataInfo $class) + { + $ce = array(); + $cmf = $this->em->getMetadataFactory(); + + foreach ($class->fieldMappings as $fieldName => $mapping) { + if (!Type::hasType($mapping['type'])) { + $ce[] = "The field '" . $class->name . "#" . $fieldName."' uses a non-existant type '" . $mapping['type'] . "'."; + } + } + + foreach ($class->associationMappings AS $fieldName => $assoc) { + if (!class_exists($assoc['targetEntity']) || $cmf->isTransient($assoc['targetEntity'])) { + $ce[] = "The target entity '" . $assoc['targetEntity'] . "' specified on " . $class->name . '#' . $fieldName . ' is unknown or not an entity.'; + return $ce; + } + + if ($assoc['mappedBy'] && $assoc['inversedBy']) { + $ce[] = "The association " . $class . "#" . $fieldName . " cannot be defined as both inverse and owning."; + } + + $targetMetadata = $cmf->getMetadataFor($assoc['targetEntity']); + + if (isset($assoc['id']) && $targetMetadata->containsForeignIdentifier) { + $ce[] = "Cannot map association '" . $class->name. "#". $fieldName ." as identifier, because " . + "the target entity '". $targetMetadata->name . "' also maps an association as identifier."; + } + + /* @var $assoc AssociationMapping */ + if ($assoc['mappedBy']) { + if ($targetMetadata->hasField($assoc['mappedBy'])) { + $ce[] = "The association " . $class->name . "#" . $fieldName . " refers to the owning side ". + "field " . $assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " which is not defined as association."; + } + if (!$targetMetadata->hasAssociation($assoc['mappedBy'])) { + $ce[] = "The association " . $class->name . "#" . $fieldName . " refers to the owning side ". + "field " . $assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " which does not exist."; + } else if ($targetMetadata->associationMappings[$assoc['mappedBy']]['inversedBy'] == null) { + $ce[] = "The field " . $class->name . "#" . $fieldName . " is on the inverse side of a ". + "bi-directional relationship, but the specified mappedBy association on the target-entity ". + $assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " does not contain the required ". + "'inversedBy=".$fieldName."' attribute."; + } else if ($targetMetadata->associationMappings[$assoc['mappedBy']]['inversedBy'] != $fieldName) { + $ce[] = "The mappings " . $class->name . "#" . $fieldName . " and " . + $assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " are ". + "incosistent with each other."; + } + } + + if ($assoc['inversedBy']) { + if ($targetMetadata->hasField($assoc['inversedBy'])) { + $ce[] = "The association " . $class->name . "#" . $fieldName . " refers to the inverse side ". + "field " . $assoc['targetEntity'] . "#" . $assoc['inversedBy'] . " which is not defined as association."; + } + if (!$targetMetadata->hasAssociation($assoc['inversedBy'])) { + $ce[] = "The association " . $class->name . "#" . $fieldName . " refers to the inverse side ". + "field " . $assoc['targetEntity'] . "#" . $assoc['inversedBy'] . " which does not exist."; + } else if ($targetMetadata->associationMappings[$assoc['inversedBy']]['mappedBy'] == null) { + $ce[] = "The field " . $class->name . "#" . $fieldName . " is on the owning side of a ". + "bi-directional relationship, but the specified mappedBy association on the target-entity ". + $assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " does not contain the required ". + "'inversedBy' attribute."; + } else if ($targetMetadata->associationMappings[$assoc['inversedBy']]['mappedBy'] != $fieldName) { + $ce[] = "The mappings " . $class->name . "#" . $fieldName . " and " . + $assoc['targetEntity'] . "#" . $assoc['inversedBy'] . " are ". + "incosistent with each other."; + } + + // Verify inverse side/owning side match each other + if (array_key_exists($assoc['inversedBy'], $targetMetadata->associationMappings)) { + $targetAssoc = $targetMetadata->associationMappings[$assoc['inversedBy']]; + if ($assoc['type'] == ClassMetadataInfo::ONE_TO_ONE && $targetAssoc['type'] !== ClassMetadataInfo::ONE_TO_ONE){ + $ce[] = "If association " . $class->name . "#" . $fieldName . " is one-to-one, then the inversed " . + "side " . $targetMetadata->name . "#" . $assoc['inversedBy'] . " has to be one-to-one as well."; + } else if ($assoc['type'] == ClassMetadataInfo::MANY_TO_ONE && $targetAssoc['type'] !== ClassMetadataInfo::ONE_TO_MANY){ + $ce[] = "If association " . $class->name . "#" . $fieldName . " is many-to-one, then the inversed " . + "side " . $targetMetadata->name . "#" . $assoc['inversedBy'] . " has to be one-to-many."; + } else if ($assoc['type'] == ClassMetadataInfo::MANY_TO_MANY && $targetAssoc['type'] !== ClassMetadataInfo::MANY_TO_MANY){ + $ce[] = "If association " . $class->name . "#" . $fieldName . " is many-to-many, then the inversed " . + "side " . $targetMetadata->name . "#" . $assoc['inversedBy'] . " has to be many-to-many as well."; + } + } + } + + if ($assoc['isOwningSide']) { + if ($assoc['type'] == ClassMetadataInfo::MANY_TO_MANY) { + $identifierColumns = $class->getIdentifierColumnNames(); + foreach ($assoc['joinTable']['joinColumns'] AS $joinColumn) { + if (!in_array($joinColumn['referencedColumnName'], $identifierColumns)) { + $ce[] = "The referenced column name '" . $joinColumn['referencedColumnName'] . "' " . + "has to be a primary key column on the target entity class '".$class->name."'."; + break; + } + } + + $identifierColumns = $targetMetadata->getIdentifierColumnNames(); + foreach ($assoc['joinTable']['inverseJoinColumns'] AS $inverseJoinColumn) { + if (!in_array($inverseJoinColumn['referencedColumnName'], $identifierColumns)) { + $ce[] = "The referenced column name '" . $joinColumn['referencedColumnName'] . "' " . + "has to be a primary key column on the target entity class '".$targetMetadata->name."'."; + break; + } + } + + if (count($targetMetadata->getIdentifierColumnNames()) != count($assoc['joinTable']['inverseJoinColumns'])) { + $ce[] = "The inverse join columns of the many-to-many table '" . $assoc['joinTable']['name'] . "' " . + "have to contain to ALL identifier columns of the target entity '". $targetMetadata->name . "', " . + "however '" . implode(", ", array_diff($targetMetadata->getIdentifierColumnNames(), array_values($assoc['relationToTargetKeyColumns']))) . + "' are missing."; + } + + if (count($class->getIdentifierColumnNames()) != count($assoc['joinTable']['joinColumns'])) { + $ce[] = "The join columns of the many-to-many table '" . $assoc['joinTable']['name'] . "' " . + "have to contain to ALL identifier columns of the source entity '". $class->name . "', " . + "however '" . implode(", ", array_diff($class->getIdentifierColumnNames(), array_values($assoc['relationToSourceKeyColumns']))) . + "' are missing."; + } + + } else if ($assoc['type'] & ClassMetadataInfo::TO_ONE) { + $identifierColumns = $targetMetadata->getIdentifierColumnNames(); + foreach ($assoc['joinColumns'] AS $joinColumn) { + if (!in_array($joinColumn['referencedColumnName'], $identifierColumns)) { + $ce[] = "The referenced column name '" . $joinColumn['referencedColumnName'] . "' " . + "has to be a primary key column on the target entity class '".$targetMetadata->name."'."; + } + } + + if (count($identifierColumns) != count($assoc['joinColumns'])) { + $ids = array(); + foreach ($assoc['joinColumns'] AS $joinColumn) { + $ids[] = $joinColumn['name']; + } + + $ce[] = "The join columns of the association '" . $assoc['fieldName'] . "' " . + "have to match to ALL identifier columns of the target entity '". $class->name . "', " . + "however '" . implode(", ", array_diff($targetMetadata->getIdentifierColumnNames(), $ids)) . + "' are missing."; + } + } + } + + if (isset($assoc['orderBy']) && $assoc['orderBy'] !== null) { + foreach ($assoc['orderBy'] AS $orderField => $orientation) { + if (!$targetMetadata->hasField($orderField)) { + $ce[] = "The association " . $class->name."#".$fieldName." is ordered by a foreign field " . + $orderField . " that is not a field on the target entity " . $targetMetadata->name; + } + } + } + } + + foreach ($class->reflClass->getProperties(\ReflectionProperty::IS_PUBLIC) as $publicAttr) { + if ($publicAttr->isStatic()) { + continue; + } + $ce[] = "Field '".$publicAttr->getName()."' in class '".$class->name."' must be private ". + "or protected. Public fields may break lazy-loading."; + } + + foreach ($class->subClasses AS $subClass) { + if (!in_array($class->name, class_parents($subClass))) { + $ce[] = "According to the discriminator map class '" . $subClass . "' has to be a child ". + "of '" . $class->name . "' but these entities are not related through inheritance."; + } + } + + return $ce; + } + + /** + * Check if the Database Schema is in sync with the current metadata state. + * + * @return bool + */ + public function schemaInSyncWithMetadata() + { + $schemaTool = new SchemaTool($this->em); + + $allMetadata = $this->em->getMetadataFactory()->getAllMetadata(); + return (count($schemaTool->getUpdateSchemaSql($allMetadata, true)) == 0); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Setup.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Setup.php new file mode 100644 index 0000000..c2550e2 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Setup.php @@ -0,0 +1,194 @@ +. +*/ + +namespace Doctrine\ORM\Tools; + +use Doctrine\Common\ClassLoader; +use Doctrine\Common\Cache\Cache; +use Doctrine\Common\Cache\ArrayCache; +use Doctrine\ORM\Configuration; +use Doctrine\ORM\Mapping\Driver\XmlDriver; +use Doctrine\ORM\Mapping\Driver\YamlDriver; + +/** + * Convenience class for setting up Doctrine from different installations and configurations. + * + * @author Benjamin Eberlei + */ +class Setup +{ + /** + * Use this method to register all autoloaders for a setup where Doctrine is checked out from + * its github repository at {@link http://github.com/doctrine/doctrine2} + * + * @param string $gitCheckoutRootPath + * @return void + */ + static public function registerAutoloadGit($gitCheckoutRootPath) + { + if (!class_exists('Doctrine\Common\ClassLoader', false)) { + require_once $gitCheckoutRootPath . "/lib/vendor/doctrine-common/lib/Doctrine/Common/ClassLoader.php"; + } + + $loader = new ClassLoader("Doctrine\Common", $gitCheckoutRootPath . "/lib/vendor/doctrine-common/lib"); + $loader->register(); + + $loader = new ClassLoader("Doctrine\DBAL", $gitCheckoutRootPath . "/lib/vendor/doctrine-dbal/lib"); + $loader->register(); + + $loader = new ClassLoader("Doctrine\ORM", $gitCheckoutRootPath . "/lib"); + $loader->register(); + + $loader = new ClassLoader("Symfony\Component", $gitCheckoutRootPath . "/lib/vendor"); + $loader->register(); + } + + /** + * Use this method to register all autoloaders for a setup where Doctrine is installed + * though {@link http://pear.doctrine-project.org}. + * + * @return void + */ + static public function registerAutoloadPEAR() + { + if (!class_exists('Doctrine\Common\ClassLoader', false)) { + require_once "Doctrine/Common/ClassLoader.php"; + } + + $loader = new ClassLoader("Doctrine"); + $loader->register(); + + $parts = explode(PATH_SEPARATOR, get_include_path()); + + foreach ($parts AS $includePath) { + if ($includePath != "." && file_exists($includePath . "/Doctrine")) { + $loader = new ClassLoader("Symfony\Component", $includePath . "/Doctrine"); + $loader->register(); + return; + } + } + } + + /** + * Use this method to register all autoloads for a downloaded Doctrine library. + * Pick the directory the library was uncompressed into. + * + * @param string $directory + */ + static public function registerAutoloadDirectory($directory) + { + if (!class_exists('Doctrine\Common\ClassLoader', false)) { + require_once $directory . "/Doctrine/Common/ClassLoader.php"; + } + + $loader = new ClassLoader("Doctrine", $directory); + $loader->register(); + + $loader = new ClassLoader("Symfony\Component", $directory . "/Doctrine"); + $loader->register(); + } + + /** + * Create a configuration with an annotation metadata driver. + * + * @param array $paths + * @param boolean $isDevMode + * @param string $proxyDir + * @param Cache $cache + * @return Configuration + */ + static public function createAnnotationMetadataConfiguration(array $paths, $isDevMode = false, $proxyDir = null, Cache $cache = null) + { + $config = self::createConfiguration($isDevMode, $proxyDir, $cache); + $config->setMetadataDriverImpl($config->newDefaultAnnotationDriver($paths)); + return $config; + } + + /** + * Create a configuration with a xml metadata driver. + * + * @param array $paths + * @param boolean $isDevMode + * @param string $proxyDir + * @param Cache $cache + * @return Configuration + */ + static public function createXMLMetadataConfiguration(array $paths, $isDevMode = false, $proxyDir = null, Cache $cache = null) + { + $config = self::createConfiguration($isDevMode, $proxyDir, $cache); + $config->setMetadataDriverImpl(new XmlDriver($paths)); + return $config; + } + + /** + * Create a configuration with a yaml metadata driver. + * + * @param array $paths + * @param boolean $isDevMode + * @param string $proxyDir + * @param Cache $cache + * @return Configuration + */ + static public function createYAMLMetadataConfiguration(array $paths, $isDevMode = false, $proxyDir = null, Cache $cache = null) + { + $config = self::createConfiguration($isDevMode, $proxyDir, $cache); + $config->setMetadataDriverImpl(new YamlDriver($paths)); + return $config; + } + + /** + * Create a configuration without a metadata driver. + * + * @param bool $isDevMode + * @param string $proxyDir + * @param Cache $cache + * @return Configuration + */ + static public function createConfiguration($isDevMode = false, $proxyDir = null, Cache $cache = null) + { + $proxyDir = $proxyDir ?: sys_get_temp_dir(); + if ($isDevMode === false && $cache === null) { + if (extension_loaded('apc')) { + $cache = new \Doctrine\Common\Cache\ApcCache; + } else if (extension_loaded('xcache')) { + $cache = new \Doctrine\Common\Cache\XcacheCache; + } else if (extension_loaded('memcache')) { + $memcache = new \Memcache(); + $memcache->connect('127.0.0.1'); + $cache = new \Doctrine\Common\Cache\MemcacheCache(); + $cache->setMemcache($memcache); + } else { + $cache = new ArrayCache; + } + } else if ($cache === null) { + $cache = new ArrayCache; + } + $cache->setNamespace("dc2_" . md5($proxyDir) . "_"); // to avoid collisions + + $config = new Configuration(); + $config->setMetadataCacheImpl($cache); + $config->setQueryCacheImpl($cache); + $config->setResultCacheImpl($cache); + $config->setProxyDir( $proxyDir ); + $config->setProxyNamespace('DoctrineProxies'); + $config->setAutoGenerateProxyClasses($isDevMode); + + return $config; + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ToolEvents.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ToolEvents.php new file mode 100644 index 0000000..7ea1f57 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ToolEvents.php @@ -0,0 +1,44 @@ +. +*/ + +namespace Doctrine\ORM\Tools; + +class ToolEvents +{ + /** + * The postGenerateSchemaTable event occurs in SchemaTool#getSchemaFromMetadata() + * whenever an entity class is transformed into its table representation. It recieves + * the current non-complete Schema instance, the Entity Metadata Class instance and + * the Schema Table instance of this entity. + * + * @var string + */ + const postGenerateSchemaTable = 'postGenerateSchemaTable'; + + /** + * The postGenerateSchema event is triggered in SchemaTool#getSchemaFromMetadata() + * after all entity classes have been transformed into the related Schema structure. + * The EventArgs contain the EntityManager and the created Schema instance. + * + * @var string + */ + const postGenerateSchema = 'postGenerateSchema'; +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ToolsException.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ToolsException.php new file mode 100644 index 0000000..4551d87 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ToolsException.php @@ -0,0 +1,40 @@ +. + */ + +namespace Doctrine\ORM\Tools; + +use Doctrine\ORM\ORMException; + +/** + * Tools related Exceptions + * + * @author Benjamin Eberlei + */ +class ToolsException extends ORMException +{ + public static function schemaToolFailure($sql, \Exception $e) + { + return new self("Schema-Tool failed with Error '" . $e->getMessage() . "' while executing DDL: " . $sql, "0", $e); + } + + public static function couldNotMapDoctrine1Type($type) + { + return new self("Could not map doctrine 1 type '$type'!"); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/TransactionRequiredException.php b/vendor/doctrine/orm/lib/Doctrine/ORM/TransactionRequiredException.php new file mode 100644 index 0000000..170f63e --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/TransactionRequiredException.php @@ -0,0 +1,40 @@ +. +*/ + +namespace Doctrine\ORM; + +/** + * Is thrown when a transaction is required for the current operation, but there is none open. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 1.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Roman Borschel + */ +class TransactionRequiredException extends ORMException +{ + static public function transactionRequired() + { + return new self('An open transaction is required for this operation.'); + } +} \ No newline at end of file diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php b/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php new file mode 100644 index 0000000..965c7d5 --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php @@ -0,0 +1,2949 @@ +. + */ + +namespace Doctrine\ORM; + +use Exception, InvalidArgumentException, UnexpectedValueException, + Doctrine\Common\Collections\ArrayCollection, + Doctrine\Common\Collections\Collection, + Doctrine\Common\NotifyPropertyChanged, + Doctrine\Common\PropertyChangedListener, + Doctrine\Common\Persistence\ObjectManagerAware, + Doctrine\ORM\Event\LifecycleEventArgs, + Doctrine\ORM\Mapping\ClassMetadata, + Doctrine\ORM\Proxy\Proxy; + +/** + * The UnitOfWork is responsible for tracking changes to objects during an + * "object-level" transaction and for writing out changes to the database + * in the correct order. + * + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @internal This class contains highly performance-sensitive code. + */ +class UnitOfWork implements PropertyChangedListener +{ + /** + * An entity is in MANAGED state when its persistence is managed by an EntityManager. + */ + const STATE_MANAGED = 1; + + /** + * An entity is new if it has just been instantiated (i.e. using the "new" operator) + * and is not (yet) managed by an EntityManager. + */ + const STATE_NEW = 2; + + /** + * A detached entity is an instance with persistent state and identity that is not + * (or no longer) associated with an EntityManager (and a UnitOfWork). + */ + const STATE_DETACHED = 3; + + /** + * A removed entity instance is an instance with a persistent identity, + * associated with an EntityManager, whose persistent state will be deleted + * on commit. + */ + const STATE_REMOVED = 4; + + /** + * The identity map that holds references to all managed entities that have + * an identity. The entities are grouped by their class name. + * Since all classes in a hierarchy must share the same identifier set, + * we always take the root class name of the hierarchy. + * + * @var array + */ + private $identityMap = array(); + + /** + * Map of all identifiers of managed entities. + * Keys are object ids (spl_object_hash). + * + * @var array + */ + private $entityIdentifiers = array(); + + /** + * Map of the original entity data of managed entities. + * Keys are object ids (spl_object_hash). This is used for calculating changesets + * at commit time. + * + * @var array + * @internal Note that PHPs "copy-on-write" behavior helps a lot with memory usage. + * A value will only really be copied if the value in the entity is modified + * by the user. + */ + private $originalEntityData = array(); + + /** + * Map of entity changes. Keys are object ids (spl_object_hash). + * Filled at the beginning of a commit of the UnitOfWork and cleaned at the end. + * + * @var array + */ + private $entityChangeSets = array(); + + /** + * The (cached) states of any known entities. + * Keys are object ids (spl_object_hash). + * + * @var array + */ + private $entityStates = array(); + + /** + * Map of entities that are scheduled for dirty checking at commit time. + * This is only used for entities with a change tracking policy of DEFERRED_EXPLICIT. + * Keys are object ids (spl_object_hash). + * + * @var array + * @todo rename: scheduledForSynchronization + */ + private $scheduledForDirtyCheck = array(); + + /** + * A list of all pending entity insertions. + * + * @var array + */ + private $entityInsertions = array(); + + /** + * A list of all pending entity updates. + * + * @var array + */ + private $entityUpdates = array(); + + /** + * Any pending extra updates that have been scheduled by persisters. + * + * @var array + */ + private $extraUpdates = array(); + + /** + * A list of all pending entity deletions. + * + * @var array + */ + private $entityDeletions = array(); + + /** + * All pending collection deletions. + * + * @var array + */ + private $collectionDeletions = array(); + + /** + * All pending collection updates. + * + * @var array + */ + private $collectionUpdates = array(); + + /** + * List of collections visited during changeset calculation on a commit-phase of a UnitOfWork. + * At the end of the UnitOfWork all these collections will make new snapshots + * of their data. + * + * @var array + */ + private $visitedCollections = array(); + + /** + * The EntityManager that "owns" this UnitOfWork instance. + * + * @var \Doctrine\ORM\EntityManager + */ + private $em; + + /** + * The calculator used to calculate the order in which changes to + * entities need to be written to the database. + * + * @var \Doctrine\ORM\Internal\CommitOrderCalculator + */ + private $commitOrderCalculator; + + /** + * The entity persister instances used to persist entity instances. + * + * @var array + */ + private $persisters = array(); + + /** + * The collection persister instances used to persist collections. + * + * @var array + */ + private $collectionPersisters = array(); + + /** + * The EventManager used for dispatching events. + * + * @var EventManager + */ + private $evm; + + /** + * Orphaned entities that are scheduled for removal. + * + * @var array + */ + private $orphanRemovals = array(); + + /** + * Read-Only objects are never evaluated + * + * @var array + */ + private $readOnlyObjects = array(); + + /** + * Map of Entity Class-Names and corresponding IDs that should eager loaded when requested. + * + * @var array + */ + private $eagerLoadingEntities = array(); + + /** + * Initializes a new UnitOfWork instance, bound to the given EntityManager. + * + * @param \Doctrine\ORM\EntityManager $em + */ + public function __construct(EntityManager $em) + { + $this->em = $em; + $this->evm = $em->getEventManager(); + } + + /** + * Commits the UnitOfWork, executing all operations that have been postponed + * up to this point. The state of all managed entities will be synchronized with + * the database. + * + * The operations are executed in the following order: + * + * 1) All entity insertions + * 2) All entity updates + * 3) All collection deletions + * 4) All collection updates + * 5) All entity deletions + * + * @param object $entity + * @return void + */ + public function commit($entity = null) + { + // Raise preFlush + if ($this->evm->hasListeners(Events::preFlush)) { + $this->evm->dispatchEvent(Events::preFlush, new Event\PreFlushEventArgs($this->em)); + } + + // Compute changes done since last commit. + if ($entity === null) { + $this->computeChangeSets(); + } else { + $this->computeSingleEntityChangeSet($entity); + } + + if ( ! ($this->entityInsertions || + $this->entityDeletions || + $this->entityUpdates || + $this->collectionUpdates || + $this->collectionDeletions || + $this->orphanRemovals)) { + return; // Nothing to do. + } + + if ($this->orphanRemovals) { + foreach ($this->orphanRemovals as $orphan) { + $this->remove($orphan); + } + } + + // Raise onFlush + if ($this->evm->hasListeners(Events::onFlush)) { + $this->evm->dispatchEvent(Events::onFlush, new Event\OnFlushEventArgs($this->em)); + } + + // Now we need a commit order to maintain referential integrity + $commitOrder = $this->getCommitOrder(); + + $conn = $this->em->getConnection(); + $conn->beginTransaction(); + + try { + if ($this->entityInsertions) { + foreach ($commitOrder as $class) { + $this->executeInserts($class); + } + } + + if ($this->entityUpdates) { + foreach ($commitOrder as $class) { + $this->executeUpdates($class); + } + } + + // Extra updates that were requested by persisters. + if ($this->extraUpdates) { + $this->executeExtraUpdates(); + } + + // Collection deletions (deletions of complete collections) + foreach ($this->collectionDeletions as $collectionToDelete) { + $this->getCollectionPersister($collectionToDelete->getMapping())->delete($collectionToDelete); + } + // Collection updates (deleteRows, updateRows, insertRows) + foreach ($this->collectionUpdates as $collectionToUpdate) { + $this->getCollectionPersister($collectionToUpdate->getMapping())->update($collectionToUpdate); + } + + // Entity deletions come last and need to be in reverse commit order + if ($this->entityDeletions) { + for ($count = count($commitOrder), $i = $count - 1; $i >= 0; --$i) { + $this->executeDeletions($commitOrder[$i]); + } + } + + $conn->commit(); + } catch (Exception $e) { + $this->em->close(); + $conn->rollback(); + + throw $e; + } + + // Take new snapshots from visited collections + foreach ($this->visitedCollections as $coll) { + $coll->takeSnapshot(); + } + + // Raise postFlush + if ($this->evm->hasListeners(Events::postFlush)) { + $this->evm->dispatchEvent(Events::postFlush, new Event\PostFlushEventArgs($this->em)); + } + + // Clear up + $this->entityInsertions = + $this->entityUpdates = + $this->entityDeletions = + $this->extraUpdates = + $this->entityChangeSets = + $this->collectionUpdates = + $this->collectionDeletions = + $this->visitedCollections = + $this->scheduledForDirtyCheck = + $this->orphanRemovals = array(); + } + + /** + * Compute the changesets of all entities scheduled for insertion + * + * @return void + */ + private function computeScheduleInsertsChangeSets() + { + foreach ($this->entityInsertions as $entity) { + $class = $this->em->getClassMetadata(get_class($entity)); + + $this->computeChangeSet($class, $entity); + } + } + + /** + * Only flush the given entity according to a ruleset that keeps the UoW consistent. + * + * 1. All entities scheduled for insertion, (orphan) removals and changes in collections are processed as well! + * 2. Read Only entities are skipped. + * 3. Proxies are skipped. + * 4. Only if entity is properly managed. + * + * @param object $entity + * @return void + */ + private function computeSingleEntityChangeSet($entity) + { + if ( $this->getEntityState($entity) !== self::STATE_MANAGED) { + throw new \InvalidArgumentException("Entity has to be managed for single computation " . self::objToStr($entity)); + } + + $class = $this->em->getClassMetadata(get_class($entity)); + + if ($class->isChangeTrackingDeferredImplicit()) { + $this->persist($entity); + } + + // Compute changes for INSERTed entities first. This must always happen even in this case. + $this->computeScheduleInsertsChangeSets(); + + if ($class->isReadOnly) { + return; + } + + // Ignore uninitialized proxy objects + if ($entity instanceof Proxy && ! $entity->__isInitialized__) { + return; + } + + // Only MANAGED entities that are NOT SCHEDULED FOR INSERTION are processed here. + $oid = spl_object_hash($entity); + + if ( ! isset($this->entityInsertions[$oid]) && isset($this->entityStates[$oid])) { + $this->computeChangeSet($class, $entity); + } + } + + /** + * Executes any extra updates that have been scheduled. + */ + private function executeExtraUpdates() + { + foreach ($this->extraUpdates as $oid => $update) { + list ($entity, $changeset) = $update; + + $this->entityChangeSets[$oid] = $changeset; + $this->getEntityPersister(get_class($entity))->update($entity); + } + } + + /** + * Gets the changeset for an entity. + * + * @return array + */ + public function getEntityChangeSet($entity) + { + $oid = spl_object_hash($entity); + + if (isset($this->entityChangeSets[$oid])) { + return $this->entityChangeSets[$oid]; + } + + return array(); + } + + /** + * Computes the changes that happened to a single entity. + * + * Modifies/populates the following properties: + * + * {@link _originalEntityData} + * If the entity is NEW or MANAGED but not yet fully persisted (only has an id) + * then it was not fetched from the database and therefore we have no original + * entity data yet. All of the current entity data is stored as the original entity data. + * + * {@link _entityChangeSets} + * The changes detected on all properties of the entity are stored there. + * A change is a tuple array where the first entry is the old value and the second + * entry is the new value of the property. Changesets are used by persisters + * to INSERT/UPDATE the persistent entity state. + * + * {@link _entityUpdates} + * If the entity is already fully MANAGED (has been fetched from the database before) + * and any changes to its properties are detected, then a reference to the entity is stored + * there to mark it for an update. + * + * {@link _collectionDeletions} + * If a PersistentCollection has been de-referenced in a fully MANAGED entity, + * then this collection is marked for deletion. + * + * @ignore + * @internal Don't call from the outside. + * @param ClassMetadata $class The class descriptor of the entity. + * @param object $entity The entity for which to compute the changes. + */ + public function computeChangeSet(ClassMetadata $class, $entity) + { + $oid = spl_object_hash($entity); + + if (isset($this->readOnlyObjects[$oid])) { + return; + } + + if ( ! $class->isInheritanceTypeNone()) { + $class = $this->em->getClassMetadata(get_class($entity)); + } + + // Fire PreFlush lifecycle callbacks + if (isset($class->lifecycleCallbacks[Events::preFlush])) { + $class->invokeLifecycleCallbacks(Events::preFlush, $entity); + } + + $actualData = array(); + + foreach ($class->reflFields as $name => $refProp) { + $value = $refProp->getValue($entity); + + if ($class->isCollectionValuedAssociation($name) && $value !== null && ! ($value instanceof PersistentCollection)) { + // If $value is not a Collection then use an ArrayCollection. + if ( ! $value instanceof Collection) { + $value = new ArrayCollection($value); + } + + $assoc = $class->associationMappings[$name]; + + // Inject PersistentCollection + $value = new PersistentCollection( + $this->em, $this->em->getClassMetadata($assoc['targetEntity']), $value + ); + $value->setOwner($entity, $assoc); + $value->setDirty( ! $value->isEmpty()); + + $class->reflFields[$name]->setValue($entity, $value); + + $actualData[$name] = $value; + + continue; + } + + if (( ! $class->isIdentifier($name) || ! $class->isIdGeneratorIdentity()) && ($name !== $class->versionField)) { + $actualData[$name] = $value; + } + } + + if ( ! isset($this->originalEntityData[$oid])) { + // Entity is either NEW or MANAGED but not yet fully persisted (only has an id). + // These result in an INSERT. + $this->originalEntityData[$oid] = $actualData; + $changeSet = array(); + + foreach ($actualData as $propName => $actualValue) { + if ( ! isset($class->associationMappings[$propName])) { + $changeSet[$propName] = array(null, $actualValue); + + continue; + } + + $assoc = $class->associationMappings[$propName]; + + if ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE) { + $changeSet[$propName] = array(null, $actualValue); + } + } + + $this->entityChangeSets[$oid] = $changeSet; + } else { + // Entity is "fully" MANAGED: it was already fully persisted before + // and we have a copy of the original data + $originalData = $this->originalEntityData[$oid]; + $isChangeTrackingNotify = $class->isChangeTrackingNotify(); + $changeSet = ($isChangeTrackingNotify && isset($this->entityChangeSets[$oid])) + ? $this->entityChangeSets[$oid] + : array(); + + foreach ($actualData as $propName => $actualValue) { + // skip field, its a partially omitted one! + if ( ! (isset($originalData[$propName]) || array_key_exists($propName, $originalData))) { + continue; + } + + $orgValue = $originalData[$propName]; + + // skip if value havent changed + if ($orgValue === $actualValue) { + continue; + } + + // if regular field + if ( ! isset($class->associationMappings[$propName])) { + if ($isChangeTrackingNotify) { + continue; + } + + $changeSet[$propName] = array($orgValue, $actualValue); + + continue; + } + + $assoc = $class->associationMappings[$propName]; + + // Persistent collection was exchanged with the "originally" + // created one. This can only mean it was cloned and replaced + // on another entity. + if ($actualValue instanceof PersistentCollection) { + $owner = $actualValue->getOwner(); + if ($owner === null) { // cloned + $actualValue->setOwner($entity, $assoc); + } else if ($owner !== $entity) { // no clone, we have to fix + if (!$actualValue->isInitialized()) { + $actualValue->initialize(); // we have to do this otherwise the cols share state + } + $newValue = clone $actualValue; + $newValue->setOwner($entity, $assoc); + $class->reflFields[$propName]->setValue($entity, $newValue); + } + } + + if ($orgValue instanceof PersistentCollection) { + // A PersistentCollection was de-referenced, so delete it. + $coid = spl_object_hash($orgValue); + + if (isset($this->collectionDeletions[$coid])) { + continue; + } + + $this->collectionDeletions[$coid] = $orgValue; + $changeSet[$propName] = $orgValue; // Signal changeset, to-many assocs will be ignored. + + continue; + } + + if ($assoc['type'] & ClassMetadata::TO_ONE) { + if ($assoc['isOwningSide']) { + $changeSet[$propName] = array($orgValue, $actualValue); + } + + if ($orgValue !== null && $assoc['orphanRemoval']) { + $this->scheduleOrphanRemoval($orgValue); + } + } + } + + if ($changeSet) { + $this->entityChangeSets[$oid] = $changeSet; + $this->originalEntityData[$oid] = $actualData; + $this->entityUpdates[$oid] = $entity; + } + } + + // Look for changes in associations of the entity + foreach ($class->associationMappings as $field => $assoc) { + if (($val = $class->reflFields[$field]->getValue($entity)) !== null) { + $this->computeAssociationChanges($assoc, $val); + if (!isset($this->entityChangeSets[$oid]) && + $assoc['isOwningSide'] && + $assoc['type'] == ClassMetadata::MANY_TO_MANY && + $val instanceof PersistentCollection && + $val->isDirty()) { + $this->entityChangeSets[$oid] = array(); + $this->originalEntityData[$oid] = $actualData; + $this->entityUpdates[$oid] = $entity; + } + } + } + } + + /** + * Computes all the changes that have been done to entities and collections + * since the last commit and stores these changes in the _entityChangeSet map + * temporarily for access by the persisters, until the UoW commit is finished. + */ + public function computeChangeSets() + { + // Compute changes for INSERTed entities first. This must always happen. + $this->computeScheduleInsertsChangeSets(); + + // Compute changes for other MANAGED entities. Change tracking policies take effect here. + foreach ($this->identityMap as $className => $entities) { + $class = $this->em->getClassMetadata($className); + + // Skip class if instances are read-only + if ($class->isReadOnly) { + continue; + } + + // If change tracking is explicit or happens through notification, then only compute + // changes on entities of that type that are explicitly marked for synchronization. + switch (true) { + case ($class->isChangeTrackingDeferredImplicit()): + $entitiesToProcess = $entities; + break; + + case (isset($this->scheduledForDirtyCheck[$className])): + $entitiesToProcess = $this->scheduledForDirtyCheck[$className]; + break; + + default: + $entitiesToProcess = array(); + + } + + foreach ($entitiesToProcess as $entity) { + // Ignore uninitialized proxy objects + if ($entity instanceof Proxy && ! $entity->__isInitialized__) { + continue; + } + + // Only MANAGED entities that are NOT SCHEDULED FOR INSERTION are processed here. + $oid = spl_object_hash($entity); + + if ( ! isset($this->entityInsertions[$oid]) && isset($this->entityStates[$oid])) { + $this->computeChangeSet($class, $entity); + } + } + } + } + + /** + * Computes the changes of an association. + * + * @param AssociationMapping $assoc + * @param mixed $value The value of the association. + */ + private function computeAssociationChanges($assoc, $value) + { + if ($value instanceof Proxy && ! $value->__isInitialized__) { + return; + } + + if ($value instanceof PersistentCollection && $value->isDirty()) { + $coid = spl_object_hash($value); + + if ($assoc['isOwningSide']) { + $this->collectionUpdates[$coid] = $value; + } + + $this->visitedCollections[$coid] = $value; + } + + // Look through the entities, and in any of their associations, + // for transient (new) entities, recursively. ("Persistence by reachability") + // Unwrap. Uninitialized collections will simply be empty. + $unwrappedValue = ($assoc['type'] & ClassMetadata::TO_ONE) ? array($value) : $value->unwrap(); + $targetClass = $this->em->getClassMetadata($assoc['targetEntity']); + + foreach ($unwrappedValue as $key => $entry) { + $state = $this->getEntityState($entry, self::STATE_NEW); + $oid = spl_object_hash($entry); + + if (!($entry instanceof $assoc['targetEntity'])) { + throw new ORMException(sprintf("Found entity of type %s on association %s#%s, but expecting %s", + get_class($entry), + $assoc['sourceEntity'], + $assoc['fieldName'], + $targetClass->name + )); + } + + switch ($state) { + case self::STATE_NEW: + if ( ! $assoc['isCascadePersist']) { + throw ORMInvalidArgumentException::newEntityFoundThroughRelationship($assoc, $entry); + } + + $this->persistNew($targetClass, $entry); + $this->computeChangeSet($targetClass, $entry); + break; + + case self::STATE_REMOVED: + // Consume the $value as array (it's either an array or an ArrayAccess) + // and remove the element from Collection. + if ($assoc['type'] & ClassMetadata::TO_MANY) { + unset($value[$key]); + } + break; + + case self::STATE_DETACHED: + // Can actually not happen right now as we assume STATE_NEW, + // so the exception will be raised from the DBAL layer (constraint violation). + throw ORMInvalidArgumentException::detachedEntityFoundThroughRelationship($assoc, $entry); + break; + + default: + // MANAGED associated entities are already taken into account + // during changeset calculation anyway, since they are in the identity map. + } + } + } + + private function persistNew($class, $entity) + { + $oid = spl_object_hash($entity); + + if (isset($class->lifecycleCallbacks[Events::prePersist])) { + $class->invokeLifecycleCallbacks(Events::prePersist, $entity); + } + + if ($this->evm->hasListeners(Events::prePersist)) { + $this->evm->dispatchEvent(Events::prePersist, new LifecycleEventArgs($entity, $this->em)); + } + + $idGen = $class->idGenerator; + + if ( ! $idGen->isPostInsertGenerator()) { + $idValue = $idGen->generate($this->em, $entity); + + if ( ! $idGen instanceof \Doctrine\ORM\Id\AssignedGenerator) { + $idValue = array($class->identifier[0] => $idValue); + + $class->setIdentifierValues($entity, $idValue); + } + + $this->entityIdentifiers[$oid] = $idValue; + } + + $this->entityStates[$oid] = self::STATE_MANAGED; + + $this->scheduleForInsert($entity); + } + + /** + * INTERNAL: + * Computes the changeset of an individual entity, independently of the + * computeChangeSets() routine that is used at the beginning of a UnitOfWork#commit(). + * + * The passed entity must be a managed entity. If the entity already has a change set + * because this method is invoked during a commit cycle then the change sets are added. + * whereby changes detected in this method prevail. + * + * @ignore + * @param ClassMetadata $class The class descriptor of the entity. + * @param object $entity The entity for which to (re)calculate the change set. + * @throws InvalidArgumentException If the passed entity is not MANAGED. + */ + public function recomputeSingleEntityChangeSet(ClassMetadata $class, $entity) + { + $oid = spl_object_hash($entity); + + if ( ! isset($this->entityStates[$oid]) || $this->entityStates[$oid] != self::STATE_MANAGED) { + throw ORMInvalidArgumentException::entityNotManaged($entity); + } + + // skip if change tracking is "NOTIFY" + if ($class->isChangeTrackingNotify()) { + return; + } + + if ( ! $class->isInheritanceTypeNone()) { + $class = $this->em->getClassMetadata(get_class($entity)); + } + + $actualData = array(); + + foreach ($class->reflFields as $name => $refProp) { + if ( ! $class->isIdentifier($name) || ! $class->isIdGeneratorIdentity()) { + $actualData[$name] = $refProp->getValue($entity); + } + } + + $originalData = $this->originalEntityData[$oid]; + $changeSet = array(); + + foreach ($actualData as $propName => $actualValue) { + $orgValue = isset($originalData[$propName]) ? $originalData[$propName] : null; + + if (is_object($orgValue) && $orgValue !== $actualValue) { + $changeSet[$propName] = array($orgValue, $actualValue); + } else if ($orgValue != $actualValue || ($orgValue === null ^ $actualValue === null)) { + $changeSet[$propName] = array($orgValue, $actualValue); + } + } + + if ($changeSet) { + if (isset($this->entityChangeSets[$oid])) { + $this->entityChangeSets[$oid] = array_merge($this->entityChangeSets[$oid], $changeSet); + } + + $this->originalEntityData[$oid] = $actualData; + } + } + + /** + * Executes all entity insertions for entities of the specified type. + * + * @param \Doctrine\ORM\Mapping\ClassMetadata $class + */ + private function executeInserts($class) + { + $className = $class->name; + $persister = $this->getEntityPersister($className); + $entities = array(); + + $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postPersist]); + $hasListeners = $this->evm->hasListeners(Events::postPersist); + + foreach ($this->entityInsertions as $oid => $entity) { + if (get_class($entity) !== $className) { + continue; + } + + $persister->addInsert($entity); + + unset($this->entityInsertions[$oid]); + + if ($hasLifecycleCallbacks || $hasListeners) { + $entities[] = $entity; + } + } + + $postInsertIds = $persister->executeInserts(); + + if ($postInsertIds) { + // Persister returned post-insert IDs + foreach ($postInsertIds as $id => $entity) { + $oid = spl_object_hash($entity); + $idField = $class->identifier[0]; + + $class->reflFields[$idField]->setValue($entity, $id); + + $this->entityIdentifiers[$oid] = array($idField => $id); + $this->entityStates[$oid] = self::STATE_MANAGED; + $this->originalEntityData[$oid][$idField] = $id; + + $this->addToIdentityMap($entity); + } + } + + foreach ($entities as $entity) { + if ($hasLifecycleCallbacks) { + $class->invokeLifecycleCallbacks(Events::postPersist, $entity); + } + + if ($hasListeners) { + $this->evm->dispatchEvent(Events::postPersist, new LifecycleEventArgs($entity, $this->em)); + } + } + } + + /** + * Executes all entity updates for entities of the specified type. + * + * @param \Doctrine\ORM\Mapping\ClassMetadata $class + */ + private function executeUpdates($class) + { + $className = $class->name; + $persister = $this->getEntityPersister($className); + + $hasPreUpdateLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::preUpdate]); + $hasPreUpdateListeners = $this->evm->hasListeners(Events::preUpdate); + + $hasPostUpdateLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postUpdate]); + $hasPostUpdateListeners = $this->evm->hasListeners(Events::postUpdate); + + foreach ($this->entityUpdates as $oid => $entity) { + if ( ! (get_class($entity) === $className || $entity instanceof Proxy && get_parent_class($entity) === $className)) { + continue; + } + + if ($hasPreUpdateLifecycleCallbacks) { + $class->invokeLifecycleCallbacks(Events::preUpdate, $entity); + + $this->recomputeSingleEntityChangeSet($class, $entity); + } + + if ($hasPreUpdateListeners) { + $this->evm->dispatchEvent( + Events::preUpdate, + new Event\PreUpdateEventArgs($entity, $this->em, $this->entityChangeSets[$oid]) + ); + } + + if ($this->entityChangeSets[$oid]) { + $persister->update($entity); + } + + unset($this->entityUpdates[$oid]); + + if ($hasPostUpdateLifecycleCallbacks) { + $class->invokeLifecycleCallbacks(Events::postUpdate, $entity); + } + + if ($hasPostUpdateListeners) { + $this->evm->dispatchEvent(Events::postUpdate, new LifecycleEventArgs($entity, $this->em)); + } + } + } + + /** + * Executes all entity deletions for entities of the specified type. + * + * @param \Doctrine\ORM\Mapping\ClassMetadata $class + */ + private function executeDeletions($class) + { + $className = $class->name; + $persister = $this->getEntityPersister($className); + + $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postRemove]); + $hasListeners = $this->evm->hasListeners(Events::postRemove); + + foreach ($this->entityDeletions as $oid => $entity) { + if ( ! (get_class($entity) == $className || $entity instanceof Proxy && get_parent_class($entity) == $className)) { + continue; + } + + $persister->delete($entity); + + unset( + $this->entityDeletions[$oid], + $this->entityIdentifiers[$oid], + $this->originalEntityData[$oid], + $this->entityStates[$oid] + ); + + // Entity with this $oid after deletion treated as NEW, even if the $oid + // is obtained by a new entity because the old one went out of scope. + //$this->entityStates[$oid] = self::STATE_NEW; + if ( ! $class->isIdentifierNatural()) { + $class->reflFields[$class->identifier[0]]->setValue($entity, null); + } + + if ($hasLifecycleCallbacks) { + $class->invokeLifecycleCallbacks(Events::postRemove, $entity); + } + + if ($hasListeners) { + $this->evm->dispatchEvent(Events::postRemove, new LifecycleEventArgs($entity, $this->em)); + } + } + } + + /** + * Gets the commit order. + * + * @return array + */ + private function getCommitOrder(array $entityChangeSet = null) + { + if ($entityChangeSet === null) { + $entityChangeSet = array_merge($this->entityInsertions, $this->entityUpdates, $this->entityDeletions); + } + + $calc = $this->getCommitOrderCalculator(); + + // See if there are any new classes in the changeset, that are not in the + // commit order graph yet (dont have a node). + // We have to inspect changeSet to be able to correctly build dependencies. + // It is not possible to use IdentityMap here because post inserted ids + // are not yet available. + $newNodes = array(); + + foreach ($entityChangeSet as $oid => $entity) { + $className = get_class($entity); + + if ($calc->hasClass($className)) { + continue; + } + + $class = $this->em->getClassMetadata($className); + $calc->addClass($class); + + $newNodes[] = $class; + } + + // Calculate dependencies for new nodes + while ($class = array_pop($newNodes)) { + foreach ($class->associationMappings as $assoc) { + if ( ! ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE)) { + continue; + } + + $targetClass = $this->em->getClassMetadata($assoc['targetEntity']); + + if ( ! $calc->hasClass($targetClass->name)) { + $calc->addClass($targetClass); + + $newNodes[] = $targetClass; + } + + $calc->addDependency($targetClass, $class); + + // If the target class has mapped subclasses, these share the same dependency. + if ( ! $targetClass->subClasses) { + continue; + } + + foreach ($targetClass->subClasses as $subClassName) { + $targetSubClass = $this->em->getClassMetadata($subClassName); + + if ( ! $calc->hasClass($subClassName)) { + $calc->addClass($targetSubClass); + + $newNodes[] = $targetSubClass; + } + + $calc->addDependency($targetSubClass, $class); + } + } + } + + return $calc->getCommitOrder(); + } + + /** + * Schedules an entity for insertion into the database. + * If the entity already has an identifier, it will be added to the identity map. + * + * @param object $entity The entity to schedule for insertion. + */ + public function scheduleForInsert($entity) + { + $oid = spl_object_hash($entity); + + if (isset($this->entityUpdates[$oid])) { + throw new InvalidArgumentException("Dirty entity can not be scheduled for insertion."); + } + + if (isset($this->entityDeletions[$oid])) { + throw ORMInvalidArgumentException::scheduleInsertForRemovedEntity($entity); + } + if (isset($this->originalEntityData[$oid]) && ! isset($this->entityInsertions[$oid])) { + throw ORMInvalidArgumentException::scheduleInsertForManagedEntity($entity); + } + + if (isset($this->entityInsertions[$oid])) { + throw ORMInvalidArgumentException::scheduleInsertTwice($entity); + } + + $this->entityInsertions[$oid] = $entity; + + if (isset($this->entityIdentifiers[$oid])) { + $this->addToIdentityMap($entity); + } + } + + /** + * Checks whether an entity is scheduled for insertion. + * + * @param object $entity + * @return boolean + */ + public function isScheduledForInsert($entity) + { + return isset($this->entityInsertions[spl_object_hash($entity)]); + } + + /** + * Schedules an entity for being updated. + * + * @param object $entity The entity to schedule for being updated. + */ + public function scheduleForUpdate($entity) + { + $oid = spl_object_hash($entity); + + if ( ! isset($this->entityIdentifiers[$oid])) { + throw ORMInvalidArgumentException::entityHasNoIdentity($entity, "scheduling for update"); + } + + if (isset($this->entityDeletions[$oid])) { + throw ORMInvalidArgumentException::entityIsRemoved($entity, "schedule for update"); + } + + if ( ! isset($this->entityUpdates[$oid]) && ! isset($this->entityInsertions[$oid])) { + $this->entityUpdates[$oid] = $entity; + } + } + + /** + * INTERNAL: + * Schedules an extra update that will be executed immediately after the + * regular entity updates within the currently running commit cycle. + * + * Extra updates for entities are stored as (entity, changeset) tuples. + * + * @ignore + * @param object $entity The entity for which to schedule an extra update. + * @param array $changeset The changeset of the entity (what to update). + */ + public function scheduleExtraUpdate($entity, array $changeset) + { + $oid = spl_object_hash($entity); + $extraUpdate = array($entity, $changeset); + + if (isset($this->extraUpdates[$oid])) { + list($ignored, $changeset2) = $this->extraUpdates[$oid]; + + $extraUpdate = array($entity, $changeset + $changeset2); + } + + $this->extraUpdates[$oid] = $extraUpdate; + } + + /** + * Checks whether an entity is registered as dirty in the unit of work. + * Note: Is not very useful currently as dirty entities are only registered + * at commit time. + * + * @param object $entity + * @return boolean + */ + public function isScheduledForUpdate($entity) + { + return isset($this->entityUpdates[spl_object_hash($entity)]); + } + + + /** + * Checks whether an entity is registered to be checked in the unit of work. + * + * @param object $entity + * @return boolean + */ + public function isScheduledForDirtyCheck($entity) + { + $rootEntityName = $this->em->getClassMetadata(get_class($entity))->rootEntityName; + + return isset($this->scheduledForDirtyCheck[$rootEntityName][spl_object_hash($entity)]); + } + + /** + * INTERNAL: + * Schedules an entity for deletion. + * + * @param object $entity + */ + public function scheduleForDelete($entity) + { + $oid = spl_object_hash($entity); + + if (isset($this->entityInsertions[$oid])) { + if ($this->isInIdentityMap($entity)) { + $this->removeFromIdentityMap($entity); + } + + unset($this->entityInsertions[$oid], $this->entityStates[$oid]); + + return; // entity has not been persisted yet, so nothing more to do. + } + + if ( ! $this->isInIdentityMap($entity)) { + return; + } + + $this->removeFromIdentityMap($entity); + + if (isset($this->entityUpdates[$oid])) { + unset($this->entityUpdates[$oid]); + } + + if ( ! isset($this->entityDeletions[$oid])) { + $this->entityDeletions[$oid] = $entity; + $this->entityStates[$oid] = self::STATE_REMOVED; + } + } + + /** + * Checks whether an entity is registered as removed/deleted with the unit + * of work. + * + * @param object $entity + * @return boolean + */ + public function isScheduledForDelete($entity) + { + return isset($this->entityDeletions[spl_object_hash($entity)]); + } + + /** + * Checks whether an entity is scheduled for insertion, update or deletion. + * + * @param $entity + * @return boolean + */ + public function isEntityScheduled($entity) + { + $oid = spl_object_hash($entity); + + return isset($this->entityInsertions[$oid]) + || isset($this->entityUpdates[$oid]) + || isset($this->entityDeletions[$oid]); + } + + /** + * INTERNAL: + * Registers an entity in the identity map. + * Note that entities in a hierarchy are registered with the class name of + * the root entity. + * + * @ignore + * @param object $entity The entity to register. + * @return boolean TRUE if the registration was successful, FALSE if the identity of + * the entity in question is already managed. + */ + public function addToIdentityMap($entity) + { + $classMetadata = $this->em->getClassMetadata(get_class($entity)); + $idHash = implode(' ', $this->entityIdentifiers[spl_object_hash($entity)]); + + if ($idHash === '') { + throw ORMInvalidArgumentException::entityWithoutIdentity($classMetadata->name, $entity); + } + + $className = $classMetadata->rootEntityName; + + if (isset($this->identityMap[$className][$idHash])) { + return false; + } + + $this->identityMap[$className][$idHash] = $entity; + + if ($entity instanceof NotifyPropertyChanged) { + $entity->addPropertyChangedListener($this); + } + + return true; + } + + /** + * Gets the state of an entity with regard to the current unit of work. + * + * @param object $entity + * @param integer $assume The state to assume if the state is not yet known (not MANAGED or REMOVED). + * This parameter can be set to improve performance of entity state detection + * by potentially avoiding a database lookup if the distinction between NEW and DETACHED + * is either known or does not matter for the caller of the method. + * @return int The entity state. + */ + public function getEntityState($entity, $assume = null) + { + $oid = spl_object_hash($entity); + + if (isset($this->entityStates[$oid])) { + return $this->entityStates[$oid]; + } + + if ($assume !== null) { + return $assume; + } + + // State can only be NEW or DETACHED, because MANAGED/REMOVED states are known. + // Note that you can not remember the NEW or DETACHED state in _entityStates since + // the UoW does not hold references to such objects and the object hash can be reused. + // More generally because the state may "change" between NEW/DETACHED without the UoW being aware of it. + $class = $this->em->getClassMetadata(get_class($entity)); + $id = $class->getIdentifierValues($entity); + + if ( ! $id) { + return self::STATE_NEW; + } + + switch (true) { + case ($class->isIdentifierNatural()); + // Check for a version field, if available, to avoid a db lookup. + if ($class->isVersioned) { + return ($class->getFieldValue($entity, $class->versionField)) + ? self::STATE_DETACHED + : self::STATE_NEW; + } + + // Last try before db lookup: check the identity map. + if ($this->tryGetById($id, $class->rootEntityName)) { + return self::STATE_DETACHED; + } + + // db lookup + if ($this->getEntityPersister(get_class($entity))->exists($entity)) { + return self::STATE_DETACHED; + } + + return self::STATE_NEW; + + case ( ! $class->idGenerator->isPostInsertGenerator()): + // if we have a pre insert generator we can't be sure that having an id + // really means that the entity exists. We have to verify this through + // the last resort: a db lookup + + // Last try before db lookup: check the identity map. + if ($this->tryGetById($id, $class->rootEntityName)) { + return self::STATE_DETACHED; + } + + // db lookup + if ($this->getEntityPersister(get_class($entity))->exists($entity)) { + return self::STATE_DETACHED; + } + + return self::STATE_NEW; + + default: + return self::STATE_DETACHED; + } + } + + /** + * INTERNAL: + * Removes an entity from the identity map. This effectively detaches the + * entity from the persistence management of Doctrine. + * + * @ignore + * @param object $entity + * @return boolean + */ + public function removeFromIdentityMap($entity) + { + $oid = spl_object_hash($entity); + $classMetadata = $this->em->getClassMetadata(get_class($entity)); + $idHash = implode(' ', $this->entityIdentifiers[$oid]); + + if ($idHash === '') { + throw ORMInvalidArgumentException::entityHasNoIdentity($entity, "remove from identity map"); + } + + $className = $classMetadata->rootEntityName; + + if (isset($this->identityMap[$className][$idHash])) { + unset($this->identityMap[$className][$idHash]); + unset($this->readOnlyObjects[$oid]); + + //$this->entityStates[$oid] = self::STATE_DETACHED; + + return true; + } + + return false; + } + + /** + * INTERNAL: + * Gets an entity in the identity map by its identifier hash. + * + * @ignore + * @param string $idHash + * @param string $rootClassName + * @return object + */ + public function getByIdHash($idHash, $rootClassName) + { + return $this->identityMap[$rootClassName][$idHash]; + } + + /** + * INTERNAL: + * Tries to get an entity by its identifier hash. If no entity is found for + * the given hash, FALSE is returned. + * + * @ignore + * @param string $idHash + * @param string $rootClassName + * @return mixed The found entity or FALSE. + */ + public function tryGetByIdHash($idHash, $rootClassName) + { + if (isset($this->identityMap[$rootClassName][$idHash])) { + return $this->identityMap[$rootClassName][$idHash]; + } + + return false; + } + + /** + * Checks whether an entity is registered in the identity map of this UnitOfWork. + * + * @param object $entity + * @return boolean + */ + public function isInIdentityMap($entity) + { + $oid = spl_object_hash($entity); + + if ( ! isset($this->entityIdentifiers[$oid])) { + return false; + } + + $classMetadata = $this->em->getClassMetadata(get_class($entity)); + $idHash = implode(' ', $this->entityIdentifiers[$oid]); + + if ($idHash === '') { + return false; + } + + return isset($this->identityMap[$classMetadata->rootEntityName][$idHash]); + } + + /** + * INTERNAL: + * Checks whether an identifier hash exists in the identity map. + * + * @ignore + * @param string $idHash + * @param string $rootClassName + * @return boolean + */ + public function containsIdHash($idHash, $rootClassName) + { + return isset($this->identityMap[$rootClassName][$idHash]); + } + + /** + * Persists an entity as part of the current unit of work. + * + * @param object $entity The entity to persist. + */ + public function persist($entity) + { + $visited = array(); + + $this->doPersist($entity, $visited); + } + + /** + * Persists an entity as part of the current unit of work. + * + * This method is internally called during persist() cascades as it tracks + * the already visited entities to prevent infinite recursions. + * + * @param object $entity The entity to persist. + * @param array $visited The already visited entities. + */ + private function doPersist($entity, array &$visited) + { + $oid = spl_object_hash($entity); + + if (isset($visited[$oid])) { + return; // Prevent infinite recursion + } + + $visited[$oid] = $entity; // Mark visited + + $class = $this->em->getClassMetadata(get_class($entity)); + + // We assume NEW, so DETACHED entities result in an exception on flush (constraint violation). + // If we would detect DETACHED here we would throw an exception anyway with the same + // consequences (not recoverable/programming error), so just assuming NEW here + // lets us avoid some database lookups for entities with natural identifiers. + $entityState = $this->getEntityState($entity, self::STATE_NEW); + + switch ($entityState) { + case self::STATE_MANAGED: + // Nothing to do, except if policy is "deferred explicit" + if ($class->isChangeTrackingDeferredExplicit()) { + $this->scheduleForDirtyCheck($entity); + } + break; + + case self::STATE_NEW: + $this->persistNew($class, $entity); + break; + + case self::STATE_REMOVED: + // Entity becomes managed again + unset($this->entityDeletions[$oid]); + + $this->entityStates[$oid] = self::STATE_MANAGED; + break; + + case self::STATE_DETACHED: + // Can actually not happen right now since we assume STATE_NEW. + throw ORMInvalidArgumentException::detachedEntityCannot($entity, "persisted"); + + default: + throw new UnexpectedValueException("Unexpected entity state: $entityState." . self::objToStr($entity)); + } + + $this->cascadePersist($entity, $visited); + } + + /** + * Deletes an entity as part of the current unit of work. + * + * @param object $entity The entity to remove. + */ + public function remove($entity) + { + $visited = array(); + + $this->doRemove($entity, $visited); + } + + /** + * Deletes an entity as part of the current unit of work. + * + * This method is internally called during delete() cascades as it tracks + * the already visited entities to prevent infinite recursions. + * + * @param object $entity The entity to delete. + * @param array $visited The map of the already visited entities. + * @throws InvalidArgumentException If the instance is a detached entity. + */ + private function doRemove($entity, array &$visited) + { + $oid = spl_object_hash($entity); + + if (isset($visited[$oid])) { + return; // Prevent infinite recursion + } + + $visited[$oid] = $entity; // mark visited + + // Cascade first, because scheduleForDelete() removes the entity from the identity map, which + // can cause problems when a lazy proxy has to be initialized for the cascade operation. + $this->cascadeRemove($entity, $visited); + + $class = $this->em->getClassMetadata(get_class($entity)); + $entityState = $this->getEntityState($entity); + + switch ($entityState) { + case self::STATE_NEW: + case self::STATE_REMOVED: + // nothing to do + break; + + case self::STATE_MANAGED: + if (isset($class->lifecycleCallbacks[Events::preRemove])) { + $class->invokeLifecycleCallbacks(Events::preRemove, $entity); + } + + if ($this->evm->hasListeners(Events::preRemove)) { + $this->evm->dispatchEvent(Events::preRemove, new LifecycleEventArgs($entity, $this->em)); + } + + $this->scheduleForDelete($entity); + break; + + case self::STATE_DETACHED: + throw ORMInvalidArgumentException::detachedEntityCannot($entity, "removed"); + default: + throw new UnexpectedValueException("Unexpected entity state: $entityState." . self::objToStr($entity)); + } + + } + + /** + * Merges the state of the given detached entity into this UnitOfWork. + * + * @param object $entity + * @return object The managed copy of the entity. + * @throws OptimisticLockException If the entity uses optimistic locking through a version + * attribute and the version check against the managed copy fails. + * + * @todo Require active transaction!? OptimisticLockException may result in undefined state!? + */ + public function merge($entity) + { + $visited = array(); + + return $this->doMerge($entity, $visited); + } + + /** + * Executes a merge operation on an entity. + * + * @param object $entity + * @param array $visited + * @return object The managed copy of the entity. + * @throws OptimisticLockException If the entity uses optimistic locking through a version + * attribute and the version check against the managed copy fails. + * @throws InvalidArgumentException If the entity instance is NEW. + */ + private function doMerge($entity, array &$visited, $prevManagedCopy = null, $assoc = null) + { + $oid = spl_object_hash($entity); + + if (isset($visited[$oid])) { + return; // Prevent infinite recursion + } + + $visited[$oid] = $entity; // mark visited + + $class = $this->em->getClassMetadata(get_class($entity)); + + // First we assume DETACHED, although it can still be NEW but we can avoid + // an extra db-roundtrip this way. If it is not MANAGED but has an identity, + // we need to fetch it from the db anyway in order to merge. + // MANAGED entities are ignored by the merge operation. + $managedCopy = $entity; + + if ($this->getEntityState($entity, self::STATE_DETACHED) !== self::STATE_MANAGED) { + if ($entity instanceof Proxy && ! $entity->__isInitialized__) { + $entity->__load(); + } + + // Try to look the entity up in the identity map. + $id = $class->getIdentifierValues($entity); + + // If there is no ID, it is actually NEW. + if ( ! $id) { + $managedCopy = $this->newInstance($class); + + $this->persistNew($class, $managedCopy); + } else { + $flatId = $id; + if ($class->containsForeignIdentifier) { + // convert foreign identifiers into scalar foreign key + // values to avoid object to string conversion failures. + foreach ($id as $idField => $idValue) { + if (isset($class->associationMappings[$idField])) { + $targetClassMetadata = $this->em->getClassMetadata($class->associationMappings[$idField]['targetEntity']); + $associatedId = $this->getEntityIdentifier($idValue); + $flatId[$idField] = $associatedId[$targetClassMetadata->identifier[0]]; + } + } + } + + $managedCopy = $this->tryGetById($flatId, $class->rootEntityName); + + if ($managedCopy) { + // We have the entity in-memory already, just make sure its not removed. + if ($this->getEntityState($managedCopy) == self::STATE_REMOVED) { + throw ORMInvalidArgumentException::entityIsRemoved($managedCopy, "merge"); + } + } else { + // We need to fetch the managed copy in order to merge. + $managedCopy = $this->em->find($class->name, $flatId); + } + + if ($managedCopy === null) { + // If the identifier is ASSIGNED, it is NEW, otherwise an error + // since the managed entity was not found. + if ( ! $class->isIdentifierNatural()) { + throw new EntityNotFoundException; + } + + $managedCopy = $this->newInstance($class); + $class->setIdentifierValues($managedCopy, $id); + + $this->persistNew($class, $managedCopy); + } else { + if ($managedCopy instanceof Proxy && ! $managedCopy->__isInitialized__) { + $managedCopy->__load(); + } + } + } + + if ($class->isVersioned) { + $managedCopyVersion = $class->reflFields[$class->versionField]->getValue($managedCopy); + $entityVersion = $class->reflFields[$class->versionField]->getValue($entity); + + // Throw exception if versions dont match. + if ($managedCopyVersion != $entityVersion) { + throw OptimisticLockException::lockFailedVersionMissmatch($entity, $entityVersion, $managedCopyVersion); + } + } + + // Merge state of $entity into existing (managed) entity + foreach ($class->reflFields as $name => $prop) { + if ( ! isset($class->associationMappings[$name])) { + if ( ! $class->isIdentifier($name)) { + $prop->setValue($managedCopy, $prop->getValue($entity)); + } + } else { + $assoc2 = $class->associationMappings[$name]; + if ($assoc2['type'] & ClassMetadata::TO_ONE) { + $other = $prop->getValue($entity); + if ($other === null) { + $prop->setValue($managedCopy, null); + } else if ($other instanceof Proxy && !$other->__isInitialized__) { + // do not merge fields marked lazy that have not been fetched. + continue; + } else if ( ! $assoc2['isCascadeMerge']) { + if ($this->getEntityState($other, self::STATE_DETACHED) !== self::STATE_MANAGED) { + $targetClass = $this->em->getClassMetadata($assoc2['targetEntity']); + $relatedId = $targetClass->getIdentifierValues($other); + + if ($targetClass->subClasses) { + $other = $this->em->find($targetClass->name, $relatedId); + } else { + $other = $this->em->getProxyFactory()->getProxy($assoc2['targetEntity'], $relatedId); + $this->registerManaged($other, $relatedId, array()); + } + } + $prop->setValue($managedCopy, $other); + } + } else { + $mergeCol = $prop->getValue($entity); + if ($mergeCol instanceof PersistentCollection && !$mergeCol->isInitialized()) { + // do not merge fields marked lazy that have not been fetched. + // keep the lazy persistent collection of the managed copy. + continue; + } + + $managedCol = $prop->getValue($managedCopy); + if (!$managedCol) { + $managedCol = new PersistentCollection($this->em, + $this->em->getClassMetadata($assoc2['targetEntity']), + new ArrayCollection + ); + $managedCol->setOwner($managedCopy, $assoc2); + $prop->setValue($managedCopy, $managedCol); + $this->originalEntityData[$oid][$name] = $managedCol; + } + if ($assoc2['isCascadeMerge']) { + $managedCol->initialize(); + + // clear and set dirty a managed collection if its not also the same collection to merge from. + if (!$managedCol->isEmpty() && $managedCol !== $mergeCol) { + $managedCol->unwrap()->clear(); + $managedCol->setDirty(true); + + if ($assoc2['isOwningSide'] && $assoc2['type'] == ClassMetadata::MANY_TO_MANY && $class->isChangeTrackingNotify()) { + $this->scheduleForDirtyCheck($managedCopy); + } + } + } + } + } + + if ($class->isChangeTrackingNotify()) { + // Just treat all properties as changed, there is no other choice. + $this->propertyChanged($managedCopy, $name, null, $prop->getValue($managedCopy)); + } + } + + if ($class->isChangeTrackingDeferredExplicit()) { + $this->scheduleForDirtyCheck($entity); + } + } + + if ($prevManagedCopy !== null) { + $assocField = $assoc['fieldName']; + $prevClass = $this->em->getClassMetadata(get_class($prevManagedCopy)); + + if ($assoc['type'] & ClassMetadata::TO_ONE) { + $prevClass->reflFields[$assocField]->setValue($prevManagedCopy, $managedCopy); + } else { + $prevClass->reflFields[$assocField]->getValue($prevManagedCopy)->add($managedCopy); + + if ($assoc['type'] == ClassMetadata::ONE_TO_MANY) { + $class->reflFields[$assoc['mappedBy']]->setValue($managedCopy, $prevManagedCopy); + } + } + } + + // Mark the managed copy visited as well + $visited[spl_object_hash($managedCopy)] = true; + + $this->cascadeMerge($entity, $managedCopy, $visited); + + return $managedCopy; + } + + /** + * Detaches an entity from the persistence management. It's persistence will + * no longer be managed by Doctrine. + * + * @param object $entity The entity to detach. + */ + public function detach($entity) + { + $visited = array(); + + $this->doDetach($entity, $visited); + } + + /** + * Executes a detach operation on the given entity. + * + * @param object $entity + * @param array $visited + * @param boolean $noCascade if true, don't cascade detach operation + */ + private function doDetach($entity, array &$visited, $noCascade = false) + { + $oid = spl_object_hash($entity); + + if (isset($visited[$oid])) { + return; // Prevent infinite recursion + } + + $visited[$oid] = $entity; // mark visited + + switch ($this->getEntityState($entity, self::STATE_DETACHED)) { + case self::STATE_MANAGED: + if ($this->isInIdentityMap($entity)) { + $this->removeFromIdentityMap($entity); + } + + unset( + $this->entityInsertions[$oid], + $this->entityUpdates[$oid], + $this->entityDeletions[$oid], + $this->entityIdentifiers[$oid], + $this->entityStates[$oid], + $this->originalEntityData[$oid] + ); + break; + case self::STATE_NEW: + case self::STATE_DETACHED: + return; + } + + if ( ! $noCascade) { + $this->cascadeDetach($entity, $visited); + } + } + + /** + * Refreshes the state of the given entity from the database, overwriting + * any local, unpersisted changes. + * + * @param object $entity The entity to refresh. + * @throws InvalidArgumentException If the entity is not MANAGED. + */ + public function refresh($entity) + { + $visited = array(); + + $this->doRefresh($entity, $visited); + } + + /** + * Executes a refresh operation on an entity. + * + * @param object $entity The entity to refresh. + * @param array $visited The already visited entities during cascades. + * @throws InvalidArgumentException If the entity is not MANAGED. + */ + private function doRefresh($entity, array &$visited) + { + $oid = spl_object_hash($entity); + + if (isset($visited[$oid])) { + return; // Prevent infinite recursion + } + + $visited[$oid] = $entity; // mark visited + + $class = $this->em->getClassMetadata(get_class($entity)); + + if ($this->getEntityState($entity) !== self::STATE_MANAGED) { + throw ORMInvalidArgumentException::entityNotManaged($entity); + } + + $this->getEntityPersister($class->name)->refresh( + array_combine($class->getIdentifierFieldNames(), $this->entityIdentifiers[$oid]), + $entity + ); + + $this->cascadeRefresh($entity, $visited); + } + + /** + * Cascades a refresh operation to associated entities. + * + * @param object $entity + * @param array $visited + */ + private function cascadeRefresh($entity, array &$visited) + { + $class = $this->em->getClassMetadata(get_class($entity)); + + $associationMappings = array_filter( + $class->associationMappings, + function ($assoc) { return $assoc['isCascadeRefresh']; } + ); + + foreach ($associationMappings as $assoc) { + $relatedEntities = $class->reflFields[$assoc['fieldName']]->getValue($entity); + + switch (true) { + case ($relatedEntities instanceof PersistentCollection): + // Unwrap so that foreach() does not initialize + $relatedEntities = $relatedEntities->unwrap(); + // break; is commented intentionally! + + case ($relatedEntities instanceof Collection): + case (is_array($relatedEntities)): + foreach ($relatedEntities as $relatedEntity) { + $this->doRefresh($relatedEntity, $visited); + } + break; + + case ($relatedEntities !== null): + $this->doRefresh($relatedEntities, $visited); + break; + + default: + // Do nothing + } + } + } + + /** + * Cascades a detach operation to associated entities. + * + * @param object $entity + * @param array $visited + */ + private function cascadeDetach($entity, array &$visited) + { + $class = $this->em->getClassMetadata(get_class($entity)); + + $associationMappings = array_filter( + $class->associationMappings, + function ($assoc) { return $assoc['isCascadeDetach']; } + ); + + foreach ($associationMappings as $assoc) { + $relatedEntities = $class->reflFields[$assoc['fieldName']]->getValue($entity); + + switch (true) { + case ($relatedEntities instanceof PersistentCollection): + // Unwrap so that foreach() does not initialize + $relatedEntities = $relatedEntities->unwrap(); + // break; is commented intentionally! + + case ($relatedEntities instanceof Collection): + case (is_array($relatedEntities)): + foreach ($relatedEntities as $relatedEntity) { + $this->doDetach($relatedEntity, $visited); + } + break; + + case ($relatedEntities !== null): + $this->doDetach($relatedEntities, $visited); + break; + + default: + // Do nothing + } + } + } + + /** + * Cascades a merge operation to associated entities. + * + * @param object $entity + * @param object $managedCopy + * @param array $visited + */ + private function cascadeMerge($entity, $managedCopy, array &$visited) + { + $class = $this->em->getClassMetadata(get_class($entity)); + + $associationMappings = array_filter( + $class->associationMappings, + function ($assoc) { return $assoc['isCascadeMerge']; } + ); + + foreach ($associationMappings as $assoc) { + $relatedEntities = $class->reflFields[$assoc['fieldName']]->getValue($entity); + + if ($relatedEntities instanceof Collection) { + if ($relatedEntities === $class->reflFields[$assoc['fieldName']]->getValue($managedCopy)) { + continue; + } + + if ($relatedEntities instanceof PersistentCollection) { + // Unwrap so that foreach() does not initialize + $relatedEntities = $relatedEntities->unwrap(); + } + + foreach ($relatedEntities as $relatedEntity) { + $this->doMerge($relatedEntity, $visited, $managedCopy, $assoc); + } + } else if ($relatedEntities !== null) { + $this->doMerge($relatedEntities, $visited, $managedCopy, $assoc); + } + } + } + + /** + * Cascades the save operation to associated entities. + * + * @param object $entity + * @param array $visited + * @param array $insertNow + */ + private function cascadePersist($entity, array &$visited) + { + $class = $this->em->getClassMetadata(get_class($entity)); + + $associationMappings = array_filter( + $class->associationMappings, + function ($assoc) { return $assoc['isCascadePersist']; } + ); + + foreach ($associationMappings as $assoc) { + $relatedEntities = $class->reflFields[$assoc['fieldName']]->getValue($entity); + + switch (true) { + case ($relatedEntities instanceof PersistentCollection): + // Unwrap so that foreach() does not initialize + $relatedEntities = $relatedEntities->unwrap(); + // break; is commented intentionally! + + case ($relatedEntities instanceof Collection): + case (is_array($relatedEntities)): + foreach ($relatedEntities as $relatedEntity) { + $this->doPersist($relatedEntity, $visited); + } + break; + + case ($relatedEntities !== null): + $this->doPersist($relatedEntities, $visited); + break; + + default: + // Do nothing + } + } + } + + /** + * Cascades the delete operation to associated entities. + * + * @param object $entity + * @param array $visited + */ + private function cascadeRemove($entity, array &$visited) + { + $class = $this->em->getClassMetadata(get_class($entity)); + + $associationMappings = array_filter( + $class->associationMappings, + function ($assoc) { return $assoc['isCascadeRemove']; } + ); + + foreach ($associationMappings as $assoc) { + if ($entity instanceof Proxy && !$entity->__isInitialized__) { + $entity->__load(); + } + + $relatedEntities = $class->reflFields[$assoc['fieldName']]->getValue($entity); + + switch (true) { + case ($relatedEntities instanceof Collection): + case (is_array($relatedEntities)): + // If its a PersistentCollection initialization is intended! No unwrap! + foreach ($relatedEntities as $relatedEntity) { + $this->doRemove($relatedEntity, $visited); + } + break; + + case ($relatedEntities !== null): + $this->doRemove($relatedEntities, $visited); + break; + + default: + // Do nothing + } + } + } + + /** + * Acquire a lock on the given entity. + * + * @param object $entity + * @param int $lockMode + * @param int $lockVersion + */ + public function lock($entity, $lockMode, $lockVersion = null) + { + if ($this->getEntityState($entity, self::STATE_DETACHED) != self::STATE_MANAGED) { + throw ORMInvalidArgumentException::entityNotManaged($entity); + } + + $entityName = get_class($entity); + $class = $this->em->getClassMetadata($entityName); + + switch ($lockMode) { + case \Doctrine\DBAL\LockMode::OPTIMISTIC; + if ( ! $class->isVersioned) { + throw OptimisticLockException::notVersioned($entityName); + } + + if ($lockVersion === null) { + return; + } + + $entityVersion = $class->reflFields[$class->versionField]->getValue($entity); + + if ($entityVersion != $lockVersion) { + throw OptimisticLockException::lockFailedVersionMissmatch($entity, $lockVersion, $entityVersion); + } + + break; + + case \Doctrine\DBAL\LockMode::PESSIMISTIC_READ: + case \Doctrine\DBAL\LockMode::PESSIMISTIC_WRITE: + if (!$this->em->getConnection()->isTransactionActive()) { + throw TransactionRequiredException::transactionRequired(); + } + + $oid = spl_object_hash($entity); + + $this->getEntityPersister($class->name)->lock( + array_combine($class->getIdentifierFieldNames(), $this->entityIdentifiers[$oid]), + $lockMode + ); + break; + + default: + // Do nothing + } + } + + /** + * Gets the CommitOrderCalculator used by the UnitOfWork to order commits. + * + * @return \Doctrine\ORM\Internal\CommitOrderCalculator + */ + public function getCommitOrderCalculator() + { + if ($this->commitOrderCalculator === null) { + $this->commitOrderCalculator = new Internal\CommitOrderCalculator; + } + + return $this->commitOrderCalculator; + } + + /** + * Clears the UnitOfWork. + * + * @param string $entityName if given, only entities of this type will get detached + */ + public function clear($entityName = null) + { + if ($entityName === null) { + $this->identityMap = + $this->entityIdentifiers = + $this->originalEntityData = + $this->entityChangeSets = + $this->entityStates = + $this->scheduledForDirtyCheck = + $this->entityInsertions = + $this->entityUpdates = + $this->entityDeletions = + $this->collectionDeletions = + $this->collectionUpdates = + $this->extraUpdates = + $this->readOnlyObjects = + $this->orphanRemovals = array(); + + if ($this->commitOrderCalculator !== null) { + $this->commitOrderCalculator->clear(); + } + } else { + $visited = array(); + foreach ($this->identityMap as $className => $entities) { + if ($className === $entityName) { + foreach ($entities as $entity) { + $this->doDetach($entity, $visited, true); + } + } + } + } + + if ($this->evm->hasListeners(Events::onClear)) { + $this->evm->dispatchEvent(Events::onClear, new Event\OnClearEventArgs($this->em, $entityName)); + } + } + + /** + * INTERNAL: + * Schedules an orphaned entity for removal. The remove() operation will be + * invoked on that entity at the beginning of the next commit of this + * UnitOfWork. + * + * @ignore + * @param object $entity + */ + public function scheduleOrphanRemoval($entity) + { + $this->orphanRemovals[spl_object_hash($entity)] = $entity; + } + + /** + * INTERNAL: + * Schedules a complete collection for removal when this UnitOfWork commits. + * + * @param PersistentCollection $coll + */ + public function scheduleCollectionDeletion(PersistentCollection $coll) + { + $coid = spl_object_hash($coll); + + //TODO: if $coll is already scheduled for recreation ... what to do? + // Just remove $coll from the scheduled recreations? + if (isset($this->collectionUpdates[$coid])) { + unset($this->collectionUpdates[$coid]); + } + + $this->collectionDeletions[$coid] = $coll; + } + + public function isCollectionScheduledForDeletion(PersistentCollection $coll) + { + return isset($this->collectionsDeletions[spl_object_hash($coll)]); + } + + /** + * @param ClassMetadata $class + */ + private function newInstance($class) + { + $entity = $class->newInstance(); + + if ($entity instanceof \Doctrine\Common\Persistence\ObjectManagerAware) { + $entity->injectObjectManager($this->em, $class); + } + + return $entity; + } + + /** + * INTERNAL: + * Creates an entity. Used for reconstitution of persistent entities. + * + * @ignore + * @param string $className The name of the entity class. + * @param array $data The data for the entity. + * @param array $hints Any hints to account for during reconstitution/lookup of the entity. + * @return object The managed entity instance. + * @internal Highly performance-sensitive method. + * + * @todo Rename: getOrCreateEntity + */ + public function createEntity($className, array $data, &$hints = array()) + { + $class = $this->em->getClassMetadata($className); + //$isReadOnly = isset($hints[Query::HINT_READ_ONLY]); + + if ($class->isIdentifierComposite) { + $id = array(); + + foreach ($class->identifier as $fieldName) { + $id[$fieldName] = isset($class->associationMappings[$fieldName]) + ? $data[$class->associationMappings[$fieldName]['joinColumns'][0]['name']] + : $data[$fieldName]; + } + + $idHash = implode(' ', $id); + } else { + $idHash = isset($class->associationMappings[$class->identifier[0]]) + ? $data[$class->associationMappings[$class->identifier[0]]['joinColumns'][0]['name']] + : $data[$class->identifier[0]]; + + $id = array($class->identifier[0] => $idHash); + } + + if (isset($this->identityMap[$class->rootEntityName][$idHash])) { + $entity = $this->identityMap[$class->rootEntityName][$idHash]; + $oid = spl_object_hash($entity); + + if ($entity instanceof Proxy && ! $entity->__isInitialized__) { + $entity->__isInitialized__ = true; + $overrideLocalValues = true; + + if ($entity instanceof NotifyPropertyChanged) { + $entity->addPropertyChangedListener($this); + } + } else { + $overrideLocalValues = isset($hints[Query::HINT_REFRESH]); + + // If only a specific entity is set to refresh, check that it's the one + if(isset($hints[Query::HINT_REFRESH_ENTITY])) { + $overrideLocalValues = $hints[Query::HINT_REFRESH_ENTITY] === $entity; + + // inject ObjectManager into just loaded proxies. + if ($overrideLocalValues && $entity instanceof ObjectManagerAware) { + $entity->injectObjectManager($this->em, $class); + } + } + } + + if ($overrideLocalValues) { + $this->originalEntityData[$oid] = $data; + } + } else { + $entity = $this->newInstance($class); + $oid = spl_object_hash($entity); + + $this->entityIdentifiers[$oid] = $id; + $this->entityStates[$oid] = self::STATE_MANAGED; + $this->originalEntityData[$oid] = $data; + $this->identityMap[$class->rootEntityName][$idHash] = $entity; + + if ($entity instanceof NotifyPropertyChanged) { + $entity->addPropertyChangedListener($this); + } + + $overrideLocalValues = true; + } + + if ( ! $overrideLocalValues) { + return $entity; + } + + foreach ($data as $field => $value) { + if (isset($class->fieldMappings[$field])) { + $class->reflFields[$field]->setValue($entity, $value); + } + } + + // Loading the entity right here, if its in the eager loading map get rid of it there. + unset($this->eagerLoadingEntities[$class->rootEntityName][$idHash]); + + if (isset($this->eagerLoadingEntities[$class->rootEntityName]) && ! $this->eagerLoadingEntities[$class->rootEntityName]) { + unset($this->eagerLoadingEntities[$class->rootEntityName]); + } + + // Properly initialize any unfetched associations, if partial objects are not allowed. + if (isset($hints[Query::HINT_FORCE_PARTIAL_LOAD])) { + return $entity; + } + + foreach ($class->associationMappings as $field => $assoc) { + // Check if the association is not among the fetch-joined associations already. + if (isset($hints['fetchAlias']) && isset($hints['fetched'][$hints['fetchAlias']][$field])) { + continue; + } + + $targetClass = $this->em->getClassMetadata($assoc['targetEntity']); + + switch (true) { + case ($assoc['type'] & ClassMetadata::TO_ONE): + if ( ! $assoc['isOwningSide']) { + // Inverse side of x-to-one can never be lazy + $class->reflFields[$field]->setValue($entity, $this->getEntityPersister($assoc['targetEntity'])->loadOneToOneEntity($assoc, $entity)); + + continue 2; + } + + $associatedId = array(); + + // TODO: Is this even computed right in all cases of composite keys? + foreach ($assoc['targetToSourceKeyColumns'] as $targetColumn => $srcColumn) { + $joinColumnValue = isset($data[$srcColumn]) ? $data[$srcColumn] : null; + + if ($joinColumnValue !== null) { + if ($targetClass->containsForeignIdentifier) { + $associatedId[$targetClass->getFieldForColumn($targetColumn)] = $joinColumnValue; + } else { + $associatedId[$targetClass->fieldNames[$targetColumn]] = $joinColumnValue; + } + } + } + + if ( ! $associatedId) { + // Foreign key is NULL + $class->reflFields[$field]->setValue($entity, null); + $this->originalEntityData[$oid][$field] = null; + + continue; + } + + if ( ! isset($hints['fetchMode'][$class->name][$field])) { + $hints['fetchMode'][$class->name][$field] = $assoc['fetch']; + } + + // Foreign key is set + // Check identity map first + // FIXME: Can break easily with composite keys if join column values are in + // wrong order. The correct order is the one in ClassMetadata#identifier. + $relatedIdHash = implode(' ', $associatedId); + + switch (true) { + case (isset($this->identityMap[$targetClass->rootEntityName][$relatedIdHash])): + $newValue = $this->identityMap[$targetClass->rootEntityName][$relatedIdHash]; + + // if this is an uninitialized proxy, we are deferring eager loads, + // this association is marked as eager fetch, and its an uninitialized proxy (wtf!) + // then we cann append this entity for eager loading! + if ($hints['fetchMode'][$class->name][$field] == ClassMetadata::FETCH_EAGER && + isset($hints['deferEagerLoad']) && + !$targetClass->isIdentifierComposite && + $newValue instanceof Proxy && + $newValue->__isInitialized__ === false) { + + $this->eagerLoadingEntities[$targetClass->rootEntityName][$relatedIdHash] = current($associatedId); + } + + break; + + case ($targetClass->subClasses): + // If it might be a subtype, it can not be lazy. There isn't even + // a way to solve this with deferred eager loading, which means putting + // an entity with subclasses at a *-to-one location is really bad! (performance-wise) + $newValue = $this->getEntityPersister($assoc['targetEntity'])->loadOneToOneEntity($assoc, $entity, $associatedId); + break; + + default: + switch (true) { + // We are negating the condition here. Other cases will assume it is valid! + case ($hints['fetchMode'][$class->name][$field] !== ClassMetadata::FETCH_EAGER): + $newValue = $this->em->getProxyFactory()->getProxy($assoc['targetEntity'], $associatedId); + break; + + // Deferred eager load only works for single identifier classes + case (isset($hints['deferEagerLoad']) && ! $targetClass->isIdentifierComposite): + // TODO: Is there a faster approach? + $this->eagerLoadingEntities[$targetClass->rootEntityName][$relatedIdHash] = current($associatedId); + + $newValue = $this->em->getProxyFactory()->getProxy($assoc['targetEntity'], $associatedId); + break; + + default: + // TODO: This is very imperformant, ignore it? + $newValue = $this->em->find($assoc['targetEntity'], $associatedId); + break; + } + + // PERF: Inlined & optimized code from UnitOfWork#registerManaged() + $newValueOid = spl_object_hash($newValue); + $this->entityIdentifiers[$newValueOid] = $associatedId; + $this->identityMap[$targetClass->rootEntityName][$relatedIdHash] = $newValue; + $this->entityStates[$newValueOid] = self::STATE_MANAGED; + // make sure that when an proxy is then finally loaded, $this->originalEntityData is set also! + break; + } + + $this->originalEntityData[$oid][$field] = $newValue; + $class->reflFields[$field]->setValue($entity, $newValue); + + if ($assoc['inversedBy'] && $assoc['type'] & ClassMetadata::ONE_TO_ONE) { + $inverseAssoc = $targetClass->associationMappings[$assoc['inversedBy']]; + $targetClass->reflFields[$inverseAssoc['fieldName']]->setValue($newValue, $entity); + } + + break; + + default: + // Inject collection + $pColl = new PersistentCollection($this->em, $targetClass, new ArrayCollection); + $pColl->setOwner($entity, $assoc); + $pColl->setInitialized(false); + + $reflField = $class->reflFields[$field]; + $reflField->setValue($entity, $pColl); + + if ($assoc['fetch'] == ClassMetadata::FETCH_EAGER) { + $this->loadCollection($pColl); + $pColl->takeSnapshot(); + } + + $this->originalEntityData[$oid][$field] = $pColl; + break; + } + } + + if ($overrideLocalValues) { + if (isset($class->lifecycleCallbacks[Events::postLoad])) { + $class->invokeLifecycleCallbacks(Events::postLoad, $entity); + } + + + if ($this->evm->hasListeners(Events::postLoad)) { + $this->evm->dispatchEvent(Events::postLoad, new LifecycleEventArgs($entity, $this->em)); + } + } + + return $entity; + } + + /** + * @return void + */ + public function triggerEagerLoads() + { + if ( ! $this->eagerLoadingEntities) { + return; + } + + // avoid infinite recursion + $eagerLoadingEntities = $this->eagerLoadingEntities; + $this->eagerLoadingEntities = array(); + + foreach ($eagerLoadingEntities as $entityName => $ids) { + $class = $this->em->getClassMetadata($entityName); + + if ($ids) { + $this->getEntityPersister($entityName)->loadAll( + array_combine($class->identifier, array(array_values($ids))) + ); + } + } + } + + /** + * Initializes (loads) an uninitialized persistent collection of an entity. + * + * @param PeristentCollection $collection The collection to initialize. + * @todo Maybe later move to EntityManager#initialize($proxyOrCollection). See DDC-733. + */ + public function loadCollection(PersistentCollection $collection) + { + $assoc = $collection->getMapping(); + $persister = $this->getEntityPersister($assoc['targetEntity']); + + switch ($assoc['type']) { + case ClassMetadata::ONE_TO_MANY: + $persister->loadOneToManyCollection($assoc, $collection->getOwner(), $collection); + break; + + case ClassMetadata::MANY_TO_MANY: + $persister->loadManyToManyCollection($assoc, $collection->getOwner(), $collection); + break; + } + } + + /** + * Gets the identity map of the UnitOfWork. + * + * @return array + */ + public function getIdentityMap() + { + return $this->identityMap; + } + + /** + * Gets the original data of an entity. The original data is the data that was + * present at the time the entity was reconstituted from the database. + * + * @param object $entity + * @return array + */ + public function getOriginalEntityData($entity) + { + $oid = spl_object_hash($entity); + + if (isset($this->originalEntityData[$oid])) { + return $this->originalEntityData[$oid]; + } + + return array(); + } + + /** + * @ignore + */ + public function setOriginalEntityData($entity, array $data) + { + $this->originalEntityData[spl_object_hash($entity)] = $data; + } + + /** + * INTERNAL: + * Sets a property value of the original data array of an entity. + * + * @ignore + * @param string $oid + * @param string $property + * @param mixed $value + */ + public function setOriginalEntityProperty($oid, $property, $value) + { + $this->originalEntityData[$oid][$property] = $value; + } + + /** + * Gets the identifier of an entity. + * The returned value is always an array of identifier values. If the entity + * has a composite identifier then the identifier values are in the same + * order as the identifier field names as returned by ClassMetadata#getIdentifierFieldNames(). + * + * @param object $entity + * @return array The identifier values. + */ + public function getEntityIdentifier($entity) + { + return $this->entityIdentifiers[spl_object_hash($entity)]; + } + + /** + * Tries to find an entity with the given identifier in the identity map of + * this UnitOfWork. + * + * @param mixed $id The entity identifier to look for. + * @param string $rootClassName The name of the root class of the mapped entity hierarchy. + * @return mixed Returns the entity with the specified identifier if it exists in + * this UnitOfWork, FALSE otherwise. + */ + public function tryGetById($id, $rootClassName) + { + $idHash = implode(' ', (array) $id); + + if (isset($this->identityMap[$rootClassName][$idHash])) { + return $this->identityMap[$rootClassName][$idHash]; + } + + return false; + } + + /** + * Schedules an entity for dirty-checking at commit-time. + * + * @param object $entity The entity to schedule for dirty-checking. + * @todo Rename: scheduleForSynchronization + */ + public function scheduleForDirtyCheck($entity) + { + $rootClassName = $this->em->getClassMetadata(get_class($entity))->rootEntityName; + + $this->scheduledForDirtyCheck[$rootClassName][spl_object_hash($entity)] = $entity; + } + + /** + * Checks whether the UnitOfWork has any pending insertions. + * + * @return boolean TRUE if this UnitOfWork has pending insertions, FALSE otherwise. + */ + public function hasPendingInsertions() + { + return ! empty($this->entityInsertions); + } + + /** + * Calculates the size of the UnitOfWork. The size of the UnitOfWork is the + * number of entities in the identity map. + * + * @return integer + */ + public function size() + { + $countArray = array_map(function ($item) { return count($item); }, $this->identityMap); + + return array_sum($countArray); + } + + /** + * Gets the EntityPersister for an Entity. + * + * @param string $entityName The name of the Entity. + * + * @return \Doctrine\ORM\Persisters\BasicEntityPersister + */ + public function getEntityPersister($entityName) + { + if (isset($this->persisters[$entityName])) { + return $this->persisters[$entityName]; + } + + $class = $this->em->getClassMetadata($entityName); + + switch (true) { + case ($class->isInheritanceTypeNone()): + $persister = new Persisters\BasicEntityPersister($this->em, $class); + break; + + case ($class->isInheritanceTypeSingleTable()): + $persister = new Persisters\SingleTablePersister($this->em, $class); + break; + + case ($class->isInheritanceTypeJoined()): + $persister = new Persisters\JoinedSubclassPersister($this->em, $class); + break; + + default: + $persister = new Persisters\UnionSubclassPersister($this->em, $class); + } + + $this->persisters[$entityName] = $persister; + + return $this->persisters[$entityName]; + } + + /** + * Gets a collection persister for a collection-valued association. + * + * @param AssociationMapping $association + * + * @return AbstractCollectionPersister + */ + public function getCollectionPersister(array $association) + { + $type = $association['type']; + + if (isset($this->collectionPersisters[$type])) { + return $this->collectionPersisters[$type]; + } + + switch ($type) { + case ClassMetadata::ONE_TO_MANY: + $persister = new Persisters\OneToManyPersister($this->em); + break; + + case ClassMetadata::MANY_TO_MANY: + $persister = new Persisters\ManyToManyPersister($this->em); + break; + } + + $this->collectionPersisters[$type] = $persister; + + return $this->collectionPersisters[$type]; + } + + /** + * INTERNAL: + * Registers an entity as managed. + * + * @param object $entity The entity. + * @param array $id The identifier values. + * @param array $data The original entity data. + */ + public function registerManaged($entity, array $id, array $data) + { + $oid = spl_object_hash($entity); + + $this->entityIdentifiers[$oid] = $id; + $this->entityStates[$oid] = self::STATE_MANAGED; + $this->originalEntityData[$oid] = $data; + + $this->addToIdentityMap($entity); + } + + /** + * INTERNAL: + * Clears the property changeset of the entity with the given OID. + * + * @param string $oid The entity's OID. + */ + public function clearEntityChangeSet($oid) + { + $this->entityChangeSets[$oid] = array(); + } + + /* PropertyChangedListener implementation */ + + /** + * Notifies this UnitOfWork of a property change in an entity. + * + * @param object $entity The entity that owns the property. + * @param string $propertyName The name of the property that changed. + * @param mixed $oldValue The old value of the property. + * @param mixed $newValue The new value of the property. + */ + public function propertyChanged($entity, $propertyName, $oldValue, $newValue) + { + $oid = spl_object_hash($entity); + $class = $this->em->getClassMetadata(get_class($entity)); + + $isAssocField = isset($class->associationMappings[$propertyName]); + + if ( ! $isAssocField && ! isset($class->fieldMappings[$propertyName])) { + return; // ignore non-persistent fields + } + + // Update changeset and mark entity for synchronization + $this->entityChangeSets[$oid][$propertyName] = array($oldValue, $newValue); + + if ( ! isset($this->scheduledForDirtyCheck[$class->rootEntityName][$oid])) { + $this->scheduleForDirtyCheck($entity); + } + } + + /** + * Gets the currently scheduled entity insertions in this UnitOfWork. + * + * @return array + */ + public function getScheduledEntityInsertions() + { + return $this->entityInsertions; + } + + /** + * Gets the currently scheduled entity updates in this UnitOfWork. + * + * @return array + */ + public function getScheduledEntityUpdates() + { + return $this->entityUpdates; + } + + /** + * Gets the currently scheduled entity deletions in this UnitOfWork. + * + * @return array + */ + public function getScheduledEntityDeletions() + { + return $this->entityDeletions; + } + + /** + * Get the currently scheduled complete collection deletions + * + * @return array + */ + public function getScheduledCollectionDeletions() + { + return $this->collectionDeletions; + } + + /** + * Gets the currently scheduled collection inserts, updates and deletes. + * + * @return array + */ + public function getScheduledCollectionUpdates() + { + return $this->collectionUpdates; + } + + /** + * Helper method to initialize a lazy loading proxy or persistent collection. + * + * @param object + * @return void + */ + public function initializeObject($obj) + { + if ($obj instanceof Proxy) { + $obj->__load(); + + return; + } + + if ($obj instanceof PersistentCollection) { + $obj->initialize(); + } + } + + /** + * Helper method to show an object as string. + * + * @param object $obj + * @return string + */ + private static function objToStr($obj) + { + return method_exists($obj, '__toString') ? (string)$obj : get_class($obj).'@'.spl_object_hash($obj); + } + + /** + * Marks an entity as read-only so that it will not be considered for updates during UnitOfWork#commit(). + * + * This operation cannot be undone as some parts of the UnitOfWork now keep gathering information + * on this object that might be necessary to perform a correct udpate. + * + * @throws \InvalidArgumentException + * @param $object + * @return void + */ + public function markReadOnly($object) + { + if ( ! is_object($object) || ! $this->isInIdentityMap($object)) { + throw ORMInvalidArgumentException::readOnlyRequiresManagedEntity($object); + } + + $this->readOnlyObjects[spl_object_hash($object)] = true; + } + + /** + * Is this entity read only? + * + * @throws \InvalidArgumentException + * @param $object + * @return void + */ + public function isReadOnly($object) + { + if ( ! is_object($object) ) { + throw ORMInvalidArgumentException::readOnlyRequiresManagedEntity($object); + } + + return isset($this->readOnlyObjects[spl_object_hash($object)]); + } +} diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Version.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Version.php new file mode 100644 index 0000000..020148e --- /dev/null +++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Version.php @@ -0,0 +1,55 @@ +. + */ + +namespace Doctrine\ORM; + +/** + * Class to store and retrieve the version of Doctrine + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class Version +{ + /** + * Current Doctrine Version + */ + const VERSION = '2.2.3-DEV'; + + /** + * Compares a Doctrine version with the current one. + * + * @param string $version Doctrine version to compare. + * @return int Returns -1 if older, 0 if it is the same, 1 if version + * passed as argument is newer. + */ + public static function compare($version) + { + $currentVersion = str_replace(' ', '', strtolower(self::VERSION)); + $version = str_replace(' ', '', $version); + + return version_compare($version, $currentVersion); + } +} diff --git a/vendor/doctrine/orm/phpunit.xml.dist b/vendor/doctrine/orm/phpunit.xml.dist new file mode 100644 index 0000000..3ab5edb --- /dev/null +++ b/vendor/doctrine/orm/phpunit.xml.dist @@ -0,0 +1,59 @@ + + + + + + + ./tests/Doctrine/Tests/ORM + + + + + + performance + locking_functional + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vendor/doctrine/orm/run-all.sh b/vendor/doctrine/orm/run-all.sh new file mode 100755 index 0000000..80712ee --- /dev/null +++ b/vendor/doctrine/orm/run-all.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# This script is a small convenience wrapper for running the doctrine testsuite against a large bunch of databases. +# Just create the phpunit.xmls as described in the array below and configure the specific files section +# to connect to that database. Just omit a file if you dont have that database and the tests will be skipped. + +configs[1]="mysql.phpunit.xml" +configs[2]='postgres.phpunit.xml' +configs[3]='sqlite.phpunit.xml' +configs[4]='oracle.phpunit.xml' +configs[5]='db2.phpunit.xml' +configs[6]='pdo-ibm.phpunit.xml' +configs[7]='sqlsrv.phpunit.xml' + +for i in "${configs[@]}"; do + if [ -f "$i" ]; + then + echo "RUNNING TESTS WITH CONFIG $i" + phpunit -c "$i" "$@" + fi; +done diff --git a/vendor/jms/aop-bundle/JMS/AopBundle/Aop/InterceptorLoader.php b/vendor/jms/aop-bundle/JMS/AopBundle/Aop/InterceptorLoader.php new file mode 100644 index 0000000..79ac040 --- /dev/null +++ b/vendor/jms/aop-bundle/JMS/AopBundle/Aop/InterceptorLoader.php @@ -0,0 +1,58 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\AopBundle\Aop; + +use CG\Proxy\InterceptorLoaderInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Lazy-loading interceptor loader implementation. + * + * @author Johannes M. Schmitt + */ +class InterceptorLoader implements InterceptorLoaderInterface +{ + private $container; + private $interceptors; + private $loadedInterceptors = array(); + + public function __construct(ContainerInterface $container, array $interceptors) + { + $this->container = $container; + $this->interceptors = $interceptors; + } + + public function loadInterceptors(\ReflectionMethod $method) + { + if (!isset($this->interceptors[$method->class][$method->name])) { + return array(); + } + + if (isset($this->loadedInterceptors[$method->class][$method->name])) { + return $this->loadedInterceptors[$method->class][$method->name]; + } + + $interceptors = array(); + foreach ($this->interceptors[$method->class][$method->name] as $id) { + $interceptors[] = $this->container->get($id); + } + + return $this->loadedInterceptors[$method->class][$method->name] = $interceptors; + } +} \ No newline at end of file diff --git a/vendor/jms/aop-bundle/JMS/AopBundle/Aop/PointcutContainer.php b/vendor/jms/aop-bundle/JMS/AopBundle/Aop/PointcutContainer.php new file mode 100644 index 0000000..5c73741 --- /dev/null +++ b/vendor/jms/aop-bundle/JMS/AopBundle/Aop/PointcutContainer.php @@ -0,0 +1,34 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\AopBundle\Aop; + +final class PointcutContainer +{ + private $pointcuts; + + public function __construct(array $pointcuts) + { + $this->pointcuts = $pointcuts; + } + + public function getPointcuts() + { + return $this->pointcuts; + } +} \ No newline at end of file diff --git a/vendor/jms/aop-bundle/JMS/AopBundle/Aop/PointcutInterface.php b/vendor/jms/aop-bundle/JMS/AopBundle/Aop/PointcutInterface.php new file mode 100644 index 0000000..a263d52 --- /dev/null +++ b/vendor/jms/aop-bundle/JMS/AopBundle/Aop/PointcutInterface.php @@ -0,0 +1,54 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\AopBundle\Aop; + +/** + * Pointcut Interface. + * + * Implementations of this class are responsible for making a decision on whether + * a certain method call matches the advice which is associated with this pointcut. + * + * @author Johannes M. Schmitt + */ +interface PointcutInterface +{ + /** + * Determines whether the advice applies to instances of the given class. + * + * There are some limits as to what you can do in this method. Namely, you may + * only base your decision on resources that are part of the ContainerBuilder. + * Specifically, you may not use any data in the class itself, such as + * annotations. + * + * @param \ReflectionClass $class + * @return boolean + */ + function matchesClass(\ReflectionClass $class); + + /** + * Determines whether the advice applies to the given method. + * + * This method is not limited in the way the matchesClass method is. It may + * use information in the associated class to make its decision. + * + * @param \ReflectionMethod $method + * @return boolean + */ + function matchesMethod(\ReflectionMethod $method); +} \ No newline at end of file diff --git a/vendor/jms/aop-bundle/JMS/AopBundle/Aop/RegexPointcut.php b/vendor/jms/aop-bundle/JMS/AopBundle/Aop/RegexPointcut.php new file mode 100644 index 0000000..cbb1404 --- /dev/null +++ b/vendor/jms/aop-bundle/JMS/AopBundle/Aop/RegexPointcut.php @@ -0,0 +1,46 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\AopBundle\Aop; + +/** + * A regex pointcut implementation. + * + * Uses a regular expression for determining whether the pointcut matches. + * + * @author Johannes M. Schmitt + */ +class RegexPointcut implements PointcutInterface +{ + private $pattern; + + public function __construct($pattern) + { + $this->pattern = $pattern; + } + + public function matchesClass(\ReflectionClass $class) + { + return true; + } + + public function matchesMethod(\ReflectionMethod $method) + { + return 0 < preg_match('#'.$this->pattern.'#', sprintf('%s::%s', $method->class, $method->name)); + } +} \ No newline at end of file diff --git a/vendor/jms/aop-bundle/JMS/AopBundle/DependencyInjection/Compiler/PointcutMatchingPass.php b/vendor/jms/aop-bundle/JMS/AopBundle/DependencyInjection/Compiler/PointcutMatchingPass.php new file mode 100644 index 0000000..51967a6 --- /dev/null +++ b/vendor/jms/aop-bundle/JMS/AopBundle/DependencyInjection/Compiler/PointcutMatchingPass.php @@ -0,0 +1,195 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\AopBundle\DependencyInjection\Compiler; + +use CG\Core\ClassUtils; + +use JMS\AopBundle\Exception\RuntimeException; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\DependencyInjection\Reference; +use CG\Proxy\Enhancer; +use CG\Proxy\InterceptionGenerator; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Matches pointcuts against service methods. + * + * This pass will collect the advices that match a certain method, and then + * generate proxy classes where necessary. + * + * @author Johannes M. Schmitt + */ +class PointcutMatchingPass implements CompilerPassInterface +{ + private $pointcuts; + private $cacheDir; + private $container; + + public function __construct(array $pointcuts = null) + { + $this->pointcuts = $pointcuts; + } + + public function process(ContainerBuilder $container) + { + $this->container = $container; + $this->cacheDir = $container->getParameter('jms_aop.cache_dir').'/proxies'; + $pointcuts = $this->getPointcuts(); + + $interceptors = array(); + foreach ($container->getDefinitions() as $id => $definition) { + $this->processDefinition($definition, $pointcuts, $interceptors); + + $this->processInlineDefinitions($pointcuts, $interceptors, $definition->getArguments()); + $this->processInlineDefinitions($pointcuts, $interceptors, $definition->getMethodCalls()); + $this->processInlineDefinitions($pointcuts, $interceptors, $definition->getProperties()); + } + + $container + ->getDefinition('jms_aop.interceptor_loader') + ->addArgument($interceptors) + ; + } + + private function processInlineDefinitions($pointcuts, &$interceptors, array $a) { + foreach ($a as $k => $v) { + if ($v instanceof Definition) { + $this->processDefinition($v, $pointcuts, $interceptors); + } else if (is_array($v)) { + $this->processInlineDefinitions($pointcuts, $interceptors, $v); + } + } + } + + private function processDefinition(Definition $definition, $pointcuts, &$interceptors) + { + if ($definition->isSynthetic()) { + return; + } + + if ($definition->getFactoryService() || $definition->getFactoryClass()) { + return; + } + + if ($file = $definition->getFile()) { + require_once $file; + } + + if (!class_exists($definition->getClass())) { + return; + } + + $class = new \ReflectionClass($definition->getClass()); + + // check if class is matched + $matchingPointcuts = array(); + foreach ($pointcuts as $interceptor => $pointcut) { + if ($pointcut->matchesClass($class)) { + $matchingPointcuts[$interceptor] = $pointcut; + } + } + + if (empty($matchingPointcuts)) { + return; + } + + $this->addResources($class, $this->container); + + if ($class->isFinal()) { + return; + } + + $classAdvices = array(); + foreach ($class->getMethods(\ReflectionMethod::IS_PROTECTED | \ReflectionMethod::IS_PUBLIC) as $method) { + if ($method->isFinal()) { + continue; + } + + $advices = array(); + foreach ($matchingPointcuts as $interceptor => $pointcut) { + if ($pointcut->matchesMethod($method)) { + $advices[] = $interceptor; + } + } + + if (empty($advices)) { + continue; + } + + $classAdvices[$method->name] = $advices; + } + + if (empty($classAdvices)) { + return; + } + + $interceptors[ClassUtils::getUserClass($class->name)] = $classAdvices; + + $generator = new InterceptionGenerator(); + $generator->setFilter(function(\ReflectionMethod $method) use ($classAdvices) { + return isset($classAdvices[$method->name]); + }); + if ($file) { + $generator->setRequiredFile($file); + } + $enhancer = new Enhancer($class, array(), array( + $generator + )); + $enhancer->writeClass($filename = $this->cacheDir.'/'.str_replace('\\', '-', $class->name).'.php'); + $definition->setFile($filename); + $definition->setClass($enhancer->getClassName($class)); + $definition->addMethodCall('__CGInterception__setLoader', array( + new Reference('jms_aop.interceptor_loader') + )); + } + + private function addResources(\ReflectionClass $class) + { + do { + $this->container->addResource(new FileResource($class->getFilename())); + } while (($class = $class->getParentClass()) && $class->getFilename()); + } + + private function getPointcuts() + { + if (null !== $this->pointcuts) { + return $this->pointcuts; + } + + $pointcuts = $pointcutReferences = array(); + + foreach ($this->container->findTaggedServiceIds('jms_aop.pointcut') as $id => $attr) { + if (!isset($attr[0]['interceptor'])) { + throw new RuntimeException('You need to set the "interceptor" attribute for the "jms_aop.pointcut" tag of service "'.$id.'".'); + } + + $pointcutReferences[$attr[0]['interceptor']] = new Reference($id); + $pointcuts[$attr[0]['interceptor']] = $this->container->get($id); + } + + $this->container + ->getDefinition('jms_aop.pointcut_container') + ->addArgument($pointcutReferences) + ; + + return $pointcuts; + } +} diff --git a/vendor/jms/aop-bundle/JMS/AopBundle/DependencyInjection/Configuration.php b/vendor/jms/aop-bundle/JMS/AopBundle/DependencyInjection/Configuration.php new file mode 100644 index 0000000..947cdf5 --- /dev/null +++ b/vendor/jms/aop-bundle/JMS/AopBundle/DependencyInjection/Configuration.php @@ -0,0 +1,45 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\AopBundle\DependencyInjection; + +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; + +/** + * This is the class that validates and merges configuration from your app/config files + * + * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class} + */ +class Configuration implements ConfigurationInterface +{ + /** + * {@inheritDoc} + */ + public function getConfigTreeBuilder() + { + $treeBuilder = new TreeBuilder(); + $treeBuilder->root('jms_aop') + ->children() + ->scalarNode('cache_dir')->cannotBeEmpty()->defaultValue('%kernel.cache_dir%/jms_aop')->end() + ->end() + ; + + return $treeBuilder; + } +} diff --git a/vendor/jms/aop-bundle/JMS/AopBundle/DependencyInjection/JMSAopExtension.php b/vendor/jms/aop-bundle/JMS/AopBundle/DependencyInjection/JMSAopExtension.php new file mode 100644 index 0000000..6f9a1e3 --- /dev/null +++ b/vendor/jms/aop-bundle/JMS/AopBundle/DependencyInjection/JMSAopExtension.php @@ -0,0 +1,53 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\AopBundle\DependencyInjection; + +use JMS\AopBundle\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use Symfony\Component\DependencyInjection\Loader; + +/** + * JMSAopExtension. + * + * @author Johannes M. Schmitt + */ +class JMSAopExtension extends Extension +{ + /** + * {@inheritDoc} + */ + public function load(array $configs, ContainerBuilder $container) + { + $configuration = new Configuration(); + $config = $this->processConfiguration($configuration, $configs); + + $cacheDir = $container->getParameterBag()->resolveValue($config['cache_dir']); + if (!is_dir($cacheDir)) { + if (false === @mkdir($cacheDir, 0777, true)) { + throw new RuntimeException(sprintf('Could not create cache directory "%s".', $cacheDir)); + } + } + $container->setParameter('jms_aop.cache_dir', $cacheDir); + + $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('services.xml'); + } +} diff --git a/vendor/jms/aop-bundle/JMS/AopBundle/Exception/Exception.php b/vendor/jms/aop-bundle/JMS/AopBundle/Exception/Exception.php new file mode 100644 index 0000000..1cbc27e --- /dev/null +++ b/vendor/jms/aop-bundle/JMS/AopBundle/Exception/Exception.php @@ -0,0 +1,28 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\AopBundle\Exception; + +/** + * Base exception for the AopBundle. + * + * @author Johannes M. Schmitt + */ +interface Exception +{ +} \ No newline at end of file diff --git a/vendor/jms/aop-bundle/JMS/AopBundle/Exception/RuntimeException.php b/vendor/jms/aop-bundle/JMS/AopBundle/Exception/RuntimeException.php new file mode 100644 index 0000000..02a0db4 --- /dev/null +++ b/vendor/jms/aop-bundle/JMS/AopBundle/Exception/RuntimeException.php @@ -0,0 +1,28 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\AopBundle\Exception; + +/** + * RuntimeException for the AopBundle. + * + * @author Johannes M. Schmitt + */ +class RuntimeException extends \RuntimeException implements Exception +{ +} \ No newline at end of file diff --git a/vendor/jms/aop-bundle/JMS/AopBundle/JMSAopBundle.php b/vendor/jms/aop-bundle/JMS/AopBundle/JMSAopBundle.php new file mode 100644 index 0000000..dbd6b8b --- /dev/null +++ b/vendor/jms/aop-bundle/JMS/AopBundle/JMSAopBundle.php @@ -0,0 +1,34 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\AopBundle; + +use Symfony\Component\DependencyInjection\Compiler\PassConfig; +use JMS\AopBundle\DependencyInjection\Compiler\PointcutMatchingPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class JMSAopBundle extends Bundle +{ + const VERSION = '1.0.0'; + + public function build(ContainerBuilder $container) + { + $container->addCompilerPass(new PointcutMatchingPass(), PassConfig::TYPE_AFTER_REMOVING); + } +} diff --git a/vendor/jms/aop-bundle/JMS/AopBundle/README b/vendor/jms/aop-bundle/JMS/AopBundle/README new file mode 100644 index 0000000..72bab21 --- /dev/null +++ b/vendor/jms/aop-bundle/JMS/AopBundle/README @@ -0,0 +1,8 @@ +For documentation, see: + + Resources/doc + + +For license, see: + + Resources/meta/LICENSE \ No newline at end of file diff --git a/vendor/jms/aop-bundle/JMS/AopBundle/Resources/config/services.xml b/vendor/jms/aop-bundle/JMS/AopBundle/Resources/config/services.xml new file mode 100644 index 0000000..c1caed4 --- /dev/null +++ b/vendor/jms/aop-bundle/JMS/AopBundle/Resources/config/services.xml @@ -0,0 +1,18 @@ + + + + + + JMS\AopBundle\Aop\InterceptorLoader + + + + + + + + + + diff --git a/vendor/jms/aop-bundle/JMS/AopBundle/Resources/doc/index.rst b/vendor/jms/aop-bundle/JMS/AopBundle/Resources/doc/index.rst new file mode 100644 index 0000000..e637fb0 --- /dev/null +++ b/vendor/jms/aop-bundle/JMS/AopBundle/Resources/doc/index.rst @@ -0,0 +1,252 @@ +======== +Overview +======== + +This bundle adds AOP capabilities to Symfony2. + +If you haven't heard of AOP yet, it basically allows you to separate a +cross-cutting concern (for example, security checks) into a dedicated class, +and not having to repeat that code in all places where it is needed. + +In other words, this allows you to execute custom code before, and after the +invocation of certain methods in your service layer, or your controllers. You +can also choose to skip the invocation of the original method, or throw exceptions. + +Installation +------------ +Checkout a copy of the code:: + + git submodule add https://github.com/schmittjoh/JMSAopBundle.git src/JMS/AopBundle + +Then register the bundle with your kernel:: + + // in AppKernel::registerBundles() + $bundles = array( + // ... + new JMS\AopBundle\JMSAopBundle(), + // ... + ); + +This bundle also requires the CG library for code generation:: + + git submodule add https://github.com/schmittjoh/cg-library.git vendor/cg-library + +Make sure that you also register the namespaces with the autoloader:: + + // app/autoload.php + $loader->registerNamespaces(array( + // ... + 'JMS' => __DIR__.'/../vendor/bundles', + 'CG' => __DIR__.'/../vendor/cg-library/src', + // ... + )); + + +Configuration +------------- +:: + + jms_aop: + cache_dir: %kernel.cache_dir%/jms_aop + + +Usage +----- +In order to execute custom code, you need two classes. First, you need a so-called +pointcut. The purpose of this class is to make a decision whether a method call +should be intercepted by a certain interceptor. This decision has to be made +statically only on the basis of the method signature itself. + +The second class is the interceptor. This class is being called instead +of the original method. It contains the custom code that you would like to +execute. At this point, you have access to the object on which the method is +called, and all the arguments which were passed to that method. + +Examples +-------- + +1. Logging +~~~~~~~~~~ + +In this example, we will be implementing logging for all methods that contain +"delete". + +Pointcut +^^^^^^^^ + +:: + + name, 'delete'); + } + } + +:: + + # services.yml + services: + my_logging_pointcut: + class: LoggingPointcut + tags: + - { name: jms_aop.pointcut, interceptor: logging_interceptor } + + +LoggingInterceptor +^^^^^^^^^^^^^^^^^^ + +:: + + context = $context; + $this->logger = $logger; + } + + public function intercept(MethodInvocation $invocation) + { + $user = $this->context->getToken()->getUsername(); + $this->logger->info(sprintf('User "%s" invoked method "%s".', $user, $invocation->reflection->name)); + + // make sure to proceed with the invocation otherwise the original + // method will never be called + return $invocation->proceed(); + } + } + +:: + + # services.yml + services: + logging_interceptor: + class: LoggingInterceptor + arguments: [@security.context, @logger] + + +2. Transaction Management +~~~~~~~~~~~~~~~~~~~~~~~~~ + +In this example, we add a @Transactional annotation, and we automatically wrap all methods +where this annotation is declared in a transaction. + +Pointcut +^^^^^^^^ + +:: + + use Doctrine\Common\Annotations\Reader; + use JMS\AopBundle\Aop\PointcutInterface; + use JMS\DiExtraBundle\Annotation as DI; + + /** + * @DI\Service + * @DI\Tag("jms_aop.pointcut", attributes = {"interceptor" = "aop.transactional_interceptor"}) + * + * @author Johannes M. Schmitt + */ + class TransactionalPointcut implements PointcutInterface + { + private $reader; + + /** + * @DI\InjectParams({ + * "reader" = @DI\Inject("annotation_reader"), + * }) + * @param Reader $reader + */ + public function __construct(Reader $reader) + { + $this->reader = $reader; + } + + public function matchesClass(\ReflectionClass $class) + { + return true; + } + + public function matchesMethod(\ReflectionMethod $method) + { + return null !== $this->reader->getMethodAnnotation($method, 'Annotation\Transactional'); + } + } + +Interceptor +^^^^^^^^^^^ + +:: + + use Symfony\Component\HttpKernel\Log\LoggerInterface; + use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; + use CG\Proxy\MethodInvocation; + use CG\Proxy\MethodInterceptorInterface; + use Doctrine\ORM\EntityManager; + use JMS\DiExtraBundle\Annotation as DI; + + /** + * @DI\Service("aop.transactional_interceptor") + * + * @author Johannes M. Schmitt + */ + class TransactionalInterceptor implements MethodInterceptorInterface + { + private $em; + private $logger; + + /** + * @DI\InjectParams + * @param EntityManager $em + */ + public function __construct(EntityManager $em, LoggerInterface $logger) + { + $this->em = $em; + $this->logger = $logger; + } + + public function intercept(MethodInvocation $invocation) + { + $this->logger->info('Beginning transaction for method "'.$invocation.'")'); + $this->em->getConnection()->beginTransaction(); + try { + $rs = $invocation->proceed(); + + $this->logger->info(sprintf('Comitting transaction for method "%s" (method invocation successful)', $invocation)); + $this->em->getConnection()->commit(); + + return $rs; + } catch (\Exception $ex) { + if ($ex instanceof NotFoundHttpException) { + $this->logger->info(sprintf('Committing transaction for method "%s" (exception thrown, but no rollback)', $invocation)); + $this->em->getConnection()->commit(); + } else { + $this->logger->info(sprintf('Rolling back transaction for method "%s" (exception thrown)', $invocation)); + $this->em->getConnection()->rollBack(); + } + + throw $ex; + } + } + } diff --git a/vendor/jms/aop-bundle/JMS/AopBundle/Resources/meta/LICENSE b/vendor/jms/aop-bundle/JMS/AopBundle/Resources/meta/LICENSE new file mode 100644 index 0000000..753842b --- /dev/null +++ b/vendor/jms/aop-bundle/JMS/AopBundle/Resources/meta/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/vendor/jms/aop-bundle/JMS/AopBundle/composer.json b/vendor/jms/aop-bundle/JMS/AopBundle/composer.json new file mode 100644 index 0000000..1fe7e80 --- /dev/null +++ b/vendor/jms/aop-bundle/JMS/AopBundle/composer.json @@ -0,0 +1,21 @@ +{ + "name": "jms/aop-bundle", + "description": "Adds AOP capabilities to Symfony2", + "keywords": ["annotations","aop"], + "type": "symfony-bundle", + "license": "Apache", + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "require": { + "symfony/framework-bundle": "2.*", + "jms/cg": "1.0.0" + }, + "autoload": { + "psr-0": { "JMS\\AopBundle": "" } + }, + "target-dir": "JMS/AopBundle" +} diff --git a/vendor/jms/cg/LICENSE b/vendor/jms/cg/LICENSE new file mode 100644 index 0000000..f49a4e1 --- /dev/null +++ b/vendor/jms/cg/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/vendor/jms/cg/composer.json b/vendor/jms/cg/composer.json new file mode 100644 index 0000000..edb5eec --- /dev/null +++ b/vendor/jms/cg/composer.json @@ -0,0 +1,19 @@ +{ + "name": "jms/cg", + "description": "Toolset for generating PHP code", + "keywords": ["code generation"], + "type": "library", + "license": "Apache", + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "require": { + "php": ">=5.3.0" + }, + "autoload": { + "psr-0": { "CG\\": "src/" } + } +} diff --git a/vendor/jms/cg/src/CG/Core/AbstractClassGenerator.php b/vendor/jms/cg/src/CG/Core/AbstractClassGenerator.php new file mode 100644 index 0000000..203d9ba --- /dev/null +++ b/vendor/jms/cg/src/CG/Core/AbstractClassGenerator.php @@ -0,0 +1,60 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Core; + +use CG\Generator\PhpClass; + +/** + * Abstract base class for all class generators. + * + * @author Johannes M. Schmitt + */ +abstract class AbstractClassGenerator implements ClassGeneratorInterface +{ + private $namingStrategy; + private $generatorStrategy; + + public function setNamingStrategy(NamingStrategyInterface $namingStrategy = null) + { + $this->namingStrategy = $namingStrategy; + } + + public function setGeneratorStrategy(GeneratorStrategyInterface $generatorStrategy = null) + { + $this->generatorStrategy = $generatorStrategy; + } + + public function getClassName(\ReflectionClass $class) + { + if (null === $this->namingStrategy) { + $this->namingStrategy = new DefaultNamingStrategy(); + } + + return $this->namingStrategy->getClassName($class); + } + + protected function generateCode(PhpClass $class) + { + if (null === $this->generatorStrategy) { + $this->generatorStrategy = new DefaultGeneratorStrategy(); + } + + return $this->generatorStrategy->generate($class); + } +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Core/ClassGeneratorInterface.php b/vendor/jms/cg/src/CG/Core/ClassGeneratorInterface.php new file mode 100644 index 0000000..93ca18f --- /dev/null +++ b/vendor/jms/cg/src/CG/Core/ClassGeneratorInterface.php @@ -0,0 +1,36 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Core; + +use CG\Generator\PhpClass; + +/** + * Interface for class generators. + * + * @author Johannes M. Schmitt + */ +interface ClassGeneratorInterface +{ + /** + * Generates the PHP class. + * + * @return string + */ + function generateClass(); +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Core/ClassUtils.php b/vendor/jms/cg/src/CG/Core/ClassUtils.php new file mode 100644 index 0000000..3e33bd5 --- /dev/null +++ b/vendor/jms/cg/src/CG/Core/ClassUtils.php @@ -0,0 +1,35 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Core; + +use CG\Proxy\Enhancer; + +abstract class ClassUtils +{ + public static function getUserClass($className) + { + if (false === $pos = strrpos($className, '\\'.NamingStrategyInterface::SEPARATOR.'\\')) { + return $className; + } + + return substr($className, $pos + NamingStrategyInterface::SEPARATOR_LENGTH + 2); + } + + private final function __construct() {} +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Core/DefaultGeneratorStrategy.php b/vendor/jms/cg/src/CG/Core/DefaultGeneratorStrategy.php new file mode 100644 index 0000000..28b60bf --- /dev/null +++ b/vendor/jms/cg/src/CG/Core/DefaultGeneratorStrategy.php @@ -0,0 +1,67 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Core; + +use CG\Generator\DefaultVisitorInterface; +use CG\Generator\PhpClass; +use CG\Generator\DefaultVisitor; +use CG\Generator\DefaultNavigator; + +/** + * The default generator strategy. + * + * This strategy allows to change the order in which methods, properties and + * constants are sorted. + * + * @author Johannes M. Schmitt + */ +class DefaultGeneratorStrategy implements GeneratorStrategyInterface +{ + private $navigator; + private $visitor; + + public function __construct(DefaultVisitorInterface $visitor = null) + { + $this->navigator = new DefaultNavigator(); + $this->visitor = $visitor ?: new DefaultVisitor(); + } + + public function setConstantSortFunc(\Closure $func = null) + { + $this->navigator->setConstantSortFunc($func); + } + + public function setMethodSortFunc(\Closure $func = null) + { + $this->navigator->setMethodSortFunc($func); + } + + public function setPropertySortFunc(\Closure $func = null) + { + $this->navigator->setPropertySortFunc($func); + } + + public function generate(PhpClass $class) + { + $this->visitor->reset(); + $this->navigator->accept($this->visitor, $class); + + return $this->visitor->getContent(); + } +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Core/DefaultNamingStrategy.php b/vendor/jms/cg/src/CG/Core/DefaultNamingStrategy.php new file mode 100644 index 0000000..600c995 --- /dev/null +++ b/vendor/jms/cg/src/CG/Core/DefaultNamingStrategy.php @@ -0,0 +1,41 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Core; + +/** + * The default naming strategy. + * + * @author Johannes M. Schmitt + */ +class DefaultNamingStrategy implements NamingStrategyInterface +{ + private $prefix; + + public function __construct($prefix = 'EnhancedProxy') + { + $this->prefix = $prefix; + } + + public function getClassName(\ReflectionClass $class) + { + $userClass = ClassUtils::getUserClass($class->name); + + return $this->prefix.'_'.sha1($class->name).'\\'.self::SEPARATOR.'\\'.$userClass; + } +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Core/GeneratorStrategyInterface.php b/vendor/jms/cg/src/CG/Core/GeneratorStrategyInterface.php new file mode 100644 index 0000000..2468bc1 --- /dev/null +++ b/vendor/jms/cg/src/CG/Core/GeneratorStrategyInterface.php @@ -0,0 +1,34 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Core; + +use CG\Generator\PhpClass; + +/** + * Generator Strategy Interface. + * + * Implementing classes are responsible for generating PHP code from the given + * PhpClass instance. + * + * @author Johannes M. Schmitt + */ +interface GeneratorStrategyInterface +{ + function generate(PhpClass $class); +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Core/NamingStrategyInterface.php b/vendor/jms/cg/src/CG/Core/NamingStrategyInterface.php new file mode 100644 index 0000000..c7c03fa --- /dev/null +++ b/vendor/jms/cg/src/CG/Core/NamingStrategyInterface.php @@ -0,0 +1,50 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Core; + +/** + * The naming strategy interface. + * + * @author Johannes M. Schmitt + */ +interface NamingStrategyInterface +{ + const SEPARATOR = '__CG__'; + const SEPARATOR_LENGTH = 6; + + /** + * Returns the class name for the proxy class. + * + * The generated class name MUST be the concatenation of a nonempty prefix, + * the namespace separator __CG__, and the original class name. + * + * Examples: + * + * +----------------------------+------------------------------+ + * | Original Name | Generated Name | + * +============================+==============================+ + * | Foo\Bar | dred332\__CG__\Foo\Bar | + * | Bar\Baz | Foo\Doo\__CG__\Bar\Baz | + * +----------------------------+------------------------------+ + * + * @param \ReflectionClass $class + * @return string the class name for the generated class + */ + function getClassName(\ReflectionClass $class); +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Core/ReflectionUtils.php b/vendor/jms/cg/src/CG/Core/ReflectionUtils.php new file mode 100644 index 0000000..e7e9ea7 --- /dev/null +++ b/vendor/jms/cg/src/CG/Core/ReflectionUtils.php @@ -0,0 +1,57 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Core; + +abstract class ReflectionUtils +{ + public static function getOverrideableMethods(\ReflectionClass $class, $publicOnly = false) + { + $filter = \ReflectionMethod::IS_PUBLIC; + + if (!$publicOnly) { + $filter |= \ReflectionMethod::IS_PROTECTED; + } + + return array_filter( + $class->getMethods($filter), + function($method) { return !$method->isFinal() && !$method->isStatic(); } + ); + } + + public static function getUnindentedDocComment($docComment) + { + $lines = explode("\n", $docComment); + for ($i=0,$c=count($lines); $i<$c; $i++) { + if (0 === $i) { + $docBlock = $lines[0]."\n"; + continue; + } + + $docBlock .= ' '.ltrim($lines[$i]); + + if ($i+1 < $c) { + $docBlock .= "\n"; + } + } + + return $docBlock; + } + + private final function __construct() { } +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Generator/AbstractPhpMember.php b/vendor/jms/cg/src/CG/Generator/AbstractPhpMember.php new file mode 100644 index 0000000..5ae8aa4 --- /dev/null +++ b/vendor/jms/cg/src/CG/Generator/AbstractPhpMember.php @@ -0,0 +1,95 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Generator; + +/** + * Abstract PHP member class. + * + * @author Johannes M. Schmitt + */ +abstract class AbstractPhpMember +{ + const VISIBILITY_PRIVATE = 'private'; + const VISIBILITY_PROTECTED = 'protected'; + const VISIBILITY_PUBLIC = 'public'; + + private $static = false; + private $visibility = self::VISIBILITY_PUBLIC; + private $name; + private $docblock; + + public function __construct($name = null) + { + $this->setName($name); + } + + public function setName($name) + { + $this->name = $name; + + return $this; + } + + public function setVisibility($visibility) + { + if ($visibility !== self::VISIBILITY_PRIVATE + && $visibility !== self::VISIBILITY_PROTECTED + && $visibility !== self::VISIBILITY_PUBLIC) { + throw new \InvalidArgumentException(sprintf('The visibility "%s" does not exist.', $visibility)); + } + + $this->visibility = $visibility; + + return $this; + } + + public function setStatic($bool) + { + $this->static = (Boolean) $bool; + + return $this; + } + + public function setDocblock($doc) + { + $this->docblock = $doc; + + return $this; + } + + public function isStatic() + { + return $this->static; + } + + public function getVisibility() + { + return $this->visibility; + } + + public function getName() + { + return $this->name; + } + + public function getDocblock() + { + return $this->docblock; + } +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Generator/DefaultNavigator.php b/vendor/jms/cg/src/CG/Generator/DefaultNavigator.php new file mode 100644 index 0000000..3d46bb3 --- /dev/null +++ b/vendor/jms/cg/src/CG/Generator/DefaultNavigator.php @@ -0,0 +1,172 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Generator; + +/** + * The default navigator. + * + * This class is responsible for the default traversal algorithm of the different + * code elements. + * + * Unlike other visitor pattern implementations, this allows to separate the + * traversal logic from the objects that are traversed. + * + * @author Johannes M. Schmitt + */ +class DefaultNavigator +{ + private $constantSortFunc; + private $propertySortFunc; + private $methodSortFunc; + + /** + * Sets a custom constant sorting function. + * + * @param \Closure $func + */ + public function setConstantSortFunc(\Closure $func = null) + { + $this->constantSortFunc = $func; + } + + /** + * Sets a custom property sorting function. + * + * @param \Closure $func + */ + public function setPropertySortFunc(\Closure $func = null) + { + $this->propertySortFunc = $func; + } + + /** + * Sets a custom method sorting function. + * + * @param \Closure $func + */ + public function setMethodSortFunc(\Closure $func = null) + { + $this->methodSortFunc = $func; + } + + public function accept(DefaultVisitorInterface $visitor, PhpClass $class) + { + $visitor->startVisitingClass($class); + + $constants = $class->getConstants(); + if (!empty($constants)) { + uksort($constants, $this->getConstantSortFunc()); + + $visitor->startVisitingConstants(); + foreach ($constants as $name => $value) { + $visitor->visitConstant($name, $value); + } + $visitor->endVisitingConstants(); + } + + $properties = $class->getProperties(); + if (!empty($properties)) { + usort($properties, $this->getPropertySortFunc()); + + $visitor->startVisitingProperties(); + foreach ($properties as $property) { + $visitor->visitProperty($property); + } + $visitor->endVisitingProperties(); + } + + $methods = $class->getMethods(); + if (!empty($methods)) { + usort($methods, $this->getMethodSortFunc()); + + $visitor->startVisitingMethods(); + foreach ($methods as $method) { + $visitor->visitMethod($method); + } + $visitor->endVisitingMethods(); + } + + $visitor->endVisitingClass($class); + } + + private function getConstantSortFunc() + { + return $this->constantSortFunc ?: 'strcasecmp'; + } + + private function getMethodSortFunc() + { + if (null !== $this->methodSortFunc) { + return $this->methodSortFunc; + } + + static $defaultSortFunc; + if (empty($defaultSortFunc)) { + $defaultSortFunc = function($a, $b) { + if ($a->isStatic() !== $isStatic = $b->isStatic()) { + return $isStatic ? 1 : -1; + } + + if (($aV = $a->getVisibility()) !== $bV = $b->getVisibility()) { + $aV = 'public' === $aV ? 3 : ('protected' === $aV ? 2 : 1); + $bV = 'public' === $bV ? 3 : ('protected' === $bV ? 2 : 1); + + return $aV > $bV ? -1 : 1; + } + + $rs = strcasecmp($a->getName(), $b->getName()); + if (0 === $rs) { + return 0; + } + + return $rs > 0 ? -1 : 1; + }; + } + + return $defaultSortFunc; + } + + private function getPropertySortFunc() + { + if (null !== $this->propertySortFunc) { + return $this->propertySortFunc; + } + + static $defaultSortFunc; + if (empty($defaultSortFunc)) { + $defaultSortFunc = function($a, $b) { + if (($aV = $a->getVisibility()) !== $bV = $b->getVisibility()) { + $aV = 'public' === $aV ? 3 : ('protected' === $aV ? 2 : 1); + $bV = 'public' === $bV ? 3 : ('protected' === $bV ? 2 : 1); + + return $aV > $bV ? -1 : 1; + } + + $rs = strcasecmp($a->getName(), $b->getName()); + if (0 === $rs) { + return 0; + } + + return $rs > 0 ? -1 : 1; + }; + } + + return $defaultSortFunc; + } +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Generator/DefaultVisitor.php b/vendor/jms/cg/src/CG/Generator/DefaultVisitor.php new file mode 100644 index 0000000..5dd4094 --- /dev/null +++ b/vendor/jms/cg/src/CG/Generator/DefaultVisitor.php @@ -0,0 +1,237 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Generator; + +/** + * The default code generation visitor. + * + * @author Johannes M. Schmitt + */ +class DefaultVisitor implements DefaultVisitorInterface +{ + private $writer; + + public function __construct() + { + $this->writer = new Writer(); + } + + public function reset() + { + $this->writer->reset(); + } + + public function startVisitingClass(PhpClass $class) + { + if ($namespace = $class->getNamespace()) { + $this->writer->write('namespace '.$namespace.';'."\n\n"); + } + + if ($files = $class->getRequiredFiles()) { + foreach ($files as $file) { + $this->writer->writeln('require_once '.var_export($file, true).';'); + } + + $this->writer->write("\n"); + } + + if ($useStatements = $class->getUseStatements()) { + foreach ($useStatements as $alias => $namespace) { + $this->writer->write('use '.$namespace); + + if (substr($namespace, strrpos($namespace, '\\') + 1) !== $alias) { + $this->writer->write(' as '.$alias); + } + + $this->writer->write(";\n"); + } + + $this->writer->write("\n"); + } + + if ($docblock = $class->getDocblock()) { + $this->writer->write($docblock); + } + + $this->writer->write('class '.$class->getShortName()); + + if ($parentClassName = $class->getParentClassName()) { + $this->writer->write(' extends '.('\\' === $parentClassName[0] ? $parentClassName : '\\'.$parentClassName)); + } + + $interfaceNames = $class->getInterfaceNames(); + if (!empty($interfaceNames)) { + $interfaceNames = array_unique($interfaceNames); + + $interfaceNames = array_map(function($name) { + if ('\\' === $name[0]) { + return $name; + } + + return '\\'.$name; + }, $interfaceNames); + + $this->writer->write(' implements '.implode(', ', $interfaceNames)); + } + + $this->writer + ->write("\n{\n") + ->indent() + ; + } + + public function startVisitingConstants() + { + } + + public function visitConstant($name, $value) + { + $this->writer->writeln('const '.$name.' = '.var_export($value, true).';'); + } + + public function endVisitingConstants() + { + $this->writer->write("\n"); + } + + public function startVisitingProperties() + { + } + + public function visitProperty(PhpProperty $property) + { + $this->writer->write($property->getVisibility().' '.($property->isStatic()? 'static ' : '').'$'.$property->getName()); + + if ($property->hasDefaultValue()) { + $this->writer->write(' = '.var_export($property->getDefaultValue(), true)); + } + + $this->writer->writeln(';'); + } + + public function endVisitingProperties() + { + $this->writer->write("\n"); + } + + public function startVisitingMethods() + { + } + + public function visitMethod(PhpMethod $method) + { + if ($docblock = $method->getDocblock()) { + $this->writer->writeln($docblock)->rtrim(); + } + + if ($method->isAbstract()) { + $this->writer->write('abstract '); + } + + $this->writer->write($method->getVisibility().' '); + + if ($method->isStatic()) { + $this->writer->write('static '); + } + + $this->writer->write('function '.$method->getName().'('); + + $this->writeParameters($method->getParameters()); + + if ($method->isAbstract()) { + $this->writer->write(");\n\n"); + + return; + } + + $this->writer + ->writeln(")") + ->writeln('{') + ->indent() + ->writeln($method->getBody()) + ->outdent() + ->rtrim() + ->write("}\n\n") + ; + } + + public function endVisitingMethods() + { + } + + public function endVisitingClass(PhpClass $class) + { + $this->writer + ->outdent() + ->rtrim() + ->write('}') + ; + } + + public function visitFunction(PhpFunction $function) + { + if ($namespace = $function->getNamespace()) { + $this->writer->write("namespace $namespace;\n\n"); + } + + $this->writer->write("function {$function->getName()}("); + $this->writeParameters($function->getParameters()); + $this->writer + ->write(")\n{\n") + ->indent() + ->writeln($function->getBody()) + ->outdent() + ->rtrim() + ->write('}') + ; + } + + public function getContent() + { + return $this->writer->getContent(); + } + + private function writeParameters(array $parameters) + { + $first = true; + foreach ($parameters as $parameter) { + if (!$first) { + $this->writer->write(', '); + } + $first = false; + + if ($type = $parameter->getType()) { + $this->writer->write( + ('array' === $type ? 'array' : ('\\' === $type[0] ? $type : '\\'. $type)) + .' ' + ); + } + + if ($parameter->isPassedByReference()) { + $this->writer->write('&'); + } + + $this->writer->write('$'.$parameter->getName()); + + if ($parameter->hasDefaultValue()) { + $this->writer->write(' = '.var_export($parameter->getDefaultValue(), true)); + } + } + } +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Generator/DefaultVisitorInterface.php b/vendor/jms/cg/src/CG/Generator/DefaultVisitorInterface.php new file mode 100644 index 0000000..d9532bb --- /dev/null +++ b/vendor/jms/cg/src/CG/Generator/DefaultVisitorInterface.php @@ -0,0 +1,47 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Generator; + +/** + * The visitor interface required by the DefaultNavigator. + * + * @author Johannes M. Schmitt + */ +interface DefaultVisitorInterface +{ + /** + * Resets the visitors internal state to allow re-using the same instance. + * + * @return void + */ + function reset(); + + function startVisitingClass(PhpClass $class); + function startVisitingConstants(); + function visitConstant($name, $value); + function endVisitingConstants(); + function startVisitingProperties(); + function visitProperty(PhpProperty $property); + function endVisitingProperties(); + function startVisitingMethods(); + function visitMethod(PhpMethod $method); + function endVisitingMethods(); + function endVisitingClass(PhpClass $class); + function visitFunction(PhpFunction $function); +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Generator/GeneratorUtils.php b/vendor/jms/cg/src/CG/Generator/GeneratorUtils.php new file mode 100644 index 0000000..8f7a44c --- /dev/null +++ b/vendor/jms/cg/src/CG/Generator/GeneratorUtils.php @@ -0,0 +1,38 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Generator; + +/** + * Some Generator utils. + * + * @author Johannes M. Schmitt + */ +abstract class GeneratorUtils +{ + private final function __construct() {} + + public static function callMethod(\ReflectionMethod $method, array $params = null) + { + if (null === $params) { + $params = array_map(function($p) { return '$'.$p->name; }, $method->getParameters()); + } + + return '\\'.$method->getDeclaringClass()->name.'::'.$method->name.'('.implode(', ', $params).')'; + } +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Generator/PhpClass.php b/vendor/jms/cg/src/CG/Generator/PhpClass.php new file mode 100644 index 0000000..e8496f0 --- /dev/null +++ b/vendor/jms/cg/src/CG/Generator/PhpClass.php @@ -0,0 +1,360 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Generator; + +use Doctrine\Common\Annotations\PhpParser; + +use CG\Core\ReflectionUtils; + +/** + * Represents a PHP class. + * + * @author Johannes M. Schmitt + */ +class PhpClass +{ + private static $phpParser; + + private $name; + private $parentClassName; + private $interfaceNames = array(); + private $useStatements = array(); + private $constants = array(); + private $properties = array(); + private $requiredFiles = array(); + private $methods = array(); + private $abstract = false; + private $final = false; + private $docblock; + + public static function create($name = null) + { + return new self($name); + } + + public static function fromReflection(\ReflectionClass $ref) + { + $class = new static(); + $class + ->setName($ref->name) + ->setAbstract($ref->isAbstract()) + ->setFinal($ref->isFinal()) + ->setConstants($ref->getConstants()) + ; + + if (null === self::$phpParser) { + if (!class_exists('Doctrine\Common\Annotations\PhpParser')) { + self::$phpParser = false; + } else { + self::$phpParser = new PhpParser(); + } + } + + if (false !== self::$phpParser) { + $class->setUseStatements(self::$phpParser->parseClass($ref)); + } + + if ($docComment = $ref->getDocComment()) { + $class->setDocblock(ReflectionUtils::getUnindentedDocComment($docComment)); + } + + foreach ($ref->getMethods() as $method) { + $class->setMethod(static::createMethod($method)); + } + + foreach ($ref->getProperties() as $property) { + $class->setProperty(static::createProperty($property)); + } + + return $class; + } + + protected static function createMethod(\ReflectionMethod $method) + { + return PhpMethod::fromReflection($method); + } + + protected static function createProperty(\ReflectionProperty $property) + { + return PhpProperty::fromReflection($property); + } + + public function __construct($name = null) + { + $this->name = $name; + } + + public function setName($name) + { + $this->name = $name; + + return $this; + } + + public function setParentClassName($name) + { + $this->parentClassName = $name; + + return $this; + } + + public function setInterfaceNames(array $names) + { + $this->interfaceNames = $names; + + return $this; + } + + public function addInterfaceName($name) + { + $this->interfaceNames[] = $name; + + return $this; + } + + public function setRequiredFiles(array $files) + { + $this->requiredFiles = $files; + + return $this; + } + + public function addRequiredFile($file) + { + $this->requiredFiles[] = $file; + + return $this; + } + + public function setUseStatements(array $useStatements) + { + $this->useStatements = $useStatements; + + return $this; + } + + public function addUseStatement($namespace, $alias = null) + { + if (null === $alias) { + $alias = substr($namespace, strrpos($namespace, '\\') + 1); + } + + $this->useStatements[$alias] = $namespace; + + return $this; + } + + public function setConstants(array $constants) + { + $this->constants = $constants; + + return $this; + } + + public function setConstant($name, $value) + { + $this->constants[$name] = $value; + + return $this; + } + + public function hasConstant($name) + { + return array_key_exists($this->constants, $name); + } + + public function removeConstant($name) + { + if (!array_key_exists($name, $this->constants)) { + throw new \InvalidArgumentException(sprintf('The constant "%s" does not exist.', $name)); + } + + unset($this->constants[$name]); + + return $this; + } + + public function setProperties(array $properties) + { + $this->properties = $properties; + + return $this; + } + + public function setProperty(PhpProperty $property) + { + $this->properties[$property->getName()] = $property; + + return $this; + } + + public function hasProperty($property) + { + if ($property instanceof PhpProperty) { + $property = $property->getName(); + } + + return isset($this->properties[$property]); + } + + public function removeProperty($property) + { + if ($property instanceof PhpProperty) { + $property = $property->getName(); + } + + if (!array_key_exists($property, $this->properties)) { + throw new \InvalidArgumentException(sprintf('The property "%s" does not exist.', $property)); + } + unset($this->properties[$property]); + + return $this; + } + + public function setMethods(array $methods) + { + $this->methods = $methods; + + return $this; + } + + public function setMethod(PhpMethod $method) + { + $this->methods[$method->getName()] = $method; + + return $this; + } + + public function hasMethod($method) + { + if ($method instanceof PhpMethod) { + $method = $method->getName(); + } + + return isset($this->methods[$method]); + } + + public function removeMethod($method) + { + if ($method instanceof PhpMethod) { + $method = $method->getName(); + } + + if (!array_key_exists($method, $this->methods)) { + throw new \InvalidArgumentException(sprintf('The method "%s" does not exist.', $method)); + } + unset($this->methods[$method]); + + return $this; + } + + public function setAbstract($bool) + { + $this->abstract = (Boolean) $bool; + + return $this; + } + + public function setFinal($bool) + { + $this->final = (Boolean) $bool; + + return $this; + } + + public function setDocblock($block) + { + $this->docblock = $block; + + return $this; + } + + public function getName() + { + return $this->name; + } + + public function getParentClassName() + { + return $this->parentClassName; + } + + public function getInterfaceNames() + { + return $this->interfaceNames; + } + + public function getRequiredFiles() + { + return $this->requiredFiles; + } + + public function getUseStatements() + { + return $this->useStatements; + } + + public function getNamespace() + { + if (false === $pos = strrpos($this->name, '\\')) { + return null; + } + + return substr($this->name, 0, $pos); + } + + public function getShortName() + { + if (false === $pos = strrpos($this->name, '\\')) { + return $this->name; + } + + return substr($this->name, $pos+1); + } + + public function getConstants() + { + return $this->constants; + } + + public function getProperties() + { + return $this->properties; + } + + public function getMethods() + { + return $this->methods; + } + + public function isAbstract() + { + return $this->abstract; + } + + public function isFinal() + { + return $this->final; + } + + public function getDocblock() + { + return $this->docblock; + } +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Generator/PhpFunction.php b/vendor/jms/cg/src/CG/Generator/PhpFunction.php new file mode 100644 index 0000000..2c14511 --- /dev/null +++ b/vendor/jms/cg/src/CG/Generator/PhpFunction.php @@ -0,0 +1,146 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Generator; + +/** + * Represents a PHP function. + * + * @author Johannes M. Schmitt + */ +class PhpFunction +{ + private $name; + private $namespace; + private $parameters = array(); + private $body = ''; + private $referenceReturned = false; + private $docblock; + + public static function create($name = null) + { + return new static($name); + } + + public function __construct($name = null) + { + $this->name = $name; + } + + public function setName($name) + { + $this->name = $name; + + return $this; + } + + public function setNamespace($namespace) + { + $this->namespace = $namespace; + + return $this; + } + + public function setParameters(array $parameters) + { + $this->parameters = $parameters; + + return $this; + } + + public function setReferenceReturned($bool) + { + $this->referenceReturned = (Boolean) $bool; + + return $this; + } + + public function replaceParameter($position, PhpParameter $parameter) + { + if ($position < 0 || $position > count($this->parameters)) { + throw new \InvalidArgumentException(sprintf('$position must be in the range [0, %d].', count($this->parameters))); + } + + $this->parameters[$position] = $parameter; + + return $this; + } + + public function addParameter(PhpParameter $parameter) + { + $this->parameters[] = $parameter; + + return $this; + } + + public function removeParameter($position) + { + if (!isset($this->parameters[$position])) { + throw new \InvalidArgumentException(sprintf('There is not parameter at position %d.', $position)); + } + + unset($this->parameters[$position]); + $this->parameters = array_values($this->parameters); + + return $this; + } + + public function setBody($body) + { + $this->body = $body; + + return $this; + } + + public function setDocblock($docBlock) + { + $this->docblock = $docBlock; + + return $this; + } + + public function getName() + { + return $this->name; + } + + public function getNamespace() + { + return $this->namespace; + } + + public function getParameters() + { + return $this->parameters; + } + + public function getBody() + { + return $this->body; + } + + public function getDocblock() + { + return $this->docblock; + } + + public function isReferenceReturned() + { + return $this->referenceReturned; + } +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Generator/PhpMethod.php b/vendor/jms/cg/src/CG/Generator/PhpMethod.php new file mode 100644 index 0000000..f8b7314 --- /dev/null +++ b/vendor/jms/cg/src/CG/Generator/PhpMethod.php @@ -0,0 +1,158 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Generator; + +use CG\Core\ReflectionUtils; + +/** + * Represents a PHP method. + * + * @author Johannes M. Schmitt + */ +class PhpMethod extends AbstractPhpMember +{ + private $final = false; + private $abstract = false; + private $parameters = array(); + private $referenceReturned = false; + private $body = ''; + + public static function create($name = null) + { + return new static($name); + } + + public static function fromReflection(\ReflectionMethod $ref) + { + $method = new static(); + $method + ->setFinal($ref->isFinal()) + ->setAbstract($ref->isAbstract()) + ->setStatic($ref->isStatic()) + ->setVisibility($ref->isPublic() ? self::VISIBILITY_PUBLIC : ($ref->isProtected() ? self::VISIBILITY_PROTECTED : self::VISIBILITY_PRIVATE)) + ->setReferenceReturned($ref->returnsReference()) + ->setName($ref->name) + ; + + if ($docComment = $ref->getDocComment()) { + $method->setDocblock(ReflectionUtils::getUnindentedDocComment($docComment)); + } + + foreach ($ref->getParameters() as $param) { + $method->addParameter(static::createParameter($param)); + } + + // FIXME: Extract body? + + return $method; + } + + protected static function createParameter(\ReflectionParameter $parameter) + { + return PhpParameter::fromReflection($parameter); + } + + public function setFinal($bool) + { + $this->final = (Boolean) $bool; + + return $this; + } + + public function setAbstract($bool) + { + $this->abstract = $bool; + + return $this; + } + + public function setReferenceReturned($bool) + { + $this->referenceReturned = (Boolean) $bool; + + return $this; + } + + public function setBody($body) + { + $this->body = $body; + + return $this; + } + + public function setParameters(array $parameters) + { + $this->parameters = array_values($parameters); + + return $this; + } + + public function addParameter(PhpParameter $parameter) + { + $this->parameters[] = $parameter; + + return $this; + } + + public function replaceParameter($position, PhpParameter $parameter) + { + if ($position < 0 || $position > strlen($this->parameters)) { + throw new \InvalidArgumentException(sprintf('The position must be in the range [0, %d].', strlen($this->parameters))); + } + $this->parameters[$position] = $parameter; + + return $this; + } + + public function removeParameter($position) + { + if (!isset($this->parameters[$position])) { + throw new \InvalidArgumentException(sprintf('There is no parameter at position "%d" does not exist.', $position)); + } + unset($this->parameters[$position]); + $this->parameters = array_values($this->parameters); + + return $this; + } + + public function isFinal() + { + return $this->final; + } + + public function isAbstract() + { + return $this->abstract; + } + + public function isReferenceReturned() + { + return $this->referenceReturned; + } + + public function getBody() + { + return $this->body; + } + + public function getParameters() + { + return $this->parameters; + } +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Generator/PhpParameter.php b/vendor/jms/cg/src/CG/Generator/PhpParameter.php new file mode 100644 index 0000000..0f8b2cb --- /dev/null +++ b/vendor/jms/cg/src/CG/Generator/PhpParameter.php @@ -0,0 +1,126 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Generator; + +/** + * Represents a PHP parameter. + * + * @author Johannes M. Schmitt + */ +class PhpParameter +{ + private $name; + private $defaultValue; + private $hasDefaultValue = false; + private $passedByReference = false; + private $type; + + public static function create($name = null) + { + return new static($name); + } + + public static function fromReflection(\ReflectionParameter $ref) + { + $parameter = new static(); + $parameter + ->setName($ref->name) + ->setPassedByReference($ref->isPassedByReference()) + ; + + if ($ref->isDefaultValueAvailable()) { + $parameter->setDefaultValue($ref->getDefaultValue()); + } + + if ($ref->isArray()) { + $parameter->setType('array'); + } else if ($class = $ref->getClass()) { + $parameter->setType($class->name); + } + + return $parameter; + } + + public function __construct($name = null) + { + $this->name = $name; + } + + public function setName($name) + { + $this->name = $name; + + return $this; + } + + public function setDefaultValue($value) + { + $this->defaultValue = $value; + $this->hasDefaultValue = true; + + return $this; + } + + public function unsetDefaultValue() + { + $this->defaultValue = null; + $this->hasDefaultValue = false; + + return $this; + } + + public function setPassedByReference($bool) + { + $this->passedByReference = (Boolean) $bool; + + return $this; + } + + public function setType($type) + { + $this->type = $type; + + return $this; + } + + public function getName() + { + return $this->name; + } + + public function getDefaultValue() + { + return $this->defaultValue; + } + + public function hasDefaultValue() + { + return $this->hasDefaultValue; + } + + public function isPassedByReference() + { + return $this->passedByReference; + } + + public function getType() + { + return $this->type; + } +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Generator/PhpProperty.php b/vendor/jms/cg/src/CG/Generator/PhpProperty.php new file mode 100644 index 0000000..a5b33d8 --- /dev/null +++ b/vendor/jms/cg/src/CG/Generator/PhpProperty.php @@ -0,0 +1,84 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Generator; + +use CG\Core\ReflectionUtils; + +/** + * Represents a PHP property. + * + * @author Johannes M. Schmitt + */ +class PhpProperty extends AbstractPhpMember +{ + private $hasDefaultValue = false; + private $defaultValue; + + public static function create($name = null) + { + return new static($name); + } + + public static function fromReflection(\ReflectionProperty $ref) + { + $property = new static(); + $property + ->setName($ref->name) + ->setStatic($ref->isStatic()) + ->setVisibility($ref->isPublic() ? self::VISIBILITY_PUBLIC : ($ref->isProtected() ? self::VISIBILITY_PROTECTED : self::VISIBILITY_PRIVATE)) + ; + + if ($docComment = $ref->getDocComment()) { + $property->setDocblock(ReflectionUtils::getUnindentedDocComment($docComment)); + } + + $defaultProperties = $ref->getDeclaringClass()->getDefaultProperties(); + if (isset($defaultProperties[$ref->name])) { + $property->setDefaultValue($defaultProperties[$ref->name]); + } + + return $property; + } + + public function setDefaultValue($value) + { + $this->defaultValue = $value; + $this->hasDefaultValue = true; + + return $this; + } + + public function unsetDefaultValue() + { + $this->hasDefaultValue = false; + $this->defaultValue = null; + + return $this; + } + + public function hasDefaultValue() + { + return $this->hasDefaultValue; + } + + public function getDefaultValue() + { + return $this->defaultValue; + } +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Generator/Writer.php b/vendor/jms/cg/src/CG/Generator/Writer.php new file mode 100644 index 0000000..29ca853 --- /dev/null +++ b/vendor/jms/cg/src/CG/Generator/Writer.php @@ -0,0 +1,103 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Generator; + +/** + * A writer implementation. + * + * This may be used to simplify writing well-formatted code. + * + * @author Johannes M. Schmitt + */ +class Writer +{ + private $content = ''; + private $indentationSpaces = 4; + private $indentationLevel = 0; + + public function indent() + { + $this->indentationLevel += 1; + + return $this; + } + + public function outdent() + { + $this->indentationLevel -= 1; + + if ($this->indentationLevel < 0) { + throw new \RuntimeException('The identation level cannot be less than zero.'); + } + + return $this; + } + + public function writeln($content) + { + $this->write($content."\n"); + + return $this; + } + + public function write($content) + { + $lines = explode("\n", $content); + for ($i=0,$c=count($lines); $i<$c; $i++) { + if ($this->indentationLevel > 0 + && !empty($lines[$i]) + && (empty($this->content) || "\n" === substr($this->content, -1))) { + $this->content .= str_repeat(' ', $this->indentationLevel * $this->indentationSpaces); + } + + $this->content .= $lines[$i]; + + if ($i+1 < $c) { + $this->content .= "\n"; + } + } + + return $this; + } + + public function rtrim() + { + $addNl = "\n" === substr($this->content, -1); + $this->content = rtrim($this->content); + + if ($addNl) { + $this->content .= "\n"; + } + + return $this; + } + + public function reset() + { + $this->content = ''; + $this->indentationLevel = 0; + + return $this; + } + + public function getContent() + { + return $this->content; + } +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Proxy/Enhancer.php b/vendor/jms/cg/src/CG/Proxy/Enhancer.php new file mode 100644 index 0000000..2ba73ed --- /dev/null +++ b/vendor/jms/cg/src/CG/Proxy/Enhancer.php @@ -0,0 +1,158 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Proxy; + +use CG\Core\NamingStrategyInterface; + +use CG\Generator\Writer; +use CG\Generator\PhpMethod; +use CG\Generator\PhpDocblock; +use CG\Generator\PhpClass; +use CG\Core\AbstractClassGenerator; + +/** + * Class enhancing generator implementation. + * + * This class enhances existing classes by generating a proxy and leveraging + * different generator implementation. + * + * There are several built-in generator such as lazy-initializing objects, or + * a generator for creating AOP joinpoints. + * + * @author Johannes M. Schmitt + */ +class Enhancer extends AbstractClassGenerator +{ + private $generatedClass; + private $class; + private $interfaces; + private $generators; + + public function __construct(\ReflectionClass $class, array $interfaces = array(), array $generators = array()) + { + if (empty($generators) && empty($interfaces)) { + throw new \RuntimeException('Either generators, or interfaces must be given.'); + } + + $this->class = $class; + $this->interfaces = $interfaces; + $this->generators = $generators; + } + + /** + * Creates a new instance of the enhanced class. + * + * @param array $args + * @return object + */ + public function createInstance(array $args = array()) + { + $generatedClass = $this->getClassName($this->class); + + if (!class_exists($generatedClass, false)) { + eval($this->generateClass()); + } + + $ref = new \ReflectionClass($generatedClass); + + return $ref->newInstanceArgs($args); + } + + public function writeClass($filename) + { + if (!is_dir($dir = dirname($filename))) { + if (false === @mkdir($dir, 0777, true)) { + throw new \RuntimeException(sprintf('Could not create directory "%s".', $dir)); + } + } + + if (!is_writable($dir)) { + throw new \RuntimeException(sprintf('The directory "%s" is not writable.', $dir)); + } + + file_put_contents($filename, "generateClass()); + } + + /** + * Creates a new enhanced class + * + * @return string + */ + public final function generateClass() + { + static $docBlock; + if (empty($docBlock)) { + $writer = new Writer(); + $writer + ->writeln('/**') + ->writeln(' * CG library enhanced proxy class.') + ->writeln(' *') + ->writeln(' * This code was generated automatically by the CG library, manual changes to it') + ->writeln(' * will be lost upon next generation.') + ->writeln(' */') + ; + $docBlock = $writer->getContent(); + } + + $this->generatedClass = PhpClass::create() + ->setDocblock($docBlock) + ->setParentClassName($this->class->name) + ; + + $proxyClassName = $this->getClassName($this->class); + if (false === strpos($proxyClassName, NamingStrategyInterface::SEPARATOR)) { + throw new \RuntimeException(sprintf('The proxy class name must be suffixed with "%s" and an optional string, but got "%s".', NamingStrategyInterface::SEPARATOR, $proxyClassName)); + } + $this->generatedClass->setName($proxyClassName); + + if (!empty($this->interfaces)) { + $this->generatedClass->setInterfaceNames(array_map(function($v) { return '\\'.$v; }, $this->interfaces)); + + foreach ($this->getInterfaceMethods() as $method) { + $method = PhpMethod::fromReflection($method); + $method->setAbstract(false); + + $this->generatedClass->setMethod($method); + } + } + + if (!empty($this->generators)) { + foreach ($this->generators as $generator) { + $generator->generate($this->class, $this->generatedClass); + } + } + + return $this->generateCode($this->generatedClass); + } + + /** + * Adds stub methods for the interfaces that have been implemented. + */ + protected function getInterfaceMethods() + { + $methods = array(); + + foreach ($this->interfaces as $interface) { + $ref = new \ReflectionClass($interface); + $methods = array_merge($methods, $ref->getMethods()); + } + + return $methods; + } +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Proxy/GeneratorInterface.php b/vendor/jms/cg/src/CG/Proxy/GeneratorInterface.php new file mode 100644 index 0000000..e641ec5 --- /dev/null +++ b/vendor/jms/cg/src/CG/Proxy/GeneratorInterface.php @@ -0,0 +1,38 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Proxy; + +use CG\Generator\PhpClass; + +/** + * Interface for enhancing generators. + * + * @author Johannes M. Schmitt + */ +interface GeneratorInterface +{ + /** + * Generates the necessary changes in the class. + * + * @param \ReflectionClass $originalClass + * @param PhpClass $generatedClass The generated class + * @return void + */ + function generate(\ReflectionClass $originalClass, PhpClass $generatedClass); +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Proxy/InterceptionGenerator.php b/vendor/jms/cg/src/CG/Proxy/InterceptionGenerator.php new file mode 100644 index 0000000..31a8ba6 --- /dev/null +++ b/vendor/jms/cg/src/CG/Proxy/InterceptionGenerator.php @@ -0,0 +1,117 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Proxy; + +use CG\Core\ClassUtils; + +use CG\Core\ReflectionUtils; + +use CG\Generator\PhpParameter; +use CG\Generator\PhpProperty; +use CG\Generator\PhpMethod; +use CG\Generator\PhpClass; + +/** + * Interception Generator. + * + * This generator creates joinpoints to allow for AOP advices. Right now, it only + * supports the most powerful around advice. + * + * @author Johannes M. Schmitt + */ +class InterceptionGenerator implements GeneratorInterface +{ + private $prefix = '__CGInterception__'; + private $filter; + private $requiredFile; + + public function setRequiredFile($file) + { + $this->requiredFile = $file; + } + + public function setPrefix($prefix) + { + $this->prefix = $prefix; + } + + public function setFilter(\Closure $filter) + { + $this->filter = $filter; + } + + public function generate(\ReflectionClass $originalClass, PhpClass $genClass) + { + $methods = ReflectionUtils::getOverrideableMethods($originalClass); + + if (null !== $this->filter) { + $methods = array_filter($methods, $this->filter); + } + + if (empty($methods)) { + return; + } + + if (!empty($this->requiredFile)) { + $genClass->addRequiredFile($this->requiredFile); + } + + $interceptorLoader = new PhpProperty(); + $interceptorLoader + ->setName($this->prefix.'loader') + ->setVisibility(PhpProperty::VISIBILITY_PRIVATE) + ; + $genClass->setProperty($interceptorLoader); + + $loaderSetter = new PhpMethod(); + $loaderSetter + ->setName($this->prefix.'setLoader') + ->setVisibility(PhpMethod::VISIBILITY_PUBLIC) + ->setBody('$this->'.$this->prefix.'loader = $loader;') + ; + $genClass->setMethod($loaderSetter); + $loaderParam = new PhpParameter(); + $loaderParam + ->setName('loader') + ->setType('CG\Proxy\InterceptorLoaderInterface') + ; + $loaderSetter->addParameter($loaderParam); + + $interceptorCode = + '$ref = new \ReflectionMethod(%s, %s);'."\n" + .'$interceptors = $this->'.$this->prefix.'loader->loadInterceptors($ref, $this, array(%s));'."\n" + .'$invocation = new \CG\Proxy\MethodInvocation($ref, $this, array(%s), $interceptors);'."\n\n" + .'return $invocation->proceed();' + ; + + foreach ($methods as $method) { + $params = array(); + foreach ($method->getParameters() as $param) { + $params[] = '$'.$param->name; + } + $params = implode(', ', $params); + + $genMethod = PhpMethod::fromReflection($method) + ->setBody(sprintf($interceptorCode, var_export(ClassUtils::getUserClass($method->class), true), var_export($method->name, true), $params, $params)) + ->setDocblock(null) + ; + $genClass->setMethod($genMethod); + } + } +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Proxy/InterceptorLoaderInterface.php b/vendor/jms/cg/src/CG/Proxy/InterceptorLoaderInterface.php new file mode 100644 index 0000000..5deff19 --- /dev/null +++ b/vendor/jms/cg/src/CG/Proxy/InterceptorLoaderInterface.php @@ -0,0 +1,38 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Proxy; + +/** + * Interception Loader. + * + * Implementations of this interface are responsible for loading the interceptors + * for a certain method. + * + * @author Johannes M. Schmitt + */ +interface InterceptorLoaderInterface +{ + /** + * Loads interceptors. + * + * @param \ReflectionMethod $method + * @return array + */ + function loadInterceptors(\ReflectionMethod $method); +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Proxy/LazyInitializerGenerator.php b/vendor/jms/cg/src/CG/Proxy/LazyInitializerGenerator.php new file mode 100644 index 0000000..8591599 --- /dev/null +++ b/vendor/jms/cg/src/CG/Proxy/LazyInitializerGenerator.php @@ -0,0 +1,153 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Proxy; + +use CG\Generator\Writer; +use CG\Core\ReflectionUtils; +use CG\Generator\GeneratorUtils; +use CG\Generator\PhpParameter; +use CG\Generator\PhpMethod; +use CG\Generator\PhpProperty; +use CG\Generator\PhpClass; + +/** + * Generator for creating lazy-initializing instances. + * + * This generator enhances concrete classes to allow for them to be lazily + * initialized upon first access. + * + * @author Johannes M. Schmitt + */ +class LazyInitializerGenerator implements GeneratorInterface +{ + private $writer; + private $prefix = '__CG__'; + private $markerInterface; + + public function __construct() + { + $this->writer = new Writer(); + } + + public function setPrefix($prefix) + { + $this->prefix = $prefix; + } + + /** + * Sets the marker interface which should be implemented by the + * generated classes. + * + * @param string $interface The FQCN of the interface + */ + public function setMarkerInterface($interface) + { + $this->markerInterface = $interface; + } + + /** + * Generates the necessary methods in the class. + * + * @param \ReflectionClass $originalClass + * @param PhpClass $class + * @return void + */ + public function generate(\ReflectionClass $originalClass, PhpClass $class) + { + $methods = ReflectionUtils::getOverrideableMethods($originalClass, true); + + // no public, non final methods + if (empty($methods)) { + return; + } + + if (null !== $this->markerInterface) { + $class->setImplementedInterfaces(array_merge( + $class->getImplementedInterfaces(), + array($this->markerInterface) + )); + } + + $initializer = new PhpProperty(); + $initializer->setName($this->prefix.'lazyInitializer'); + $initializer->setVisibility(PhpProperty::VISIBILITY_PRIVATE); + $class->setProperty($initializer); + + $initialized = new PhpProperty(); + $initialized->setName($this->prefix.'initialized'); + $initialized->setDefaultValue(false); + $initialized->setVisibility(PhpProperty::VISIBILITY_PRIVATE); + $class->setProperty($initialized); + + $initializerSetter = new PhpMethod(); + $initializerSetter->setName($this->prefix.'setLazyInitializer'); + $initializerSetter->setBody('$this->'.$this->prefix.'lazyInitializer = $initializer;'); + + $parameter = new PhpParameter(); + $parameter->setName('initializer'); + $parameter->setType('\CG\Proxy\LazyInitializerInterface'); + $initializerSetter->addParameter($parameter); + $class->setMethod($initializerSetter); + + $this->addMethods($class, $methods); + + $initializingMethod = new PhpMethod(); + $initializingMethod->setName($this->prefix.'initialize'); + $initializingMethod->setVisibility(PhpMethod::VISIBILITY_PRIVATE); + $initializingMethod->setBody( + $this->writer + ->reset() + ->writeln('if (null === $this->'.$this->prefix.'lazyInitializer) {') + ->indent() + ->writeln('throw new \RuntimeException("'.$this->prefix.'setLazyInitializer() must be called prior to any other public method on this object.");') + ->outdent() + ->write("}\n\n") + ->writeln('$this->'.$this->prefix.'lazyInitializer->initializeObject($this);') + ->writeln('$this->'.$this->prefix.'initialized = true;') + ->getContent() + ); + $class->setMethod($initializingMethod); + } + + private function addMethods(PhpClass $class, array $methods) + { + foreach ($methods as $method) { + $initializingCode = 'if (false === $this->'.$this->prefix.'initialized) {'."\n" + .' $this->'.$this->prefix.'initialize();'."\n" + .'}'; + + if ($class->hasMethod($method->name)) { + $genMethod = $class->getMethod($method->name); + $genMethod->setBody( + $initializingCode."\n" + .$genMethod->getBody() + ); + + continue; + } + + $genMethod = PhpMethod::fromReflection($method); + $genMethod->setBody( + $initializingCode."\n\n" + .'return '.GeneratorUtils::callMethod($method).';' + ); + $class->setMethod($genMethod); + } + } +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Proxy/LazyInitializerInterface.php b/vendor/jms/cg/src/CG/Proxy/LazyInitializerInterface.php new file mode 100644 index 0000000..7cfca5b --- /dev/null +++ b/vendor/jms/cg/src/CG/Proxy/LazyInitializerInterface.php @@ -0,0 +1,38 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Proxy; + +/** + * Lazy Initializer. + * + * Implementations of this interface are responsible for lazily initializing + * object instances. + * + * @author Johannes M. Schmitt + */ +interface LazyInitializerInterface +{ + /** + * Initializes the passed object. + * + * @param object $object + * @return void + */ + function initializeObject($object); +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Proxy/MethodInterceptorInterface.php b/vendor/jms/cg/src/CG/Proxy/MethodInterceptorInterface.php new file mode 100644 index 0000000..f1a7997 --- /dev/null +++ b/vendor/jms/cg/src/CG/Proxy/MethodInterceptorInterface.php @@ -0,0 +1,42 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Proxy; + +/** + * Interface for Method Interceptors. + * + * Implementations of this interface can execute custom code before, and after the + * invocation of the actual method. In addition, they can also catch, or throw + * exceptions, modify the return value, or modify the arguments. + * + * This is also known as around advice in AOP terminology. + * + * @author Johannes M. Schmitt + */ +interface MethodInterceptorInterface +{ + /** + * Called when intercepting a method call. + * + * @param MethodInvocation $invocation + * @return mixed the return value for the method invocation + * @throws \Exception may throw any exception + */ + function intercept(MethodInvocation $invocation); +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Proxy/MethodInvocation.php b/vendor/jms/cg/src/CG/Proxy/MethodInvocation.php new file mode 100644 index 0000000..11393f4 --- /dev/null +++ b/vendor/jms/cg/src/CG/Proxy/MethodInvocation.php @@ -0,0 +1,77 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Proxy; + +/** + * Represents a method invocation. + * + * This object contains information for the method invocation, such as the object + * on which the method is invoked, and the arguments that are passed to the method. + * + * Before the actual method is called, first all the interceptors must call the + * proceed() method on this class. + * + * @author Johannes M. Schmitt + */ +class MethodInvocation +{ + public $reflection; + public $object; + public $arguments; + + private $interceptors; + private $pointer; + + public function __construct(\ReflectionMethod $reflection, $object, array $arguments, array $interceptors) + { + $this->reflection = $reflection; + $this->object = $object; + $this->arguments = $arguments; + $this->interceptors = $interceptors; + $this->pointer = 0; + } + + /** + * Proceeds down the call-chain and eventually calls the original method. + * + * @return mixed + */ + public function proceed() + { + if (isset($this->interceptors[$this->pointer])) { + return $this->interceptors[$this->pointer++]->intercept($this); + } + + $this->reflection->setAccessible(true); + + return $this->reflection->invokeArgs($this->object, $this->arguments); + } + + /** + * Returns a string representation of the method. + * + * This is intended for debugging purposes only. + * + * @return string + */ + public function __toString() + { + return sprintf('%s::%s', $this->reflection->class, $this->reflection->name); + } +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Proxy/RegexInterceptionLoader.php b/vendor/jms/cg/src/CG/Proxy/RegexInterceptionLoader.php new file mode 100644 index 0000000..74a7c37 --- /dev/null +++ b/vendor/jms/cg/src/CG/Proxy/RegexInterceptionLoader.php @@ -0,0 +1,48 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace CG\Proxy; + +class RegexInterceptionLoader implements InterceptorLoaderInterface +{ + private $interceptors; + + public function __construct(array $interceptors = array()) + { + $this->interceptors = $interceptors; + } + + public function loadInterceptors(\ReflectionMethod $method) + { + $signature = $method->class.'::'.$method->name; + + $matchingInterceptors = array(); + foreach ($this->interceptors as $pattern => $interceptor) { + if (preg_match('#'.$pattern.'#', $signature)) { + $matchingInterceptors[] = $this->initializeInterceptor($interceptor); + } + } + + return $matchingInterceptors; + } + + protected function initializeInterceptor($interceptor) + { + return $interceptor; + } +} \ No newline at end of file diff --git a/vendor/jms/cg/src/CG/Version.php b/vendor/jms/cg/src/CG/Version.php new file mode 100644 index 0000000..0ca6842 --- /dev/null +++ b/vendor/jms/cg/src/CG/Version.php @@ -0,0 +1,8 @@ + + */ +final class AfterSetup +{ +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/DoctrineListener.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/DoctrineListener.php new file mode 100644 index 0000000..3a834f0 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/DoctrineListener.php @@ -0,0 +1,74 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Annotation; + +use JMS\DiExtraBundle\Exception\InvalidTypeException; + +/** + * @Annotation + * @Target("CLASS") + */ +class DoctrineListener +{ + /** @var array @Required */ + public $events; + + /** @var string */ + public $connection; + + /** @var boolean */ + public $lazy = true; + + /** @var integer */ + public $priority = 0; + + public function __construct() + { + if (0 === func_num_args()) { + return; + } + $values = func_get_arg(0); + + if (!isset($values['value'])) { + throw new InvalidTypeException('DoctrineListener', 'value', 'array or string', null); + } + $this->events = (array) $values['value']; + + if (isset($values['connection'])) { + if (!is_string($values['connection'])) { + throw new InvalidTypeException('DoctrineListener', 'connection', 'string', $values['connection']); + } + $this->connection = $values['connection']; + } + + if (isset($values['lazy'])) { + if (!is_boolean($values['lazy'])) { + throw new InvalidTypeException('DoctrineListener', 'lazy', 'boolean', $values['lazy']); + } + $this->lazy = $values['lazy']; + } + + if (isset($values['priority'])) { + if (!is_integer($values['priority'])) { + throw new InvalidTypeException('DoctrineListener', 'priority', 'integer', $values['priority']); + } + $this->priority = $values['priority']; + } + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/FormType.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/FormType.php new file mode 100644 index 0000000..073b971 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/FormType.php @@ -0,0 +1,37 @@ + + */ +final class FormType +{ + /** @var string */ + public $alias; + + public function __construct() + { + if (0 === func_num_args()) { + return; + } + $values = func_get_arg(0); + + if (isset($values['value'])) { + $values['alias'] = $values['value']; + } + + if (isset($values['alias'])) { + if (!is_string($values['alias'])) { + throw new InvalidTypeException('FormType', 'alias', 'string', $values['alias']); + } + + $this->alias = $values['alias']; + } + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Inject.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Inject.php new file mode 100644 index 0000000..f723003 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Inject.php @@ -0,0 +1,27 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Annotation; + +/** + * @Annotation + * @Target({"PROPERTY", "ANNOTATION"}) + */ +final class Inject extends Reference +{ +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/InjectParams.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/InjectParams.php new file mode 100644 index 0000000..44a4d82 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/InjectParams.php @@ -0,0 +1,57 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Annotation; + +use JMS\DiExtraBundle\Exception\InvalidTypeException; + +/** + * @Annotation + * @Target("METHOD") + */ +final class InjectParams +{ + /** @var array */ + public $params = array(); + + public function __construct() + { + if (0 === func_num_args()) { + return; + } + $values = func_get_arg(0); + + if (isset($values['params'])) { + $values['value'] = $values['params']; + } + + if (isset($values['value'])) { + if (!is_array($values['value'])) { + throw new InvalidTypeException('InjectParams', 'value', 'array', $values['value']); + } + + foreach ($values['value'] as $k => $v) { + if (!$v instanceof Inject) { + throw new InvalidTypeException('InjectParams', sprintf('value[%s]', $k), '@Inject', $v); + } + + $this->params[$k] = $v; + } + } + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/LookupMethod.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/LookupMethod.php new file mode 100644 index 0000000..30fef73 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/LookupMethod.php @@ -0,0 +1,27 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Annotation; + +/** + * @Annotation + * @Target("METHOD") + */ +final class LookupMethod extends Reference +{ +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Observe.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Observe.php new file mode 100644 index 0000000..000f827 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Observe.php @@ -0,0 +1,62 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Annotation; + +use JMS\DiExtraBundle\Exception\InvalidTypeException; + +/** + * @Annotation + * @Target("METHOD") + */ +final class Observe +{ + /** @var string @Required */ + public $event; + + /** @var integer */ + public $priority = 0; + + public function __construct() + { + if (0 === func_num_args()) { + return; + } + $values = func_get_arg(0); + + if (isset($values['event'])) { + $values['value'] = $values['event']; + } + + if (isset($values['value'])) { + if (!is_string($values['value'])) { + throw new InvalidTypeException('Observe', 'value', 'string', $values['value']); + } + + $this->event = $values['value']; + } + + if (isset($values['priority'])) { + if (!is_numeric($values['priority'])) { + throw new InvalidTypeException('Observe', 'priority', 'integer', $values['priority']); + } + + $this->priority = $values['priority']; + } + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Reference.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Reference.php new file mode 100644 index 0000000..853f514 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Reference.php @@ -0,0 +1,54 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Annotation; + +use JMS\DiExtraBundle\Exception\InvalidTypeException; + +abstract class Reference +{ + /** @var string */ + public $value; + + /** @var boolean */ + public $required; + + public final function __construct() + { + if (0 === func_num_args()) { + return; + } + $values = func_get_arg(0); + + if (isset($values['value'])) { + if (!is_string($values['value'])) { + throw new InvalidTypeException('Inject', 'value', 'string', $values['value']); + } + + $this->value = $values['value']; + } + + if (isset($values['required'])) { + if (!is_bool($values['required'])) { + throw new InvalidTypeException('Inject', 'required', 'boolean', $values['required']); + } + + $this->required = $values['required']; + } + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Service.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Service.php new file mode 100644 index 0000000..caa0557 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Service.php @@ -0,0 +1,87 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Annotation; + +use JMS\DiExtraBundle\Exception\InvalidTypeException; + +/** + * @Annotation + * @Target("CLASS") + */ +final class Service +{ + /** @var string */ + public $id; + + /** @var string */ + public $parent; + + /** @var boolean */ + public $public; + + /** @var string */ + public $scope; + + /** @var boolean */ + public $abstract; + + public function __construct() + { + if (0 === func_num_args()) { + return; + } + $values = func_get_arg(0); + + if (isset($values['value'])) { + if (!is_string($values['value'])) { + throw new InvalidTypeException('Service', 'value', 'string', $values['value']); + } + + $this->id = $values['value']; + } + if (isset($values['parent'])) { + if (!is_string($values['parent'])) { + throw new InvalidTypeException('Service', 'parent', 'string', $values['parent']); + } + + $this->parent = $values['parent']; + } + if (isset($values['public'])) { + if (!is_bool($values['public'])) { + throw new InvalidTypeException('Service', 'public', 'boolean', $values['public']); + } + + $this->public = $values['public']; + } + if (isset($values['scope'])) { + if (!is_string($values['scope'])) { + throw new InvalidTypeException('Service', 'scope', 'string', $values['scope']); + } + + $this->scope = $values['scope']; + } + if (isset($values['abstract'])) { + if (!is_bool($values['abstract'])) { + throw new InvalidTypeException('Service', 'abstract', 'boolean', $values['abstract']); + } + + $this->abstract = $values['abstract']; + } + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Tag.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Tag.php new file mode 100644 index 0000000..55942be --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Tag.php @@ -0,0 +1,60 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Annotation; + +use JMS\DiExtraBundle\Exception\InvalidArgumentException; +use JMS\DiExtraBundle\Exception\InvalidTypeException; + +/** + * @Annotation + * @Target("CLASS") + */ +final class Tag +{ + /** @var string @Required */ + public $name; + + /** @var array */ + public $attributes = array(); + + public function __construct() + { + if (0 === func_num_args()) { + return; + } + $values = func_get_arg(0); + + if (!isset($values['value'])) { + throw new InvalidArgumentException('A value must be given for annotation "@Tag".'); + } + if (!is_string($values['value'])) { + throw new InvalidTypeException('Tag', 'value', 'string', $values['value']); + } + + $this->name = $values['value']; + + if (isset($values['attributes'])) { + if (!is_array($values['attributes'])) { + throw new InvalidTypeException('Tag', 'attributes', 'array', $values['attributes']); + } + + $this->attributes = $values['attributes']; + } + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Validator.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Validator.php new file mode 100644 index 0000000..cc8e38a --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Annotation/Validator.php @@ -0,0 +1,51 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Annotation; + +use JMS\DiExtraBundle\Exception\InvalidTypeException; + +/** + * @Annotation + * @Target("CLASS") + */ +final class Validator +{ + /** @var string @Required */ + public $alias; + + public function __construct() + { + if (0 === func_num_args()) { + return; + } + $values = func_get_arg(0); + + if (isset($values['alias'])) { + $values['value'] = $values['alias']; + } + + if (!isset($values['value'])) { + throw new \InvalidArgumentException('A value must be given for @Validator annotations.'); + } + if (!is_string($values['value'])) { + throw new InvalidTypeException('Validator', 'value', 'string', $values['value']); + } + $this->alias = $values['value']; + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Config/FastDirectoriesResource.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Config/FastDirectoriesResource.php new file mode 100644 index 0000000..719ac41 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Config/FastDirectoriesResource.php @@ -0,0 +1,78 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Config; + +use JMS\DiExtraBundle\Finder\PatternFinder; + +use Symfony\Component\Config\Resource\ResourceInterface; + +class FastDirectoriesResource implements ResourceInterface +{ + private $finder; + + private $directories; + private $filePattern; + private $files = array(); + + public function __construct(array $directories, $filePattern = null) + { + $this->finder = new PatternFinder('.*', '*.php'); + $this->finder->setRegexPattern(true); + + $this->directories = $directories; + $this->filePattern = $filePattern ?: '*'; + } + + public function __toString() + { + return implode(', ', $this->directories); + } + + public function getResource() + { + return $this->directories; + } + + public function update() + { + $this->files = $this->getFiles(); + } + + public function isFresh($timestamp) + { + $files = $this->getFiles(); + + if (array_diff($this->files, $files) || array_diff($files, $this->files)) { + return false; + } + + foreach ($files as $file) { + if (filemtime($file) > $timestamp) { + return false; + } + } + + return true; + } + + private function getFiles() + { + return $this->finder->findFiles($this->directories); + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Config/ServiceFilesResource.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Config/ServiceFilesResource.php new file mode 100644 index 0000000..40508b2 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Config/ServiceFilesResource.php @@ -0,0 +1,52 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Config; + +use JMS\DiExtraBundle\Finder\PatternFinder; +use Symfony\Component\Config\Resource\ResourceInterface; + +class ServiceFilesResource implements ResourceInterface +{ + private $files; + private $dirs; + + public function __construct(array $files, array $dirs) + { + $this->files = $files; + $this->dirs = $dirs; + } + + public function isFresh($timestamp) + { + $finder = new PatternFinder('JMS\DiExtraBundle\Annotation'); + $files = $finder->findFiles($this->dirs); + + return !array_diff($files, $this->files) && !array_diff($this->files, $files); + } + + public function __toString() + { + return implode(', ', $this->files); + } + + public function getResource() + { + return array($this->files, $this->dirs); + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/Compiler/AnnotationConfigurationPass.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/Compiler/AnnotationConfigurationPass.php new file mode 100644 index 0000000..cb8d77b --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/Compiler/AnnotationConfigurationPass.php @@ -0,0 +1,120 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Alias; +use JMS\DiExtraBundle\Exception\RuntimeException; +use JMS\DiExtraBundle\Config\ServiceFilesResource; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\Definition; +use JMS\DiExtraBundle\Finder\PatternFinder; +use Symfony\Component\HttpKernel\KernelInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +class AnnotationConfigurationPass implements CompilerPassInterface +{ + private $kernel; + private $finder; + + public function __construct(KernelInterface $kernel) + { + $this->kernel = $kernel; + $this->finder = new PatternFinder('JMS\DiExtraBundle\Annotation'); + } + + public function process(ContainerBuilder $container) + { + $reader = $container->get('annotation_reader'); + $factory = $container->get('jms_di_extra.metadata.metadata_factory'); + $converter = $container->get('jms_di_extra.metadata.converter'); + + $directories = $this->getScanDirectories($container); + if (!$directories) { + $container->getCompiler()->addLogMessage('No directories configured for AnnotationConfigurationPass.'); + return; + } + + $files = $this->finder->findFiles($directories); + $container->addResource(new ServiceFilesResource($files, $directories)); + foreach ($files as $file) { + $container->addResource(new FileResource($file)); + require_once $file; + + $className = $this->getClassName($file); + + if (null === $metadata = $factory->getMetadataForClass($className)) { + continue; + } + if (null === $metadata->getOutsideClassMetadata()->id) { + continue; + } + + foreach ($converter->convert($metadata) as $id => $definition) { + $container->setDefinition($id, $definition); + } + } + } + + private function getScanDirectories(ContainerBuilder $c) + { + $bundles = $this->kernel->getBundles(); + $scanBundles = $c->getParameter('jms_di_extra.bundles'); + $scanAllBundles = $c->getParameter('jms_di_extra.all_bundles'); + + $directories = $c->getParameter('jms_di_extra.directories'); + foreach ($bundles as $name => $bundle) { + if (!$scanAllBundles && !in_array($name, $scanBundles, true)) { + continue; + } + + if ('JMSDiExtraBundle' === $name) { + continue; + } + + $directories[] = $bundle->getPath(); + } + + return $directories; + } + + /** + * Only supports one namespaced class per file + * + * @throws \RuntimeException if the class name cannot be extracted + * @param string $filename + * @return string the fully qualified class name + */ + private function getClassName($filename) + { + $src = file_get_contents($filename); + + if (!preg_match('/\bnamespace\s+([^;]+);/s', $src, $match)) { + throw new RuntimeException(sprintf('Namespace could not be determined for file "%s".', $filename)); + } + $namespace = $match[1]; + + if (!preg_match('/\bclass\s+([^\s]+)\s+(?:extends|implements|{)/s', $src, $match)) { + throw new RuntimeException(sprintf('Could not extract class name from file "%s".', $filename)); + } + + return $namespace.'\\'.$match[1]; + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/Compiler/IntegrationPass.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/Compiler/IntegrationPass.php new file mode 100644 index 0000000..db3e488 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/Compiler/IntegrationPass.php @@ -0,0 +1,55 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Integrates the bundle with external code. + * + * @author Johannes M. Schmitt + */ +class IntegrationPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + // replace Symfony2's default controller resolver + $container->setAlias('controller_resolver', new Alias('jms_di_extra.controller_resolver', false)); + + // replace SensioFrameworkExtraBundle's default template listener + if ($container->hasDefinition('sensio_framework_extra.view.listener')) { + $def = $container->getDefinition('sensio_framework_extra.view.listener'); + + // only overwrite if it has the default class otherwise the user has to do the integration manually + if ('%sensio_framework_extra.view.listener.class%' === $def->getClass()) { + $def->setClass('%jms_di_extra.template_listener.class%'); + } + } + + if ($container->hasDefinition('sensio_framework_extra.controller.listener')) { + $def = $container->getDefinition('sensio_framework_extra.controller.listener'); + + if ('%sensio_framework_extra.controller.listener.class%' === $def->getClass()) { + $def->setClass('%jms_di_extra.controller_listener.class%'); + } + } + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/Compiler/ResourceOptimizationPass.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/Compiler/ResourceOptimizationPass.php new file mode 100644 index 0000000..ee73a0e --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/Compiler/ResourceOptimizationPass.php @@ -0,0 +1,81 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\DependencyInjection\Compiler; + +use JMS\DiExtraBundle\Config\FastDirectoriesResource; + +use Symfony\Component\Config\Resource\DirectoryResource; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +class ResourceOptimizationPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + $resources = $directories = array(); + + $ref = new \ReflectionProperty('Symfony\Component\Config\Resource\DirectoryResource', 'pattern'); + $ref->setAccessible(true); + + foreach ($container->getResources() as $resource) { + if ($resource instanceof DirectoryResource) { + if (null === $pattern = $ref->getValue($resource)) { + $pattern = '*'; + } + + $directories[$pattern][] = $resource->getResource(); + + continue; + } + + $resources[] = $resource; + } + + $sortFunc = function($a, $b) { + return strlen($a) - strlen($b); + }; + + foreach ($directories as $pattern => $pDirectories) { + $newResources = array(); + + usort($pDirectories, $sortFunc); + foreach ($pDirectories as $a) { + foreach ($newResources as $b) { + if (0 === strpos($a, $b)) { + continue 2; + } + } + + $newResources[] = $a; + } + + $directories[$pattern] = $newResources; + } + + foreach ($directories as $pattern => $pDirectories) { + $newResource = new FastDirectoriesResource($pDirectories, $pattern); + $newResource->update(); + $resources[] = $newResource; + } + + $ref = new \ReflectionProperty('Symfony\Component\DependencyInjection\ContainerBuilder', 'resources'); + $ref->setAccessible(true); + $ref->setValue($container, $resources); + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/Configuration.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/Configuration.php new file mode 100644 index 0000000..52129b8 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/Configuration.php @@ -0,0 +1,69 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\DependencyInjection; + +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; + +class Configuration implements ConfigurationInterface +{ + public function getConfigTreeBuilder() + { + $tb = new TreeBuilder(); + + $tb + ->root('jms_di_extra', 'array') + ->children() + ->arrayNode('locations') + ->addDefaultsIfNotSet() + ->children() + ->booleanNode('all_bundles')->defaultFalse()->end() + ->arrayNode('bundles') + ->beforeNormalization() + ->ifString() + ->then(function($v) { + return preg_split('/\s*,\s*/', $v); + }) + ->end() + ->prototype('scalar')->end() + ->end() + ->arrayNode('directories') + ->beforeNormalization() + ->ifString() + ->then(function($v) { + return preg_split('/\s*,\s*/', $v); + }) + ->end() + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + ->scalarNode('cache_dir')->defaultValue('%kernel.cache_dir%/diextra')->end() + ->arrayNode('metadata') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('cache')->defaultValue('file')->cannotBeEmpty()->end() + ->end() + ->end() + ->end() + ->end(); + + return $tb; + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/JMSDiExtraExtension.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/JMSDiExtraExtension.php new file mode 100644 index 0000000..9c0266c --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/JMSDiExtraExtension.php @@ -0,0 +1,84 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\DependencyInjection; + +use JMS\DiExtraBundle\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\HttpKernel\DependencyInjection\Extension; + +class JMSDiExtraExtension extends Extension +{ + public function load(array $configs, ContainerBuilder $container) + { + $config = $this->mergeConfigs($configs); + + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('services.xml'); + + $container->setParameter('jms_di_extra.all_bundles', $config['locations']['all_bundles']); + $container->setParameter('jms_di_extra.bundles', $config['locations']['bundles']); + $container->setParameter('jms_di_extra.directories', $config['locations']['directories']); + $container->setParameter('jms_di_extra.cache_dir', $config['cache_dir']); + + $this->configureMetadata($config['metadata'], $container, $config['cache_dir'].'/metadata'); + + $this->addClassesToCompile(array( + 'JMS\\DiExtraBundle\\HttpKernel\ControllerResolver', + )); + } + + private function configureMetadata(array $config, $container, $cacheDir) + { + if ('none' === $config['cache']) { + $container->removeAlias('jms_di_extra.metadata.cache'); + return; + } + + if ('file' === $config['cache']) { + $cacheDir = $container->getParameterBag()->resolveValue($cacheDir); + if (!file_exists($cacheDir)) { + if (false === @mkdir($cacheDir, 0777, true)) { + throw new RuntimeException(sprintf('The cache dir "%s" could not be created.', $cacheDir)); + } + } + if (!is_writable($cacheDir)) { + throw new RuntimeException(sprintf('The cache dir "%s" is not writable.', $cacheDir)); + } + + $container + ->getDefinition('jms_di_extra.metadata.cache.file_cache') + ->replaceArgument(0, $cacheDir) + ; + } else { + $container->setAlias('jms_di_extra.metadata.cache', new Alias($config['cache'], false)); + } + } + + private function mergeConfigs(array $configs) + { + $processor = new Processor(); + $configuration = new Configuration(); + + return $processor->process($configuration->getConfigTreeBuilder()->buildTree(), $configs); + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/LookupMethodClassInterface.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/LookupMethodClassInterface.php new file mode 100644 index 0000000..40a506f --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/DependencyInjection/LookupMethodClassInterface.php @@ -0,0 +1,24 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\DependencyInjection; + +interface LookupMethodClassInterface +{ + function __jmsDiExtra_getOriginalClassName(); +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/EventListener/ControllerListener.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/EventListener/ControllerListener.php new file mode 100644 index 0000000..cab730f --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/EventListener/ControllerListener.php @@ -0,0 +1,58 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\EventListener; + +use Sensio\Bundle\FrameworkExtraBundle\EventListener\ControllerListener as BaseControllerListener; +use CG\Core\ClassUtils; +use Doctrine\Common\Annotations\Reader; +use Symfony\Component\HttpKernel\Event\FilterControllerEvent; +use Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationInterface; + +/** + * The ControllerListener class parses annotation blocks located in + * controller classes. + * + * @author Fabien Potencier + */ +class ControllerListener extends BaseControllerListener +{ + /** + * Modifies the Request object to apply configuration information found in + * controllers annotations like the template to render or HTTP caching + * configuration. + * + * @param FilterControllerEvent $event A FilterControllerEvent instance + */ + public function onKernelController(FilterControllerEvent $event) + { + if (!is_array($controller = $event->getController())) { + return; + } + + $object = new \ReflectionClass(ClassUtils::getUserClass(get_class($controller[0]))); + $method = $object->getMethod($controller[1]); + + $request = $event->getRequest(); + foreach ($this->reader->getMethodAnnotations($method) as $configuration) { + if ($configuration instanceof ConfigurationInterface) { + $request->attributes->set('_'.$configuration->getAliasName(), $configuration); + } + } + } +} diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/EventListener/TemplateListener.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/EventListener/TemplateListener.php new file mode 100644 index 0000000..feacc35 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/EventListener/TemplateListener.php @@ -0,0 +1,50 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\EventListener; + +use CG\Core\ClassUtils; +use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference; +use Symfony\Component\HttpFoundation\Request; +use JMS\DiExtraBundle\DependencyInjection\LookupMethodClassInterface; +use Sensio\Bundle\FrameworkExtraBundle\EventListener\TemplateListener as FrameworkExtraTemplateListener; + +class TemplateListener extends FrameworkExtraTemplateListener +{ + protected function guessTemplateName($controller, Request $request, $engine = 'twig') + { + $controllerClass = get_class($controller[0]); + $userClass = ClassUtils::getUserClass($controllerClass); + + if ($controllerClass === $userClass) { + return parent::guessTemplateName($controller, $request, $engine); + } + + if (!preg_match('/Controller\\\(.+)Controller$/', $userClass, $matchController)) { + throw new \InvalidArgumentException(sprintf('The "%s" class does not look like a controller class (it must be in a "Controller" sub-namespace and the class name must end with "Controller")', $userClass)); + } + + if (!preg_match('/^(.+)Action$/', $controller[1], $matchAction)) { + throw new \InvalidArgumentException(sprintf('The "%s" method does not look like an action method (it does not end with Action)', $controller[1])); + } + + $bundle = $this->getBundleForClass($userClass); + + return new TemplateReference($bundle->getName(), $matchController[1], $matchAction[1], $request->getRequestFormat(), $engine); + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Exception/Exception.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Exception/Exception.php new file mode 100644 index 0000000..293e70b --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Exception/Exception.php @@ -0,0 +1,28 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Exception; + +/** + * Base exception for the DiExtraBundle. + * + * @author Johannes M. Schmitt + */ +interface Exception +{ +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Exception/InvalidArgumentException.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Exception/InvalidArgumentException.php new file mode 100644 index 0000000..990c60f --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Exception/InvalidArgumentException.php @@ -0,0 +1,28 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Exception; + +/** + * InvalidArgumentException for the DiExtraBundle. + * + * @author Johannes M. Schmitt + */ +class InvalidArgumentException extends \InvalidArgumentException implements Exception +{ +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Exception/InvalidTypeException.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Exception/InvalidTypeException.php new file mode 100644 index 0000000..7437778 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Exception/InvalidTypeException.php @@ -0,0 +1,29 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Exception; + +class InvalidTypeException extends InvalidArgumentException +{ + public function __construct($annotName, $attrName, $expected, $actual) + { + $msg = sprintf('The attribute "%s" on annotation "@%s" is expected to be of type %s, but got %s.', $attrName, $annotName, $expected, gettype($actual)); + + parent::__construct($msg); + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Exception/RuntimeException.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Exception/RuntimeException.php new file mode 100644 index 0000000..a47a6e4 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Exception/RuntimeException.php @@ -0,0 +1,28 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Exception; + +/** + * RuntimeException for the DiExtraBundle. + * + * @author Johannes M. Schmitt + */ +class RuntimeException extends \RuntimeException implements Exception +{ +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Finder/PatternFinder.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Finder/PatternFinder.php new file mode 100644 index 0000000..f4bea5f --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Finder/PatternFinder.php @@ -0,0 +1,201 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Finder; + +use JMS\DiExtraBundle\Exception\RuntimeException; +use Symfony\Component\Finder\Finder; +use Symfony\Component\Process\ExecutableFinder; + +class PatternFinder +{ + const METHOD_GREP = 1; + const METHOD_FINDSTR = 2; + const METHOD_FINDER = 3; + + private static $method; + private static $grepPath; + + private $pattern; + private $filePattern; + private $recursive = true; + private $regexPattern = false; + + public function __construct($pattern, $filePattern = '*.php') + { + if (null === self::$method) { + self::determineMethod(); + } + + $this->pattern = $pattern; + $this->filePattern = $filePattern; + } + + public function setRecursive($bool) + { + $this->recursive = (Boolean) $bool; + } + + public function setRegexPattern($bool) + { + $this->regexPattern = (Boolean) $bool; + } + + public function findFiles(array $dirs) + { + // check for grep availability + if (self::METHOD_GREP === self::$method) { + return $this->findUsingGrep($dirs); + } + + // use FINDSTR on Windows + if (self::METHOD_FINDSTR === self::$method) { + return $this->findUsingFindstr($dirs); + } + + // this should really be avoided at all costs since it is damn slow + return $this->findUsingFinder($dirs); + } + + private function findUsingFindstr(array $dirs) + { + $cmd = 'FINDSTR /M /S /P'; + + if (!$this->recursive) { + $cmd .= ' /L'; + } + + $cmd .= ' /D:'.escapeshellarg(implode(';', $dirs)); + $cmd .= ' '.escapeshellarg($this->pattern); + $cmd .= ' '.$this->filePattern; + + exec($cmd, $lines, $exitCode); + + if (1 === $exitCode) { + return array(); + } + + if (0 !== $exitCode) { + throw new RuntimeException(sprintf('Command "%s" exited with non-successful status code. "%d".', $cmd, $exitCode)); + } + + // Looks like FINDSTR has different versions with different output formats. + // + // Supported format #1: + // C:\matched\dir1: + // Relative\Path\To\File1.php + // Relative\Path\To\File2.php + // C:\matched\dir2: + // Relative\Path\To\File3.php + // Relative\Path\To\File4.php + // + // Supported format #2: + // C:\matched\dir1\Relative\Path\To\File1.php + // C:\matched\dir1\Relative\Path\To\File2.php + // C:\matched\dir2\Relative\Path\To\File3.php + // C:\matched\dir2\Relative\Path\To\File4.php + + $files = array(); + $currentDir = ''; + foreach ($lines as $line) { + if (':' === substr($line, -1)) { + $currentDir = trim($line, ' :/').'/'; + continue; + } + + $files[] = $currentDir.$line; + } + + return $files; + } + + private function findUsingGrep(array $dirs) + { + $cmd = self::$grepPath; + + if (!$this->regexPattern) { + $cmd .= ' --fixed-strings'; + } else { + $cmd .= ' --extended-regexp'; + } + + if ($this->recursive) { + $cmd .= ' --directories=recurse'; + } else { + $cmd .= ' --directories=skip'; + } + + $cmd .= ' --devices=skip --files-with-matches --with-filename --max-count=1 --color=never --include='.$this->filePattern; + $cmd .= ' '.escapeshellarg($this->pattern); + + foreach ($dirs as $dir) { + $cmd .= ' '.escapeshellarg($dir); + } + exec($cmd, $files, $exitCode); + + if (1 === $exitCode) { + return array(); + } + + if (0 !== $exitCode) { + throw new RuntimeException(sprintf('Command "%s" exited with non-successful status code "%d".', $cmd, $exitCode)); + } + + return $files; + } + + private function findUsingFinder(array $dirs) + { + $finder = new Finder(); + $pattern = $this->pattern; + $regex = $this->regexPattern; + $finder + ->files() + ->name($this->filePattern) + ->in($dirs) + ->ignoreVCS(true) + ->filter(function($file) use ($pattern, $regex) { + if (!$regex) { + return false !== strpos(file_get_contents($file->getPathName()), $pattern); + } + + return 0 < preg_match('#'.$pattern.'#', file_get_contents($file->getPathName())); + }) + ; + + if (!$this->recursive) { + $finder->depth('<= 0'); + } + + return array_keys(iterator_to_array($finder)); + } + + private static function determineMethod() + { + $finder = new ExecutableFinder(); + $isWindows = 0 === stripos(PHP_OS, 'win'); + + if (!$isWindows && self::$grepPath = $finder->find('grep')) { + self::$method = self::METHOD_GREP; + } else if ($isWindows) { + self::$method = self::METHOD_FINDSTR; + } else { + self::$method = self::METHOD_FINDER; + } + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Generator/DefinitionInjectorGenerator.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Generator/DefinitionInjectorGenerator.php new file mode 100644 index 0000000..3bfea60 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Generator/DefinitionInjectorGenerator.php @@ -0,0 +1,192 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Generator; + +use CG\Generator\Writer; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Definition; + +/** + * Generates lightweight code for injecting a single definition. + * + * @author Johannes M. Schmitt + */ +class DefinitionInjectorGenerator +{ + private $nameGenerator; + private $inlinedDefinitions; + + public function __construct() + { + $this->nameGenerator = new NameGenerator(); + $this->inlinedDefinitions = new \SplObjectStorage(); + } + + public function generate(Definition $def) + { + $writer = new Writer(); + + $writer + ->writeln('writeln('/**') + ->writeln(' * This code has been auto-generated by the JMSDiExtraBundle.') + ->writeln(' *') + ->writeln(' * Manual changes to it will be lost.') + ->writeln(' */') + ->writeln('return function($container) {') + ->indent() + ; + + if ($file = $def->getFile()) { + $writer->writeln('require_once '.var_export($file, true).';'); + + require_once $file; + } + + foreach ($this->getInlineDefinitions($def) as $inlineDef) { + $name = $this->nameGenerator->nextName(); + $this->inlinedDefinitions[$inlineDef] = $name; + + $writer->writeln('$'.$name.' = new \\'.$inlineDef->getClass().$this->dumpArguments($inlineDef->getArguments()).';'); + } + + $writer->writeln('$instance = new \\'.$def->getClass().$this->dumpArguments($def->getArguments()).';'); + + foreach ($def->getMethodCalls() as $call) { + list($method, $arguments) = $call; + $writer->writeln('$instance->'.$method.$this->dumpArguments($arguments).';'); + } + + $ref = new \ReflectionClass($def->getClass()); + foreach ($def->getProperties() as $property => $value) { + $refProperty = $this->getReflectionProperty($ref, $property); + + if ($refProperty->isPublic()) { + $writer->writeln('$instance->'.$property.' = '.$this->dumpValue($value).';'); + } else { + $writer + ->writeln(sprintf("\$refProperty = new \ReflectionProperty(%s, %s);", var_export($refProperty->getDeclaringClass()->getName(), true), var_export($property, true))) + ->writeln('$refProperty->setAccessible(true);') + ->writeln('$refProperty->setValue($instance, '.$this->dumpValue($value).');') + ; + } + } + + if (method_exists($def, 'getInitMethod') && $def->getInitMethod()) { + $writer->writeln('$instance->'.$def->getInitMethod().'();'); + } + + $writer + ->writeln('return $instance;') + ->outdent() + ->writeln('};') + ; + + return $writer->getContent(); + } + + private function getReflectionProperty($ref, $property) + { + $origClass = $ref->getName(); + while (!$ref->hasProperty($property) && false !== $ref = $ref->getParentClass()); + + if (!$ref->hasProperty($property)) { + throw new \RuntimeException(sprintf('Could not find property "%s" anywhere in class "%s" or one of its parents.', $property, $origName)); + } + + return $ref->getProperty($property); + } + + private function getInlineDefinitions(Definition $def) + { + $defs = new \SplObjectStorage(); + $this->getDefinitionsFromArray($def->getArguments(), $defs); + $this->getDefinitionsFromArray($def->getMethodCalls(), $defs); + $this->getDefinitionsFromArray($def->getProperties(), $defs); + + return $defs; + } + + private function getDefinitionsFromArray(array $a, \SplObjectStorage $defs) + { + foreach ($a as $k => $v) { + if ($v instanceof Definition) { + $defs->attach($v); + } else if (is_array($v)) { + $this->getDefinitionsFromArray($v, $defs); + } + } + } + + private function dumpArguments(array $arguments) + { + $code = '('; + + $first = true; + foreach ($arguments as $argument) { + if (!$first) { + $code .= ', '; + } + $first = false; + + $code .= $this->dumpValue($argument); + } + + return $code.')'; + } + + private function dumpValue($value) + { + if (is_array($value)) { + $code = 'array('; + + $first = true; + foreach ($value as $k => $v) { + if (!$first) { + $code .= ', '; + } + $first = false; + + $code .= sprintf('%s => %s', var_export($k, true), $this->dumpValue($v)); + } + + return $code.')'; + } else if ($value instanceof Reference) { + if ('service_container' === (string) $value) { + return '$container'; + } + + return sprintf('$container->get(%s, %d)', var_export((string) $value, true), $value->getInvalidBehavior()); + } else if ($value instanceof Parameter) { + return sprintf('$container->getParameter(%s)', var_export((string) $value, true)); + } else if (is_scalar($value) || null === $value) { + // we do not support embedded parameters + if (is_string($value) && '%' === $value[0] && '%' !== $value[1]) { + return sprintf('$container->getParameter(%s)', var_export(substr($value, 1, -1), true)); + } + + return var_export($value, true); + } else if ($value instanceof Definition) { + return sprintf('$%s', $this->inlinedDefinitions[$value]); + } + + throw new \RuntimeException(sprintf('Found unsupported value of type %s during definition injector generation: "%s"', gettype($value), json_encode($value))); + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Generator/LookupMethodClassGenerator.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Generator/LookupMethodClassGenerator.php new file mode 100644 index 0000000..54b02cf --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Generator/LookupMethodClassGenerator.php @@ -0,0 +1,119 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Generator; + +use Metadata\ClassHierarchyMetadata; +use CG\Generator\PhpParameter; +use CG\Generator\PhpMethod; +use CG\Generator\PhpProperty; +use CG\Generator\PhpClass; +use CG\Proxy\GeneratorInterface; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\Reference; + +class LookupMethodClassGenerator implements GeneratorInterface +{ + const PREFIX = '__jmsDiExtra_'; + + private $metadata; + private $requiredFile; + + public function __construct(ClassHierarchyMetadata $metadata) + { + $this->metadata = $metadata; + } + + public function setRequiredFile($file) + { + $this->requiredFile = $file; + } + + public function generate(\ReflectionClass $class, PhpClass $genClass) + { + if (!empty($this->requiredFile)) { + $genClass->addRequiredFile($this->requiredFile); + } + + $genClass->setProperty(PhpProperty::create() + ->setName(self::PREFIX.'container') + ->setVisibility('private') + ); + + $genClass->setMethod(PhpMethod::create() + ->setName(self::PREFIX.'setContainer') + ->addParameter(PhpParameter::create() + ->setName('container') + ->setType('Symfony\Component\DependencyInjection\ContainerInterface') + ) + ->setBody('$this->'.self::PREFIX.'container = $container;') + ); + + $genClass->addInterfaceName('JMS\DiExtraBundle\DependencyInjection\LookupMethodClassInterface'); + $genClass->setMethod(PhpMethod::create() + ->setName(self::PREFIX.'getOriginalClassName') + ->setFinal(true) + ->setBody('return '.var_export($class->name, true).';') + ); + + foreach ($this->getLookupMethods() as $name => $value) { + $genClass->setMethod(PhpMethod::fromReflection($class->getMethod($name)) + ->setAbstract(false) + ->setBody('return '.$this->dumpValue($value).';') + ->setDocblock(null) + ); + } + } + + private function getLookupMethods() + { + $outerClass = $this->metadata->getOutsideClassMetadata()->reflection; + $lookupMethods = array(); + foreach ($this->metadata->classMetadata as $classMetadata) { + if (!$classMetadata->lookupMethods) { + continue; + } + + foreach ($classMetadata->lookupMethods as $name => $value) { + // check if method has been overridden + if ($outerClass->getMethod($name)->class !== $classMetadata->reflection->name) { + continue; + } + + $lookupMethods[$name] = $value; + } + } + + return $lookupMethods; + } + + private function dumpValue($value) + { + if ($value instanceof Parameter) { + return '$this->'.self::PREFIX.'container->getParameter('.var_export((string) $value, true).')'; + } else if ($value instanceof Reference) { + return '$this->'.self::PREFIX.'container->get('.var_export((string) $value, true).', '.var_export($value->getInvalidBehavior(), true).')'; + } else if (is_string($value) && '%' === $value[0]) { + return '$this->'.self::PREFIX.'container->getParameter('.var_export(substr($value, 1, -1), true).')'; + } else if (is_array($value) || is_scalar($value) || null === $value) { + return var_export($value, true); + } + + throw new \RuntimeException(sprintf('Invalid value for lookup method: %s', json_encode($value))); + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Generator/NameGenerator.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Generator/NameGenerator.php new file mode 100644 index 0000000..df3c1c8 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Generator/NameGenerator.php @@ -0,0 +1,79 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Generator; + +class NameGenerator +{ + private $count = 0; + private $firstChars = 'abcdefghijklmnopqrstuvwxyz'; + private $firstCharsLength = 26; + private $nonFirstChars = 'abcdefghijklmnopqrstuvwxyz0123456789_'; + private $nonFirstCharsLength = 37; + private $reservedNames = array(); + + public function addReservedName($name) + { + $this->reservedNames[$name] = true; + } + + public function setFirstChars($chars) + { + $this->firstChars = $chars; + $this->firstCharsLength = strlen($chars); + } + + public function setNonFirstChars($chars) + { + $this->nonFirstChars = $chars; + $this->nonFirstCharsLength = strlen($chars); + } + + public function reset() + { + $this->count = 0; + } + + public function nextName() + { + while (true) { + $name = ''; + $i = $this->count; + + if ('' === $name) { + $name .= $this->firstChars[$i%$this->firstCharsLength]; + $i = intval($i/$this->firstCharsLength); + } + + while ($i > 0) { + $i -= 1; + $name .= $this->nonFirstChars[$i%$this->nonFirstCharsLength]; + $i = intval($i/$this->nonFirstCharsLength); + } + + $this->count += 1; + + // check that the name is not reserved + if (isset($this->reservedNames[$name])) { + continue; + } + + return $name; + } + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/HttpKernel/ControllerResolver.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/HttpKernel/ControllerResolver.php new file mode 100644 index 0000000..f1a48ce --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/HttpKernel/ControllerResolver.php @@ -0,0 +1,179 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\HttpKernel; + +use Metadata\ClassHierarchyMetadata; +use JMS\DiExtraBundle\Metadata\ClassMetadata; +use CG\Core\DefaultNamingStrategy; +use CG\Proxy\Enhancer; +use JMS\AopBundle\DependencyInjection\Compiler\PointcutMatchingPass; +use JMS\DiExtraBundle\Generator\DefinitionInjectorGenerator; +use JMS\DiExtraBundle\Generator\LookupMethodClassGenerator; +use JMS\DiExtraBundle\DependencyInjection\Dumper\PhpDumper; +use Metadata\MetadataFactory; +use Symfony\Component\DependencyInjection\Compiler\InlineServiceDefinitionsPass; +use Symfony\Component\DependencyInjection\ContainerAwareInterface; +use Symfony\Component\DependencyInjection\Compiler\ResolveDefinitionTemplatesPass; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Config\ConfigCache; +use Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver as BaseControllerResolver; + +class ControllerResolver extends BaseControllerResolver +{ + protected function createController($controller) + { + if (false === $pos = strpos($controller, '::')) { + $count = substr_count($controller, ':'); + if (2 == $count) { + // controller in the a:b:c notation then + $controller = $this->parser->parse($controller); + $pos = strpos($controller, '::'); + } elseif (1 == $count) { + // controller in the service:method notation + list($service, $method) = explode(':', $controller); + + return array($this->container->get($service), $method); + } else { + throw new \LogicException(sprintf('Unable to parse the controller name "%s".', $controller)); + } + } + + $class = substr($controller, 0, $pos); + $method = substr($controller, $pos+2); + + if (!class_exists($class)) { + throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class)); + } + + $filename = $this->container->getParameter('jms_di_extra.cache_dir').'/controller_injectors/'.str_replace('\\', '', $class).'.php'; + $cache = new ConfigCache($filename, $this->container->getParameter('kernel.debug')); + + if (!$cache->isFresh()) { + $metadata = $this->container->get('jms_di_extra.metadata.metadata_factory')->getMetadataForClass($class); + if (null === $metadata) { + $metadata = new ClassHierarchyMetadata(); + $metadata->addClassMetadata(new ClassMetadata($class)); + } + + $this->prepareContainer($cache, $filename, $metadata); + } + + $inject = require $filename; + $controller = $inject($this->container); + + if ($controller instanceof ContainerAwareInterface) { + $controller->setContainer($this->container); + } + + return array($controller, $method); + } + + private function prepareContainer($cache, $containerFilename, $metadata) + { + $container = new ContainerBuilder(); + $container->setParameter('jms_aop.cache_dir', $this->container->getParameter('jms_di_extra.cache_dir')); + $def = $container + ->register('jms_aop.interceptor_loader', 'JMS\AopBundle\Aop\InterceptorLoader') + ->addArgument(new Reference('service_container')) + ->setPublic(false) + ; + + // add resources + $ref = $metadata->getOutsideClassMetadata()->reflection; + while ($ref && false !== $filename = $ref->getFilename()) { + $container->addResource(new FileResource($filename)); + $ref = $ref->getParentClass(); + } + + // add definitions + $definitions = $this->container->get('jms_di_extra.metadata.converter')->convert($metadata); + $serviceIds = $parameters = array(); + + $controllerDef = array_pop($definitions); + $container->setDefinition('controller', $controllerDef); + + foreach ($definitions as $id => $def) { + $container->setDefinition($id, $def); + } + + $this->generateLookupMethods($controllerDef, $metadata); + + $config = $container->getCompilerPassConfig(); + $config->setOptimizationPasses(array()); + $config->setRemovingPasses(array()); + $config->addPass(new ResolveDefinitionTemplatesPass()); + $config->addPass(new PointcutMatchingPass($this->container->get('jms_aop.pointcut_container')->getPointcuts())); + $config->addPass(new InlineServiceDefinitionsPass()); + $container->compile(); + + if (!file_exists($dir = dirname($containerFilename))) { + if (false === @mkdir($dir, 0777, true)) { + throw new \RuntimeException(sprintf('Could not create directory "%s".', $dir)); + } + } + + static $generator; + if (null === $generator) { + $generator = new DefinitionInjectorGenerator(); + } + + $cache->write($generator->generate($container->getDefinition('controller')), $container->getResources()); + } + + private function generateLookupMethods($def, $metadata) + { + $found = false; + foreach ($metadata->classMetadata as $cMetadata) { + if (!empty($cMetadata->lookupMethods)) { + $found = true; + break; + } + } + + if (!$found) { + return; + } + + $generator = new LookupMethodClassGenerator($metadata); + $outerClass = $metadata->getOutsideClassMetadata()->reflection; + + if ($file = $def->getFile()) { + $generator->setRequiredFile($file); + } + + $enhancer = new Enhancer( + $outerClass, + array(), + array( + $generator, + ) + ); + + $filename = $this->container->getParameter('jms_di_extra.cache_dir').'/lookup_method_classes/'.str_replace('\\', '-', $outerClass->name).'.php'; + $enhancer->writeClass($filename); + + $def->setFile($filename); + $def->setClass($enhancer->getClassName($outerClass)); + $def->addMethodCall('__jmsDiExtra_setContainer', array(new Reference('service_container'))); + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/JMSDiExtraBundle.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/JMSDiExtraBundle.php new file mode 100644 index 0000000..6a88dbe --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/JMSDiExtraBundle.php @@ -0,0 +1,50 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle; + +use JMS\DiExtraBundle\DependencyInjection\Compiler\ResourceOptimizationPass; +use JMS\DiExtraBundle\DependencyInjection\Compiler\IntegrationPass; +use Symfony\Component\HttpKernel\KernelInterface; +use Symfony\Component\DependencyInjection\Compiler\PassConfig; +use JMS\DiExtraBundle\DependencyInjection\Compiler\AnnotationConfigurationPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class JMSDiExtraBundle extends Bundle +{ + const VERSION = '1.0.1'; + + private $kernel; + + public function __construct(KernelInterface $kernel) + { + $this->kernel = $kernel; + } + + public function build(ContainerBuilder $container) + { + $config = $container->getCompiler()->getPassConfig(); + $passes = $config->getBeforeOptimizationPasses(); + array_unshift($passes, new AnnotationConfigurationPass($this->kernel)); + $config->setBeforeOptimizationPasses($passes); + + $container->addCompilerPass(new IntegrationPass()); + $container->addCompilerPass(new ResourceOptimizationPass(), PassConfig::TYPE_AFTER_REMOVING); + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Metadata/ClassMetadata.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Metadata/ClassMetadata.php new file mode 100644 index 0000000..7b992d9 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Metadata/ClassMetadata.php @@ -0,0 +1,74 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Metadata; + +use Metadata\ClassMetadata as BaseClassMetadata; + +class ClassMetadata extends BaseClassMetadata +{ + public $id; + public $parent; + public $scope; + public $public; + public $abstract; + public $tags = array(); + public $arguments; + public $methodCalls = array(); + public $lookupMethods = array(); + public $properties = array(); + public $initMethod; + + public function serialize() + { + return serialize(array( + $this->id, + $this->parent, + $this->scope, + $this->public, + $this->abstract, + $this->tags, + $this->arguments, + $this->methodCalls, + $this->lookupMethods, + $this->properties, + $this->initMethod, + parent::serialize(), + )); + } + + public function unserialize($str) + { + list( + $this->id, + $this->parent, + $this->scope, + $this->public, + $this->abstract, + $this->tags, + $this->arguments, + $this->methodCalls, + $this->lookupMethods, + $this->properties, + $this->initMethod, + $parentStr + ) = unserialize($str); + + parent::unserialize($parentStr); + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Metadata/Driver/AnnotationDriver.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Metadata/Driver/AnnotationDriver.php new file mode 100644 index 0000000..cbd2051 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Metadata/Driver/AnnotationDriver.php @@ -0,0 +1,220 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Metadata\Driver; + +use JMS\DiExtraBundle\Annotation\AfterSetup; + +use JMS\DiExtraBundle\Annotation\FormType; + +use JMS\DiExtraBundle\Annotation\DoctrineListener; +use JMS\DiExtraBundle\Annotation\Reference as AnnotReference; +use JMS\DiExtraBundle\Annotation\LookupMethod; +use JMS\DiExtraBundle\Annotation\Validator; +use JMS\DiExtraBundle\Annotation\InjectParams; +use JMS\DiExtraBundle\Exception\InvalidTypeException; +use JMS\DiExtraBundle\Annotation\Observe; +use Doctrine\Common\Annotations\Reader; +use JMS\DiExtraBundle\Annotation\Inject; +use JMS\DiExtraBundle\Annotation\Service; +use JMS\DiExtraBundle\Annotation\Tag; +use JMS\DiExtraBundle\Metadata\ClassMetadata; +use Metadata\Driver\DriverInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Reference; + +class AnnotationDriver implements DriverInterface +{ + private $reader; + + public function __construct(Reader $reader) + { + $this->reader = $reader; + } + + public function loadMetadataForClass(\ReflectionClass $class) + { + $metadata = new ClassMetadata($className = $class->getName()); + if (false !== $filename = $class->getFilename()) { + $metadata->fileResources[] = $filename; + } + + // this is a bit of a hack, but avoids any timeout issues when a class + // is moved into one of the compiled classes files, and Doctrine + // Common 2.1 is used. + if (false !== strpos($filename, '/classes.php') + || false !== strpos($filename, '/bootstrap.php')) { + return null; + } + + foreach ($this->reader->getClassAnnotations($class) as $annot) { + if ($annot instanceof Service) { + if (null === $annot->id) { + $metadata->id = $this->generateId($className); + } else { + $metadata->id = $annot->id; + } + + $metadata->parent = $annot->parent; + $metadata->public = $annot->public; + $metadata->scope = $annot->scope; + $metadata->abstract = $annot->abstract; + } else if ($annot instanceof Tag) { + $metadata->tags[$annot->name][] = $annot->attributes; + } else if ($annot instanceof Validator) { + // automatically register as service if not done explicitly + if (null === $metadata->id) { + $metadata->id = $this->generateId($className); + } + + $metadata->tags['validator.constraint_validator'][] = array( + 'alias' => $annot->alias, + ); + } else if ($annot instanceof DoctrineListener) { + if (null === $metadata->id) { + $metadata->id = $this->generateId($className); + } + + foreach ($annot->events as $event) { + $metadata->tags['doctrine.event_listener'][] = array( + 'event' => $event, + 'connection' => $annot->connection ?: 'default', + 'lazy' => $annot->lazy, + 'priority' => $annot->priority, + ); + } + } else if ($annot instanceof FormType) { + if (null === $metadata->id) { + $metadata->id = $this->generateId($className); + } + + $alias = $annot->alias; + + // try to extract it from the class itself + if (null === $alias) { + $instance = unserialize(sprintf('O:%d:"%s":0:{}', strlen($className), $className)); + $alias = $instance->getName(); + } + + $metadata->tags['form.type'][] = array( + 'alias' => $alias, + ); + } + } + + $hasInjection = false; + foreach ($class->getProperties() as $property) { + if ($property->getDeclaringClass()->getName() !== $className) { + continue; + } + $name = $property->getName(); + + foreach ($this->reader->getPropertyAnnotations($property) as $annot) { + if ($annot instanceof Inject) { + $hasInjection = true; + $metadata->properties[$name] = $this->convertReferenceValue($name, $annot); + } + } + } + + foreach ($class->getMethods() as $method) { + if ($method->getDeclaringClass()->getName() !== $className) { + continue; + } + $name = $method->getName(); + + foreach ($this->reader->getMethodAnnotations($method) as $annot) { + if ($annot instanceof Observe) { + $metadata->tags['kernel.event_listener'][] = array( + 'event' => $annot->event, + 'method' => $name, + 'priority' => $annot->priority, + ); + } else if ($annot instanceof InjectParams) { + $params = array(); + foreach ($method->getParameters() as $param) { + if (!isset($annot->params[$paramName = $param->getName()])) { + $params[] = $this->convertReferenceValue($paramName, new Inject(array('value' => null))); + continue; + } + + $params[] = $this->convertReferenceValue($paramName, $annot->params[$paramName]); + } + + if (!$params) { + continue; + } + + $hasInjection = true; + + if ('__construct' === $name) { + $metadata->arguments = $params; + } else { + $metadata->methodCalls[] = array($name, $params); + } + } else if ($annot instanceof LookupMethod) { + $hasInjection = true; + + if ($method->isFinal()) { + throw new \RuntimeException(sprintf('The method "%s::%s" is marked as final and cannot be declared as lookup-method.', $className, $name)); + } + if ($method->isPrivate()) { + throw new \RuntimeException(sprintf('The method "%s::%s" is marked as private and cannot be declared as lookup-method.', $className, $name)); + } + if ($method->getParameters()) { + throw new \RuntimeException(sprintf('The method "%s::%s" must have a no-arguments signature if you want to use it as lookup-method.', $className, $name)); + } + + $metadata->lookupMethods[$name] = $this->convertReferenceValue('get' === substr($name, 0, 3) ? substr($name, 3) : $name, $annot); + } else if ($annot instanceof AfterSetup) { + if (!$method->isPublic()) { + throw new \RuntimeException(sprintf('The init method "%s::%s" must be public.', $method->class, $method->name)); + } + + $metadata->initMethod = $method->name; + } + } + } + + if (null == $metadata->id && !$hasInjection) { + return null; + } + + return $metadata; + } + + private function convertReferenceValue($name, AnnotReference $annot) + { + if (null === $annot->value) { + return new Reference($this->generateId($name), false !== $annot->required ? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE : ContainerInterface::NULL_ON_INVALID_REFERENCE); + } + + if (false === strpos($annot->value, '%')) { + return new Reference($annot->value, false !== $annot->required ? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE : ContainerInterface::NULL_ON_INVALID_REFERENCE); + } + + return $annot->value; + } + + private function generateId($name) + { + $name = preg_replace('/(?<=[a-zA-Z0-9])[A-Z]/', '_\\0', $name); + + return strtolower(strtr($name, '\\', '.')); + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Metadata/MetadataConverter.php b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Metadata/MetadataConverter.php new file mode 100644 index 0000000..a4f8ea5 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Metadata/MetadataConverter.php @@ -0,0 +1,85 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\DiExtraBundle\Metadata; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\Definition; +use Metadata\ClassHierarchyMetadata; + +class MetadataConverter +{ + /** + * Converts class hierarchy metadata to definition instances. + * + * @param ClassHierarchyMetadata $metadata + * @return array an array of Definition instances + */ + public function convert(ClassHierarchyMetadata $metadata) + { + static $count = 0; + $definitions = array(); + + $previous = null; + foreach ($metadata->classMetadata as $classMetadata) { + if (null === $previous && null === $classMetadata->parent) { + $definition = new Definition(); + } else { + $definition = new DefinitionDecorator( + $classMetadata->parent ?: $previous->id + ); + } + + $definition->setClass($classMetadata->name); + if (null !== $classMetadata->scope) { + $definition->setScope($classMetadata->scope); + } + if (null !== $classMetadata->public) { + $definition->setPublic($classMetadata->public); + } + if (null !== $classMetadata->abstract) { + $definition->setAbstract($classMetadata->abstract); + } + if (null !== $classMetadata->arguments) { + $definition->setArguments($classMetadata->arguments); + } + + $definition->setMethodCalls($classMetadata->methodCalls); + $definition->setTags($classMetadata->tags); + $definition->setProperties($classMetadata->properties); + + if (null === $classMetadata->id) { + $classMetadata->id = '_jms_di_extra.unnamed.service_'.$count++; + } + + if ($classMetadata->initMethod) { + if (!method_exists($definition, 'setInitMethod')) { + throw new \RuntimeException(sprintf('@AfterSetup is not available on your Symfony version.')); + } + + $definition->setInitMethod($classMetadata->initMethod); + } + + $definitions[$classMetadata->id] = $definition; + $previous = $classMetadata; + } + + return $definitions; + } +} \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/README b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/README new file mode 100644 index 0000000..72bab21 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/README @@ -0,0 +1,8 @@ +For documentation, see: + + Resources/doc + + +For license, see: + + Resources/meta/LICENSE \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Resources/config/services.xml b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Resources/config/services.xml new file mode 100644 index 0000000..c1ac0d4 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Resources/config/services.xml @@ -0,0 +1,50 @@ + + + + + + JMS\DiExtraBundle\Metadata\Driver\AnnotationDriver + + Metadata\MetadataFactory + Metadata\Cache\FileCache + + JMS\DiExtraBundle\Metadata\MetadataConverter + JMS\DiExtraBundle\HttpKernel\ControllerResolver + + JMS\DiExtraBundle\EventListener\TemplateListener + JMS\DiExtraBundle\EventListener\ControllerListener + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Resources/doc/index.rst b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Resources/doc/index.rst new file mode 100644 index 0000000..9b7ece5 --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Resources/doc/index.rst @@ -0,0 +1,290 @@ +======== +Overview +======== + +This bundle allows you to configure dependency injection using annotations. + +Installation +------------ +Add the following to your ``deps`` file:: + + [JMSDiExtraBundle] + git=https://github.com/schmittjoh/JMSDiExtraBundle.git + target=/bundles/JMS/DiExtraBundle + + ; Dependencies: + ;-------------- + [metadata] + git=https://github.com/schmittjoh/metadata.git + version=1.1.0 ; <- make sure to get 1.1, not 1.0 + +Then register the bundle with your kernel:: + + // in AppKernel::registerBundles() + $bundles = array( + // ... + new JMS\DiExtraBundle\JMSDiExtraBundle($this), + // ... + ); + +In addition, this bundle also requires the JMSAopBundle. See its documentation for +installation instructions:: + + https://github.com/schmittjoh/JMSAopBundle/blob/master/Resources/doc/index.rst + + +Make sure that you also register the namespaces with the autoloader:: + + // app/autoload.php + $loader->registerNamespaces(array( + // ... + 'JMS' => __DIR__.'/../vendor/bundles', + 'Metadata' => __DIR__.'/../vendor/metadata/src', + // ... + )); + + +Configuration +------------- +For optimal development performance (in production there is no difference either way), +it is recommended to explicitly configure the directories which should be scanned for +service classes (by default no directory is scanned):: + + jms_di_extra: + locations: + all_bundles: false + bundles: [FooBundle, AcmeBlogBundle, etc.] + directories: [%kernel.root_dir%/../src, some/other/dir] + +Usage +----- + +Non-Controller Classes +~~~~~~~~~~~~~~~~~~~~~~ + +Non-controller classes are configured, and managed by Symfony's DIC just like any +other service that you configure using YML, XML, or PHP. The only difference is +that you can do it via annotations which is a lot more convenient. + +You can use these annotations on services (for examples, see below): +@Service, @Inject, @InjectParams, @Observe, @Tag + +Note that you cannot use the @Inject annotation on private, or protected properties. +Likewise, the @InjectParams annotation does not work on protected, or private methods. + + +Controllers +~~~~~~~~~~~ + +Controllers are a special type of class which is also treated specially by this +bundle. The most notable difference is that you do not need to define these +classes as services. Yes, no services, but don't worry you can still use all of +the DIC's features, and even some more. + +- Constructor/Setter Injection:: + + em = $em; + $this->session = $session; + } + // ... some actions + } + + **Note:** Constructor Injection is not possible when a parent definition + also defines a constructor which is configured for injection. + +- Property Injection:: + + getMailer(); + } + } + + /** @DI\LookupMethod("mailer") */ + protected function getMailer() { /* empty body here */ } + } + +You can use this type of injection if you have a dependency that you do not +always need in the controller, and which is costly to initialize, like the +mailer in the example above. + + +Annotations +----------- + +@Inject +~~~~~~~~~ +This marks a property, or parameter for injection:: + + use JMS\DiExtraBundle\Annotation\Inject; + + class Controller + { + /** + * @Inject("security.context", required = false) + */ + private $securityContext; + + /** + * @Inject("%kernel.cache_dir%") + */ + private $cacheDir; + + /** + * @Inject + */ + private $session; + } + +If you do not specify the service explicitly, we will try to guess it based on the name +of the property or the parameter. + +@InjectParams +~~~~~~~~~~~~~~~ +This marks the parameters of a method for injection:: + + use JMS\DiExtraBundle\Annotation\Inject; + use JMS\DiExtraBundle\Annotation\InjectParams; + use JMS\DiExtraBundle\Annotation\Service; + + /** + * @Service + */ + class Listener + { + /** + * @InjectParams({ + * "em" = @Inject("doctrine.entity_manager") + * }) + */ + public function __construct(EntityManager $em, Session $session) + { + // ... + } + } + +If you don't define all parameters in the param map, we will try to guess which services +should be injected into the remaining parameters based on their name. + +@Service +~~~~~~~~ +Marks a class as service:: + + use JMS\DiExtraBundle\Annotation\Service; + + /** + * @Service("some.service.id", parent="another.service.id", public=false) + */ + class Listener + { + } + +If you do not explicitly define a service id, then we will generated a sensible default +based on the fully qualified class name for you. + +@Tag +~~~~ +Adds a tag to the service:: + + use JMS\DiExtraBundle\Annotation\Service; + use JMS\DiExtraBundle\Annotation\Tag; + + /** + * @Service + * @Tag("doctrine.event_listener", attributes = {"event" = "postGenerateSchema", lazy=true}) + */ + class Listener + { + // ... + } + +@Observe +~~~~~~~~ +Automatically registers a method as listener to a certain event:: + + use JMS\DiExtraBundle\Annotation\Observe; + use JMS\DiExtraBundle\Annotation\Service; + + /** + * @Service + */ + class RequestListener + { + /** + * @Observe("kernel.request", priority = 255) + */ + public function onKernelRequest() + { + // ... + } + } + +@Validator +~~~~~~~~~~ +Automatically registers the given class as constraint validator for the Validator component:: + + use JMS\DiExtraBundle\Annotation\Validator; + use Symfony\Component\Validator\Constraint; + use Symfony\Component\Validator\ConstraintValidator; + + /** + * @Validator("my_alias") + */ + class MyValidator extends ConstraintValidator + { + // ... + } + + class MyConstraint extends Constraint + { + // ... + public function validatedBy() + { + return 'my_alias'; + } + } + +The @Validator annotation also implies the @Service annotation if you do not specify it explicitly. +The alias which is passed to the @Validator annotation must match the string that is returned from +the ``validatedBy`` method of your constraint. + diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Resources/meta/LICENSE b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Resources/meta/LICENSE new file mode 100644 index 0000000..753842b --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Resources/meta/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/composer.json b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/composer.json new file mode 100644 index 0000000..cc6196c --- /dev/null +++ b/vendor/jms/di-extra-bundle/JMS/DiExtraBundle/composer.json @@ -0,0 +1,21 @@ +{ + "name": "jms/di-extra-bundle", + "description": "Allows to configure dependency injection using annotations", + "keywords": ["annotations","dependency injection"], + "type": "symfony-bundle", + "license": "Apache", + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "require": { + "symfony/framework-bundle": "2.*", + "jms/metadata": "1.1.*" + }, + "autoload": { + "psr-0": { "JMS\\DiExtraBundle": "" } + }, + "target-dir": "JMS/DiExtraBundle" +} diff --git a/vendor/jms/metadata/CHANGELOG.md b/vendor/jms/metadata/CHANGELOG.md new file mode 100644 index 0000000..74da57e --- /dev/null +++ b/vendor/jms/metadata/CHANGELOG.md @@ -0,0 +1,18 @@ +CHANGELOG +========= + +This changelog references all relevant changes: + +To get the diff between the two last versions, go to +https://github.com/schmittjoh/metadata/compare/1.0.0...1.1.0 + +* 1.1.0 (2011-10-04) + + * added support for metadata on interfaces + * added support for non annotation-based drivers + * added support for merging metadata + +This release is fully backwards compatible with the 1.0.0 release. Therefore, +the 1.0.x branch has been discontinued. + +* 1.0.0 (2011-07-09) diff --git a/vendor/jms/metadata/LICENSE b/vendor/jms/metadata/LICENSE new file mode 100644 index 0000000..f49a4e1 --- /dev/null +++ b/vendor/jms/metadata/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/vendor/jms/metadata/composer.json b/vendor/jms/metadata/composer.json new file mode 100644 index 0000000..e598e25 --- /dev/null +++ b/vendor/jms/metadata/composer.json @@ -0,0 +1,19 @@ +{ + "name": "jms/metadata", + "description": "Class/method/property metadata management in PHP", + "keywords": ["annotations","metadata","yaml","xml"], + "type": "library", + "license": "Apache", + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "require": { + "php": ">=5.3.0" + }, + "autoload": { + "psr-0": { "Metadata\\": "src/" } + } +} diff --git a/vendor/jms/metadata/src/Metadata/Cache/CacheInterface.php b/vendor/jms/metadata/src/Metadata/Cache/CacheInterface.php new file mode 100644 index 0000000..dbf3ccb --- /dev/null +++ b/vendor/jms/metadata/src/Metadata/Cache/CacheInterface.php @@ -0,0 +1,35 @@ +dir = rtrim($dir, '\\/'); + } + + public function loadClassMetadataFromCache(\ReflectionClass $class) + { + $path = $this->dir.'/'.strtr($class->getName(), '\\', '-').'.cache.php'; + if (!file_exists($path)) { + return null; + } + + return include $path; + } + + public function putClassMetadataInCache(ClassMetadata $metadata) + { + $path = $this->dir.'/'.strtr($metadata->name, '\\', '-').'.cache.php'; + file_put_contents($path, 'dir.'/'.strtr($class->getName(), '\\', '-').'.cache.php'; + if (file_exists($path)) { + unlink($path); + } + } +} \ No newline at end of file diff --git a/vendor/jms/metadata/src/Metadata/ClassHierarchyMetadata.php b/vendor/jms/metadata/src/Metadata/ClassHierarchyMetadata.php new file mode 100644 index 0000000..c90a5e4 --- /dev/null +++ b/vendor/jms/metadata/src/Metadata/ClassHierarchyMetadata.php @@ -0,0 +1,55 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Metadata; + +/** + * Represents the metadata for the entire class hierarchy. + * + * @author Johannes M. Schmitt + */ +class ClassHierarchyMetadata +{ + public $classMetadata = array(); + + public function addClassMetadata(ClassMetadata $metadata) + { + $this->classMetadata[$metadata->name] = $metadata; + } + + public function getRootClassMetadata() + { + return reset($this->classMetadata); + } + + public function getOutsideClassMetadata() + { + return end($this->classMetadata); + } + + public function isFresh($timestamp) + { + foreach ($this->classMetadata as $metadata) { + if (!$metadata->isFresh($timestamp)) { + return false; + } + } + + return true; + } +} \ No newline at end of file diff --git a/vendor/jms/metadata/src/Metadata/ClassMetadata.php b/vendor/jms/metadata/src/Metadata/ClassMetadata.php new file mode 100644 index 0000000..2479a4f --- /dev/null +++ b/vendor/jms/metadata/src/Metadata/ClassMetadata.php @@ -0,0 +1,98 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Metadata; + +/** + * Base class for class metadata. + * + * This class is intended to be extended to add your own application specific + * properties, and flags. + * + * @author Johannes M. Schmitt + */ +class ClassMetadata implements \Serializable +{ + public $name; + public $reflection; + public $methodMetadata = array(); + public $propertyMetadata = array(); + public $fileResources = array(); + public $createdAt; + + public function __construct($name) + { + $this->name = $name; + + $this->reflection = new \ReflectionClass($name); + $this->createdAt = time(); + } + + public function addMethodMetadata(MethodMetadata $metadata) + { + $this->methodMetadata[$metadata->name] = $metadata; + } + + public function addPropertyMetadata(PropertyMetadata $metadata) + { + $this->propertyMetadata[$metadata->name] = $metadata; + } + + public function isFresh($timestamp = null) + { + if (null === $timestamp) { + $timestamp = $this->createdAt; + } + + foreach ($this->fileResources as $filepath) { + if (!file_exists($filepath)) { + return false; + } + + if ($timestamp < filemtime($filepath)) { + return false; + } + } + + return true; + } + + public function serialize() + { + return serialize(array( + $this->name, + $this->methodMetadata, + $this->propertyMetadata, + $this->fileResources, + $this->createdAt, + )); + } + + public function unserialize($str) + { + list( + $this->name, + $this->methodMetadata, + $this->propertyMetadata, + $this->fileResources, + $this->createdAt + ) = unserialize($str); + + $this->reflection = new \ReflectionClass($this->name); + } +} \ No newline at end of file diff --git a/vendor/jms/metadata/src/Metadata/Driver/AbstractFileDriver.php b/vendor/jms/metadata/src/Metadata/Driver/AbstractFileDriver.php new file mode 100644 index 0000000..b02f387 --- /dev/null +++ b/vendor/jms/metadata/src/Metadata/Driver/AbstractFileDriver.php @@ -0,0 +1,42 @@ + + */ +abstract class AbstractFileDriver implements DriverInterface +{ + private $locator; + + public function __construct(FileLocatorInterface $locator) + { + $this->locator = $locator; + } + + public function loadMetadataForClass(\ReflectionClass $class) + { + if (null === $path = $this->locator->findFileForClass($class, $this->getExtension())) { + return null; + } + + return $this->loadMetadataFromFile($class, $path); + } + + /** + * Parses the content of the file, and converts it to the desired metadata. + * + * @param string $file + * @return ClassMetadata|null + */ + abstract protected function loadMetadataFromFile(\ReflectionClass $class, $file); + + /** + * Returns the extension of the file. + * + * @return string + */ + abstract protected function getExtension(); +} \ No newline at end of file diff --git a/vendor/jms/metadata/src/Metadata/Driver/DriverChain.php b/vendor/jms/metadata/src/Metadata/Driver/DriverChain.php new file mode 100644 index 0000000..809ccf1 --- /dev/null +++ b/vendor/jms/metadata/src/Metadata/Driver/DriverChain.php @@ -0,0 +1,40 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Metadata\Driver; + +final class DriverChain implements DriverInterface +{ + private $drivers; + + public function __construct(array $drivers) + { + $this->drivers = $drivers; + } + + public function loadMetadataForClass(\ReflectionClass $class) + { + foreach ($this->drivers as $driver) { + if (null !== $metadata = $driver->loadMetadataForClass($class)) { + return $metadata; + } + } + + return null; + } +} \ No newline at end of file diff --git a/vendor/jms/metadata/src/Metadata/Driver/DriverInterface.php b/vendor/jms/metadata/src/Metadata/Driver/DriverInterface.php new file mode 100644 index 0000000..57ed66d --- /dev/null +++ b/vendor/jms/metadata/src/Metadata/Driver/DriverInterface.php @@ -0,0 +1,24 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Metadata\Driver; + +interface DriverInterface +{ + function loadMetadataForClass(\ReflectionClass $class); +} diff --git a/vendor/jms/metadata/src/Metadata/Driver/FileLocator.php b/vendor/jms/metadata/src/Metadata/Driver/FileLocator.php new file mode 100644 index 0000000..41f7b99 --- /dev/null +++ b/vendor/jms/metadata/src/Metadata/Driver/FileLocator.php @@ -0,0 +1,29 @@ +dirs = $dirs; + } + + public function findFileForClass(\ReflectionClass $class, $extension) + { + foreach ($this->dirs as $prefix => $dir) { + if (0 !== strpos($class->getNamespaceName(), $prefix)) { + continue; + } + + $path = $dir.'/'.str_replace('\\', '.', substr($class->getName(), strlen($prefix)+1)).'.'.$extension; + if (file_exists($path)) { + return $path; + } + } + + return null; + } +} \ No newline at end of file diff --git a/vendor/jms/metadata/src/Metadata/Driver/FileLocatorInterface.php b/vendor/jms/metadata/src/Metadata/Driver/FileLocatorInterface.php new file mode 100644 index 0000000..5092f3d --- /dev/null +++ b/vendor/jms/metadata/src/Metadata/Driver/FileLocatorInterface.php @@ -0,0 +1,8 @@ +container = $container; + $this->realDriverId = $realDriverId; + } + + public function loadMetadataForClass(\ReflectionClass $class) + { + return $this->container->get($this->realDriverId)->loadMetadataForClass($class); + } +} \ No newline at end of file diff --git a/vendor/jms/metadata/src/Metadata/MergeableClassMetadata.php b/vendor/jms/metadata/src/Metadata/MergeableClassMetadata.php new file mode 100644 index 0000000..13ec158 --- /dev/null +++ b/vendor/jms/metadata/src/Metadata/MergeableClassMetadata.php @@ -0,0 +1,23 @@ +name = $object->name; + $this->reflection = $object->reflection; + $this->methodMetadata = array_merge($this->methodMetadata, $object->methodMetadata); + $this->propertyMetadata = array_merge($this->propertyMetadata, $object->propertyMetadata); + $this->fileResources = array_merge($this->fileResources, $object->fileResources); + + if ($object->createdAt < $this->createdAt) { + $this->createdAt = $object->createdAt; + } + } +} \ No newline at end of file diff --git a/vendor/jms/metadata/src/Metadata/MergeableInterface.php b/vendor/jms/metadata/src/Metadata/MergeableInterface.php new file mode 100644 index 0000000..1da234f --- /dev/null +++ b/vendor/jms/metadata/src/Metadata/MergeableInterface.php @@ -0,0 +1,8 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Metadata; + +use Metadata\Driver\DriverInterface; +use Metadata\Cache\CacheInterface; + +final class MetadataFactory implements MetadataFactoryInterface +{ + private $driver; + private $cache; + private $loadedMetadata = array(); + private $loadedClassMetadata = array(); + private $hierarchyMetadataClass; + private $includeInterfaces = false; + private $debug; + + public function __construct(DriverInterface $driver, $hierarchyMetadataClass = 'Metadata\ClassHierarchyMetadata', $debug = false) + { + $this->driver = $driver; + $this->hierarchyMetadataClass = $hierarchyMetadataClass; + $this->debug = $debug; + } + + public function setIncludeInterfaces($bool) + { + $this->includeInterfaces = (Boolean) $bool; + } + + public function setCache(CacheInterface $cache) + { + $this->cache = $cache; + } + + public function getMetadataForClass($className) + { + if (isset($this->loadedMetadata[$className])) { + return $this->loadedMetadata[$className]; + } + + $metadata = null; + foreach ($this->getClassHierarchy($className) as $class) { + if (isset($this->loadedClassMetadata[$name = $class->getName()])) { + $this->addClassMetadata($metadata, $this->loadedClassMetadata[$name]); + continue; + } + + // check the cache + if (null !== $this->cache + && (null !== $classMetadata = $this->cache->loadClassMetadataFromCache($class))) { + if ($this->debug && !$classMetadata->isFresh()) { + $this->cache->evictClassMetadataFromCache($classMetadata->reflection); + } else { + $this->loadedClassMetadata[$name] = $classMetadata; + $this->addClassMetadata($metadata, $classMetadata); + continue; + } + } + + // load from source + if (null !== $classMetadata = $this->driver->loadMetadataForClass($class)) { + $this->loadedClassMetadata[$name] = $classMetadata; + $this->addClassMetadata($metadata, $classMetadata); + + if (null !== $this->cache) { + $this->cache->putClassMetadataInCache($classMetadata); + } + + continue; + } + } + + return $this->loadedMetadata[$className] = $metadata; + } + + private function addClassMetadata(&$metadata, $toAdd) + { + if ($toAdd instanceof MergeableInterface) { + if (null === $metadata) { + $metadata = clone $toAdd; + } else { + $metadata->merge($toAdd); + } + } else { + if (null === $metadata) { + $metadata = new $this->hierarchyMetadataClass; + } + + $metadata->addClassMetadata($toAdd); + } + } + + private function getClassHierarchy($class) + { + $classes = array(); + $refl = new \ReflectionClass($class); + + do { + $classes[] = $refl; + } while (false !== $refl = $refl->getParentClass()); + + $classes = array_reverse($classes, false); + + if (!$this->includeInterfaces) { + return $classes; + } + + $addedInterfaces = array(); + $newHierarchy = array(); + + foreach ($classes as $class) { + foreach ($class->getInterfaces() as $interface) { + if (isset($addedInterfaces[$interface->getName()])) { + continue; + } + $addedInterfaces[$interface->getName()] = true; + + $newHierarchy[] = $interface; + } + + $newHierarchy[] = $class; + } + + return $newHierarchy; + } +} \ No newline at end of file diff --git a/vendor/jms/metadata/src/Metadata/MetadataFactoryInterface.php b/vendor/jms/metadata/src/Metadata/MetadataFactoryInterface.php new file mode 100644 index 0000000..d7fa68a --- /dev/null +++ b/vendor/jms/metadata/src/Metadata/MetadataFactoryInterface.php @@ -0,0 +1,24 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Metadata; + +interface MetadataFactoryInterface +{ + function getMetadataForClass($className); +} \ No newline at end of file diff --git a/vendor/jms/metadata/src/Metadata/MethodMetadata.php b/vendor/jms/metadata/src/Metadata/MethodMetadata.php new file mode 100644 index 0000000..db2d501 --- /dev/null +++ b/vendor/jms/metadata/src/Metadata/MethodMetadata.php @@ -0,0 +1,61 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Metadata; + +/** + * Base class for method metadata. + * + * This class is intended to be extended to add your application specific + * properties, and flags. + * + * @author Johannes M. Schmitt + */ +class MethodMetadata implements \Serializable +{ + public $class; + public $name; + public $reflection; + + public function __construct($class, $name) + { + $this->class = $class; + $this->name = $name; + + $this->reflection = new \ReflectionMethod($class, $name); + $this->reflection->setAccessible(true); + } + + public function invoke($obj, array $args = array()) + { + return $this->reflection->invokeArgs($obj, $args); + } + + public function serialize() + { + return serialize(array($this->class, $this->name)); + } + + public function unserialize($str) + { + list($this->class, $this->name) = unserialize($str); + + $this->reflection = new \ReflectionMethod($this->class, $this->name); + $this->reflection->setAccessible(true); + } +} \ No newline at end of file diff --git a/vendor/jms/metadata/src/Metadata/PropertyMetadata.php b/vendor/jms/metadata/src/Metadata/PropertyMetadata.php new file mode 100644 index 0000000..a581ce0 --- /dev/null +++ b/vendor/jms/metadata/src/Metadata/PropertyMetadata.php @@ -0,0 +1,69 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Metadata; + +/** + * Base class for property metadata. + * + * This class is intended to be extended to add your application specific + * properties, and flags. + * + * @author Johannes M. Schmitt + */ +class PropertyMetadata implements \Serializable +{ + public $class; + public $name; + public $reflection; + + public function __construct($class, $name) + { + $this->class = $class; + $this->name = $name; + + $this->reflection = new \ReflectionProperty($class, $name); + $this->reflection->setAccessible(true); + } + + public function getValue($obj) + { + return $this->reflection->getValue($obj); + } + + public function setValue($obj, $value) + { + $this->reflection->setValue($obj, $value); + } + + public function serialize() + { + return serialize(array( + $this->class, + $this->name, + )); + } + + public function unserialize($str) + { + list($this->class, $this->name) = unserialize($str); + + $this->reflection = new \ReflectionProperty($this->class, $this->name); + $this->reflection->setAccessible(true); + } +} \ No newline at end of file diff --git a/vendor/jms/metadata/src/Metadata/Version.php b/vendor/jms/metadata/src/Metadata/Version.php new file mode 100644 index 0000000..0ea37d6 --- /dev/null +++ b/vendor/jms/metadata/src/Metadata/Version.php @@ -0,0 +1,24 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Metadata; + +final class Version +{ + const VERSION = '1.1.1'; +} diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/PreAuthorize.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/PreAuthorize.php new file mode 100644 index 0000000..0128138 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/PreAuthorize.php @@ -0,0 +1,59 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Annotation; + +use JMS\SecurityExtraBundle\Exception\InvalidArgumentException; + +/** + * Annotation for expression-based access control. + * + * @Annotation + * @Target("METHOD") + * + * @author Johannes M. Schmitt + */ +final class PreAuthorize +{ + /** + * @Required + * @var string + */ + public $expr; + + public function __construct() + { + if (0 === func_num_args()) { + return; + } + $values = func_get_arg(0); + + if (isset($values['value'])) { + $values['expr'] = $values['value']; + } + if (!isset($values['expr'])) { + throw new InvalidArgumentException('The "expr" attribute must be set for annotation @PreAuthorize.'); + } + + if (!is_string($values['expr'])) { + throw new InvalidArgumentException(sprintf('The "expr" attribute of annotation @PreAuthorize must be a string, but got "%s".', gettype($values['expr']))); + } + + $this->expr = $values['expr']; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/RunAs.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/RunAs.php new file mode 100644 index 0000000..94de7a3 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/RunAs.php @@ -0,0 +1,42 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Annotation; + +use JMS\SecurityExtraBundle\Exception\InvalidArgumentException; + +/** + * @Annotation + * @Target("METHOD") + */ +final class RunAs +{ + public $roles; + + public function __construct(array $values) + { + if (isset($values['value'])) { + $values['roles'] = $values['value']; + } + if (!isset($values['roles'])) { + throw new InvalidArgumentException('"roles" must be defined for RunAs annotation.'); + } + + $this->roles = array_map('trim', explode(',', $values['roles'])); + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/SatisfiesParentSecurityPolicy.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/SatisfiesParentSecurityPolicy.php new file mode 100644 index 0000000..e087f2f --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/SatisfiesParentSecurityPolicy.php @@ -0,0 +1,81 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Annotation; + +/** + * This must be declared on classes which inherit from classes that have + * requested method invocation securing capabilities. + * + * It indicates to the analyzer that the developer is aware of these security + * restrictions, and has applied them to the root class in an appropriate + * fashion. + * + * We cannot do this automatically without properly analyzing the control flow, + * and in some cases it is not possible at all. See the following example: + * + * + * // child class + * public function editComment($commentId) + * { + * // retrieve comment from database + * $comment = $this->entityManager->find($commentId); + * + * return parent::editComment($comment); + * } + * + * // base class which is inherited from + * /** + * * @SecureParam(name="comment", permissions="EDIT") + * *\/ + * public function editComment(Comment $comment) + * { + * // do some supposedly secure action + * } + * + * + * The above example can be rewritten so that we can apply security checks + * automatically: + * + * + * // child class + * public function editComment($commentId) + * { + * // retrieve comment from database + * $comment = $this->entityManager->find($commentId); + * + * return $this->doEditComment($comment); + * } + * + * // base class which is inherited from + * /** + * * @SecureParam(name="comment", permissions="EDIT") + * *\/ + * protected function doEditComment(Comment $comment) + * { + * // do some secure action + * } + * + * + * @Annotation + * @Target("METHOD") + * @author Johannes M. Schmitt + */ +final class SatisfiesParentSecurityPolicy +{ +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/Secure.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/Secure.php new file mode 100644 index 0000000..bffd8fd --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/Secure.php @@ -0,0 +1,45 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Annotation; + +use JMS\SecurityExtraBundle\Exception\InvalidArgumentException; + +/** + * Represents a @Secure annotation. + * + * @Annotation + * @Target("METHOD") + * @author Johannes M. Schmitt + */ +final class Secure +{ + public $roles; + + public function __construct(array $values) + { + if (isset($values['value'])) { + $values['roles'] = $values['value']; + } + if (!isset($values['roles'])) { + throw new InvalidArgumentException('You must define a "roles" attribute for each Secure annotation.'); + } + + $this->roles = array_map('trim', explode(',', $values['roles'])); + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/SecureParam.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/SecureParam.php new file mode 100644 index 0000000..ec098b7 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/SecureParam.php @@ -0,0 +1,48 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Annotation; + +use JMS\SecurityExtraBundle\Exception\InvalidArgumentException; + +/** + * Represents a @SecureParam annotation. + * + * @Annotation + * @Target("METHOD") + * @author Johannes M. Schmitt + */ +final class SecureParam +{ + public $name; + public $permissions; + + public function __construct(array $values) + { + if (!isset($values['name'])) { + throw new InvalidArgumentException('You must define a "name" attribute for each SecureParam annotation.'); + } + if (!isset($values['permissions'])) { + throw new InvalidArgumentException('You must define a "permissions" attribute for each SecureParam annotation.'); + } + + $this->name = $values['name']; + + $this->permissions = array_map('trim', explode(',', $values['permissions'])); + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/SecureReturn.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/SecureReturn.php new file mode 100644 index 0000000..35e071e --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Annotation/SecureReturn.php @@ -0,0 +1,45 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Annotation; + +use JMS\SecurityExtraBundle\Exception\InvalidArgumentException; + +/** + * Represents a @SecureReturn annotation. + * + * @Annotation + * @Target("METHOD") + * @author Johannes M. Schmitt + */ +final class SecureReturn +{ + public $permissions; + + public function __construct(array $values) + { + if (isset($values['value'])) { + $values['permissions'] = $values['value']; + } + if (!isset($values['permissions'])) { + throw new InvalidArgumentException('You must define a "permissions" attribute for each SecureReturn annotation.'); + } + + $this->permissions = array_map('trim', explode(',', $values['permissions'])); + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/CHANGELOG-1.1.md b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/CHANGELOG-1.1.md new file mode 100644 index 0000000..a76156b --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/CHANGELOG-1.1.md @@ -0,0 +1,38 @@ +This document details all changes from JMSSecurityExtraBundle 1.0.x to 1.1: + +- The configuration option "secure_controllers" has been removed. This setting is + now automatically enabled, but it requires the JMSDiExtraBundle. + +- The dependencies of this bundle have changed: + + * The metadata library 1.1 version is now required instead of the 1.0 version + (if you are using the Standard Edition, just change the "version=origin/1.0.x" + line from your deps file to "version=1.1.0"). + * The JMSAopBundle is now required. For installation instructions, please see + https://github.com/schmittjoh/JMSAopBundle + * The JMSDiExtraBundle is now required if you want to secure your non-service + controllers (if you only have service controllers, you don't need it). For + installation instructions, see https://github.com/schmittjoh/JMSDiExtraBundle + +- The attribute "IS_IDDQD" has been renamed to "ROLE_IDDQD" + +- A powerful expression-based authorization language has been added which works + in combination with the existing voting system. Since it is much more powerful + than the built-in voters, and also much faster, you are highly encouraged to + migrate your existing authorization rules to expressions, and eventually disable + the built-in voters entirely. Some examples for how to convert simple attributes + to their equivalent expressions are listed below: + + * IS_AUTHENTICATED_ANONYMOUSLY -> "permitAll" + * IS_AUTHENTICATED_REMEMBERED -> "isAuthenticated()" + * IS_AUTHENTICATED_FULLY -> "isFullyAuthenticated()" + * ROLE_FOO -> "hasRole('ROLE_FOO')" + +- The ability to configure method access control (e.g. for controller actions) + in the DI configuration has been added. Note that for non-service controllers + the JMSDiExtraBundle is required. + +- The "is_expr_granted" Twig function has been added if you want to check an + expression from a Twig template. + + diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/AccessControlConfiguration.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/AccessControlConfiguration.php new file mode 100644 index 0000000..dc547a1 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/AccessControlConfiguration.php @@ -0,0 +1,90 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\DependencyInjection; + +use Symfony\Component\Config\Definition\ConfigurationInterface; + +use Symfony\Component\HttpKernel\Kernel; + +use Symfony\Bundle\SecurityBundle\DependencyInjection\MainConfiguration as BaseConfiguration; +use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AbstractFactory; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; + +/** + * Enhances the access_control section configuration. + * + * @author Johannes M. Schmitt + */ +class AccessControlConfiguration implements ConfigurationInterface +{ + /** + * Generates the configuration tree builder. + * + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder + */ + public function getConfigTreeBuilder() + { + $tb = new TreeBuilder(); + $rootNode = $tb->root('security'); + + $rootNode + ->ignoreExtraKeys() + ->fixXmlConfig('rule', 'access_control') + ->children() + ->arrayNode('access_control') + ->cannotBeOverwritten() + ->prototype('array') + ->fixXmlConfig('role') + ->validate() + ->always(function($v) { + if (!empty($v['roles']) && isset($v['access'])) { + throw new \Exception('"roles", and "access" cannot be set at the same time.'); + } + + if (empty($v['roles'])) { + unset($v['roles']); + } + + return $v; + }) + ->end() + ->children() + ->scalarNode('requires_channel')->defaultNull()->end() + ->scalarNode('path')->defaultNull()->end() + ->scalarNode('host')->defaultNull()->end() + ->scalarNode('ip')->defaultNull()->end() + ->arrayNode('methods') + ->beforeNormalization()->ifString()->then(function($v) { return preg_split('/\s*,\s*/', $v); })->end() + ->prototype('scalar')->end() + ->end() + ->arrayNode('roles') + ->beforeNormalization()->ifString()->then(function($v) { return preg_split('/\s*,\s*/', $v); })->end() + ->prototype('scalar')->end() + ->end() + ->scalarNode('access')->end() + ->end() + ->end() + ->end() + ->end() + ; + + return $tb; + } +} diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Compiler/AddAfterInvocationProvidersPass.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Compiler/AddAfterInvocationProvidersPass.php new file mode 100644 index 0000000..64547b1 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Compiler/AddAfterInvocationProvidersPass.php @@ -0,0 +1,52 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Collects after invocation providers. + * + * @author Johannes M. Schmitt + */ +class AddAfterInvocationProvidersPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('security.access.after_invocation_manager')) { + return; + } + + $providers = array(); + foreach (array_keys($container->findTaggedServiceIds('security.after_invocation.provider')) as $id) { + if ('security.access.after_invocation.acl_provider' === $id && !$container->has('security.acl.provider')) { + continue; + } + + $providers[] = new Reference($id); + } + + $container + ->getDefinition('security.access.after_invocation_manager') + ->setArguments(array($providers)) + ; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Compiler/AddExpressionCompilersPass.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Compiler/AddExpressionCompilersPass.php new file mode 100644 index 0000000..6b63a42 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Compiler/AddExpressionCompilersPass.php @@ -0,0 +1,66 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\DependencyInjection\Compiler; + +use JMS\SecurityExtraBundle\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +class AddExpressionCompilersPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('security.expressions.compiler')) { + return; + } + + $compilerDef = $container->getDefinition('security.expressions.compiler'); + foreach ($container->findTaggedServiceIds('security.expressions.function_compiler') + as $id => $attr) { + $compilerDef->addMethodCall('addFunctionCompiler', array(new Reference($id))); + } + + foreach ($container->findTaggedServiceIds('security.expressions.type_compiler') + as $id => $attr) { + $compilerDef->addMethodCall('addTypeCompiler', array(new Reference($id))); + } + + $serviceMap = $parameterMap = array(); + foreach ($container->findTaggedServiceIds('security.expressions.variable') as $id => $attributes) { + foreach ($attributes as $attr) { + if (!isset($attr['variable']) || (!isset($attr['service']) && !isset($attr['parameter']))) { + throw new RuntimeException(sprintf('"variable", and either "service" or "parameter" must be given for tag "security.expressions.variable" for service id "%s".', $id)); + } + + if (isset($attr['service'])) { + $serviceMap[$attr['variable']] = $attr['service']; + $container + ->findDefinition($attr['service']) + ->setPublic(true) + ; + } else { + $parameterMap[$attr['variable']] = $attr['parameter']; + } + } + } + $container->getDefinition('security.expressions.variable_compiler') + ->addMethodCall('setMaps', array($serviceMap, $parameterMap)); + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Compiler/CollectSecuredServicesPass.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Compiler/CollectSecuredServicesPass.php new file mode 100644 index 0000000..b813b89 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Compiler/CollectSecuredServicesPass.php @@ -0,0 +1,43 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Collects secured services. + * + * @author Johannes M. Schmitt + */ +class CollectSecuredServicesPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + $securedClasses = array(); + foreach ($container->findTaggedServiceIds('security.secure_service') as $id => $attr) { + $securedClasses[] = $container->getDefinition($id)->getClass(); + } + + $container + ->getDefinition('security.access.pointcut') + ->addMethodCall('setSecuredClasses', array($securedClasses)) + ; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Compiler/DisableVotersPass.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Compiler/DisableVotersPass.php new file mode 100644 index 0000000..fb35bb9 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Compiler/DisableVotersPass.php @@ -0,0 +1,46 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +class DisableVotersPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if ($container->getParameter('security.role_voter.disabled')) { + $container->removeDefinition('security.access.role_hierarchy_voter'); + $container->removeDefinition('security.access.simple_role_voter'); + } + + if ($container->getParameter('security.authenticated_voter.disabled')) { + $container->removeDefinition('security.access.authenticated_voter'); + } + + if ($container->hasDefinition('security.acl.voter.basic_permissions')) { + if ($container->getParameter('security.acl_voter.disabled')) { + $container->removeDefinition('security.acl.voter.basic_permissions'); + } else { + $container->getDefinition('security.acl.voter.basic_permissions') + ->setClass('JMS\SecurityExtraBundle\Security\Acl\Voter\AclVoter'); + } + } + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Compiler/IntegrationPass.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Compiler/IntegrationPass.php new file mode 100644 index 0000000..abfcdb2 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Compiler/IntegrationPass.php @@ -0,0 +1,22 @@ +hasAlias('security.acl.provider') + && !$container->hasDefinition('security.acl.provider')) { + $container->removeDefinition('security.acl.permission_evaluator'); + } + + if ($container->hasDefinition('security.role_hierarchy')) { + $container->getDefinition('security.role_hierarchy') + ->setPublic(true); + } + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Configuration.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Configuration.php new file mode 100644 index 0000000..70cf1d5 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/Configuration.php @@ -0,0 +1,64 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\DependencyInjection; + +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; + +class Configuration implements ConfigurationInterface +{ + public function getConfigTreeBuilder() + { + $tb = new TreeBuilder(); + $tb + ->root('jms_security_extra') + ->validate() + ->always(function($v) { + if ($v['method_access_control'] && !$v['expressions']) { + throw new \Exception('You need to enable expressions if you want to configure method access via the DI config.'); + } + + return $v; + }) + ->end() + ->children() + ->booleanNode('secure_all_services')->defaultFalse()->end() + ->booleanNode('enable_iddqd_attribute')->defaultFalse()->end() + ->scalarNode('cache_dir')->cannotBeEmpty()->defaultValue('%kernel.cache_dir%/jms_security')->end() + ->booleanNode('expressions')->defaultFalse()->end() + ->arrayNode('voters') + ->addDefaultsIfNotSet() + ->canBeUnset() + ->children() + ->booleanNode('disable_authenticated')->defaultFalse()->end() + ->booleanNode('disable_role')->defaultFalse()->end() + ->booleanNode('disable_acl')->defaultFalse()->end() + ->end() + ->end() + ->arrayNode('method_access_control') + ->useAttributeAsKey('pattern') + ->prototype('scalar')->isRequired()->cannotBeEmpty()->end() + ->end() + ->end() + ->end() + ; + + return $tb; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/JMSSecurityExtraExtension.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/JMSSecurityExtraExtension.php new file mode 100644 index 0000000..cd2e1c2 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/JMSSecurityExtraExtension.php @@ -0,0 +1,100 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\DependencyInjection; + +use Symfony\Component\DependencyInjection\Reference; + +use JMS\SecurityExtraBundle\Exception\RuntimeException; +use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * JMSSecurityExtraExtension. + * + * @author Johannes M. Schmitt + */ +class JMSSecurityExtraExtension extends Extension +{ + public function load(array $configs, ContainerBuilder $container) + { + $bundles = $container->getParameter('kernel.bundles'); + if (!isset($bundles['JMSAopBundle'])) { + throw new RuntimeException('The JMSSecurityExtraBundle requires the JMSAopBundle, please make sure to enable it in your AppKernel.'); + } + + $config = $this->processConfiguration(new Configuration(), $configs); + + $loader = new XmlFileLoader($container, new FileLocator(array(__DIR__.'/../Resources/config/'))); + $loader->load('services.xml'); + + $container->setParameter('security.access.secure_all_services', $config['secure_all_services']); + + $cacheDir = $container->getParameterBag()->resolveValue($config['cache_dir']); + if (!is_dir($cacheDir)) { + if (false === @mkdir($cacheDir, 0777, true)) { + throw new RuntimeException(sprintf('Could not create cache directory "%s".', $cacheDir)); + } + } + $container->setParameter('security.extra.cache_dir', $cacheDir); + + if ($config['expressions']) { + $loader->load('security_expressions.xml'); + + if (!is_dir($cacheDir.'/expressions')) { + if (false === @mkdir($cacheDir.'/expressions', 0777, true)) { + throw new RuntimeException(sprintf('Could not create cache directory "%s".', $cacheDir.'/expressions')); + } + } + + $container->getDefinition('security.expressions.voter') + ->addMethodCall('setCacheDir', array($cacheDir.'/expressions')); + } + + $disableAllVoters = !isset($config['voters']); + $container->setParameter('security.authenticated_voter.disabled', + $disableAllVoters || $config['voters']['disable_authenticated']); + $container->setParameter('security.role_voter.disabled', + $disableAllVoters || $config['voters']['disable_role']); + $container->setParameter('security.acl_voter.disabled', + $disableAllVoters || $config['voters']['disable_acl']); + + if ($config['enable_iddqd_attribute']) { + $container + ->getDefinition('security.extra.iddqd_voter') + ->addTag('security.voter') + ; + + // FIXME: Also add an iddqd after invocation provider + } + + if ($config['method_access_control']) { + $driverDef = $container->getDefinition('security.extra.driver_chain'); + $args = $driverDef->getArguments(); + array_unshift($args[0], new Reference('security.extra.config_driver')); + $driverDef->setArguments($args); + + $container->setParameter('security.access.method_access_control', + $config['method_access_control']); + } + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/SecurityExtension.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/SecurityExtension.php new file mode 100644 index 0000000..96ddf99 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/DependencyInjection/SecurityExtension.php @@ -0,0 +1,130 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\DependencyInjection; + +use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension as BaseSecurityExtension; +use Symfony\Component\HttpKernel\Kernel; +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\Config\FileLocator; + +/** + * Enhances the access_control section of the SecurityBundle. + * + * @author Johannes M. Schmitt + */ +class SecurityExtension extends Extension +{ + private $extension; + + public function __construct(BaseSecurityExtension $extension) + { + $this->extension = $extension; + } + + public function getAlias() + { + return $this->extension->getAlias(); + } + + public function getNamespace() + { + return $this->extension->getNamespace(); + } + + public function getXsdValidationBasePath() + { + return $this->extension->getXsdValidationBasePath(); + } + + public function getClassesToCompile() + { + return array_merge(parent::getClassesToCompile(), $this->extension->getClassesToCompile()); + } + + public function load(array $configs, ContainerBuilder $container) + { + $parentConfigs = array(); + + foreach ($configs as $config) { + if (isset($config['rule'])) { + unset($config['rule']); + } + if (isset($config['access_control'])) { + unset($config['access_control']); + } + + $parentConfigs[] = $config; + } + $this->extension->load($parentConfigs, $container); + + $config = $this->processConfiguration(new AccessControlConfiguration(), $configs); + $this->createAuthorization($config, $container); + } + + public function __call($method, array $args) + { + return call_user_func_array(array($this->extension, $method), $args); + } + + private function createAuthorization($config, ContainerBuilder $container) + { + if (!$config['access_control']) { + return; + } + + $this->addClassesToCompile(array( + 'Symfony\\Component\\Security\\Http\\AccessMap', + )); + + foreach ($config['access_control'] as $access) { + $matcher = $this->invokeParent('createRequestMatcher', array( + $container, + $access['path'], + $access['host'], + count($access['methods']) === 0 ? null : $access['methods'], + $access['ip'] + )); + + if (isset($access['roles'])) { + $attributes = $access['roles']; + } else { + $def = new DefinitionDecorator('security.expressions.expression'); + $def->addArgument($access['access']); + $container->setDefinition($exprId = 'security.expressions.expression.'.sha1($access['access']), $def); + + $attributes = array(new Reference($exprId)); + } + + $container->getDefinition('security.access_map') + ->addMethodCall('add', array($matcher, $attributes, $access['requires_channel'])); + } + } + + private function invokeParent($method, array $args = array()) + { + $ref = new \ReflectionMethod($this->extension, $method); + $ref->setAccessible(true); + + return $ref->invokeArgs($this->extension, $args); + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Exception/Exception.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Exception/Exception.php new file mode 100644 index 0000000..b6606f9 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Exception/Exception.php @@ -0,0 +1,28 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Exception; + +/** + * Base exception for the SecurityExtraBundle. + * + * @author Johannes M. Schmitt + */ +interface Exception +{ +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Exception/InvalidArgumentException.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Exception/InvalidArgumentException.php new file mode 100644 index 0000000..6a9f2ae --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Exception/InvalidArgumentException.php @@ -0,0 +1,28 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Exception; + +/** + * InvalidArgumentException for the SecurityExtraBundle. + * + * @author Johannes M. Schmitt + */ +class InvalidArgumentException extends \InvalidArgumentException implements Exception +{ +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Exception/RuntimeException.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Exception/RuntimeException.php new file mode 100644 index 0000000..b7bb573 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Exception/RuntimeException.php @@ -0,0 +1,28 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Exception; + +/** + * RuntimeException for the SecurityExtraBundle. + * + * @author Johannes M. Schmitt + */ +class RuntimeException extends \RuntimeException implements Exception +{ +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/JMSSecurityExtraBundle.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/JMSSecurityExtraBundle.php new file mode 100644 index 0000000..6f5c0e3 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/JMSSecurityExtraBundle.php @@ -0,0 +1,59 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle; + +use JMS\SecurityExtraBundle\DependencyInjection\SecurityExtension; +use JMS\SecurityExtraBundle\DependencyInjection\Compiler\IntegrationPass; +use JMS\SecurityExtraBundle\DependencyInjection\Compiler\DisableVotersPass; +use JMS\SecurityExtraBundle\DependencyInjection\Compiler\AddExpressionCompilersPass; +use Symfony\Component\DependencyInjection\Compiler\PassConfig; +use JMS\SecurityExtraBundle\DependencyInjection\Compiler\AddAfterInvocationProvidersPass; +use JMS\SecurityExtraBundle\DependencyInjection\Compiler\CollectSecuredServicesPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\HttpKernel\Bundle\Bundle; + +/** + * Registers our custom compiler pass. + * + * @author Johannes M. Schmitt + */ +class JMSSecurityExtraBundle extends Bundle +{ + const VERSION = '1.1.0'; + + public function build(ContainerBuilder $container) + { + if (!$container->hasExtension('security')) { + throw new \LogicException('The JMSSecurityExtraBundle must be registered after the SecurityBundle in your AppKernel.php.'); + } + $container->registerExtension(new SecurityExtension($container->getExtension('security'))); + + $passConfig = $container->getCompilerPassConfig(); + + // needs to run before voter collection + $passes = $passConfig->getBeforeOptimizationPasses(); + array_unshift($passes, new DisableVotersPass()); + $passConfig->setBeforeOptimizationPasses($passes); + + $passConfig->addPass(new AddAfterInvocationProvidersPass()); + $passConfig->addPass(new CollectSecuredServicesPass()); + $passConfig->addPass(new AddExpressionCompilersPass()); + $passConfig->addPass(new IntegrationPass()); + } +} diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Metadata/ClassMetadata.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Metadata/ClassMetadata.php new file mode 100644 index 0000000..5f692cb --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Metadata/ClassMetadata.php @@ -0,0 +1,93 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Metadata; + +use JMS\SecurityExtraBundle\Exception\RuntimeException; +use JMS\SecurityExtraBundle\Exception\InvalidArgumentException; +use Metadata\MethodMetadata; +use Metadata\MergeableInterface; +use Metadata\MergeableClassMetadata; + +/** + * Contains class metadata information + * + * @author Johannes M. Schmitt + */ +class ClassMetadata extends MergeableClassMetadata +{ + public function addMethodMetadata(MethodMetadata $metadata) + { + if ($this->reflection->isFinal()) { + throw new RuntimeException(sprintf('Class "%s" is declared final, and cannot be secured.', $reflection->name)); + } + + if ($metadata->reflection->isStatic()) { + throw new RuntimeException(sprintf('Method "%s::%s" is declared static and cannot be secured.', $metadata->reflection->class, $metadata->reflection->name)); + } + + if ($metadata->reflection->isFinal()) { + throw new RuntimeException(sprintf('Method "%s::%s" is declared final and cannot be secured.', $metadata->reflection->class, $metadata->reflection->name)); + } + + parent::addMethodMetadata($metadata); + } + + public function merge(MergeableInterface $metadata) + { + if (!$metadata instanceof ClassMetadata) { + throw new InvalidArgumentException('$metadata must be an instance of ClassMetadata.'); + } + + foreach ($this->methodMetadata as $name => $methodMetadata) { + // check if metadata was declared on an interface + if (!$metadata->reflection->hasMethod($name)) { + continue; + } + + if ($metadata->reflection->getMethod($name)->getDeclaringClass()->name + !== $methodMetadata->class) { + if (!isset($metadata->methodMetadata[$name])) { + if ($methodMetadata->reflection->isAbstract()) { + continue; + } + + throw new RuntimeException(sprintf( + 'You have overridden a secured method "%s::%s" in "%s". ' + .'Please copy over the applicable security metadata, and ' + .'also add @SatisfiesParentSecurityPolicy.', + $methodMetadata->reflection->class, + $name, + $metadata->reflection->name + )); + } + + if (!$metadata->methodMetadata[$name]->satisfiesParentSecurityPolicy) { + throw new RuntimeException(sprintf('Unresolved security metadata conflict for method "%s::%s" in "%s". Please copy the respective annotations, and add @SatisfiesParentSecurityPolicy to the child method.', $metadata->reflection->name, $name, $methodMetadata->reflection->getDeclaringClass()->getFilename())); + } + } + } + + parent::merge($metadata); + } + + public function isProxyRequired() + { + return !empty($this->methodMetadata); + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Metadata/Driver/AnnotationDriver.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Metadata/Driver/AnnotationDriver.php new file mode 100644 index 0000000..7617c60 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Metadata/Driver/AnnotationDriver.php @@ -0,0 +1,107 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Metadata\Driver; + +use JMS\SecurityExtraBundle\Exception\InvalidArgumentException; +use Doctrine\Common\Annotations\Reader; +use JMS\SecurityExtraBundle\Annotation\PreAuthorize; +use JMS\SecurityExtraBundle\Annotation\RunAs; +use JMS\SecurityExtraBundle\Annotation\SatisfiesParentSecurityPolicy; +use JMS\SecurityExtraBundle\Annotation\Secure; +use JMS\SecurityExtraBundle\Annotation\SecureParam; +use JMS\SecurityExtraBundle\Annotation\SecureReturn; +use JMS\SecurityExtraBundle\Metadata\ClassMetadata; +use JMS\SecurityExtraBundle\Metadata\MethodMetadata; +use Metadata\Driver\DriverInterface; +use \ReflectionClass; +use \ReflectionMethod; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Expression; + +/** + * Loads security annotations and converts them to metadata + * + * @author Johannes M. Schmitt + */ +class AnnotationDriver implements DriverInterface +{ + private $reader; + + public function __construct(Reader $reader) + { + $this->reader = $reader; + } + + public function loadMetadataForClass(ReflectionClass $reflection) + { + $metadata = new ClassMetadata($reflection->getName()); + + foreach ($reflection->getMethods(ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED) as $method) { + // check if the method was defined on this class + if ($method->getDeclaringClass()->getName() !== $reflection->getName()) { + continue; + } + + $annotations = $this->reader->getMethodAnnotations($method); + + if ($annotations && null !== $methodMetadata = $this->convertMethodAnnotations($method, $annotations)) { + $metadata->addMethodMetadata($methodMetadata); + } + } + + return $metadata; + } + + private function convertMethodAnnotations(\ReflectionMethod $method, array $annotations) + { + $parameters = array(); + foreach ($method->getParameters() as $index => $parameter) { + $parameters[$parameter->getName()] = $index; + } + + $methodMetadata = new MethodMetadata($method->getDeclaringClass()->getName(), $method->getName()); + $hasSecurityMetadata = false; + foreach ($annotations as $annotation) { + if ($annotation instanceof Secure) { + $methodMetadata->roles = $annotation->roles; + $hasSecurityMetadata = true; + } else if ($annotation instanceof PreAuthorize) { + $methodMetadata->roles = array(new Expression($annotation->expr)); + $hasSecurityMetadata = true; + } else if ($annotation instanceof SecureParam) { + if (!isset($parameters[$annotation->name])) { + throw new InvalidArgumentException(sprintf('The parameter "%s" does not exist for method "%s".', $annotation->name, $method->getName())); + } + + $methodMetadata->addParamPermissions($parameters[$annotation->name], $annotation->permissions); + $hasSecurityMetadata = true; + } else if ($annotation instanceof SecureReturn) { + $methodMetadata->returnPermissions = $annotation->permissions; + $hasSecurityMetadata = true; + } else if ($annotation instanceof SatisfiesParentSecurityPolicy) { + $methodMetadata->satisfiesParentSecurityPolicy = true; + $hasSecurityMetadata = true; + } else if ($annotation instanceof RunAs) { + $methodMetadata->runAsRoles = $annotation->roles; + $hasSecurityMetadata = true; + } + } + + return $hasSecurityMetadata ? $methodMetadata : null; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Metadata/Driver/ConfigDriver.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Metadata/Driver/ConfigDriver.php new file mode 100644 index 0000000..00dd89e --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Metadata/Driver/ConfigDriver.php @@ -0,0 +1,100 @@ + + */ +class ConfigDriver implements DriverInterface +{ + private $bundles; + private $config; + + public function __construct(array $bundles, array $config) + { + uasort($bundles, function($a, $b) { + return strlen($b) - strlen($a); + }); + + foreach ($bundles as $name => $namespace) { + $bundles[$name] = substr($namespace, 0, strrpos($namespace, '\\')); + } + + $this->bundles = $bundles; + $this->config = $config; + } + + public function loadMetadataForClass(\ReflectionClass $class) + { + $metadata = new ClassMetadata($class->name); + + foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED) as $method) { + if ($method->getDeclaringClass()->name !== $class->name) { + continue; + } + + $expression = null; + if (null !== $notation = $this->getControllerNotation($method)) { + $expression = $this->getExpressionForSignature($notation); + } + + if (null === $expression && null === $expression = + $this->getExpressionForSignature($method->class.'::'.$method->name)) { + continue; + } + + $methodMetadata = new MethodMetadata($method->class, $method->name); + $methodMetadata->roles = array(new Expression($expression)); + $metadata->addMethodMetadata($methodMetadata); + } + + if (!$metadata->methodMetadata) { + return null; + } + + return $metadata; + } + + private function getExpressionForSignature($signature) + { + foreach ($this->config as $pattern => $expr) { + if (!preg_match('#'.$pattern.'#i', $signature)) { + continue; + } + + return $expr; + } + + return null; + } + + // TODO: Is it feasible to reverse-engineer the notation for service controllers? + private function getControllerNotation(\ReflectionMethod $method) + { + $signature = $method->class.'::'.$method->name; + + // check if class is a controller + if (0 === preg_match('#\\\\Controller\\\\([^\\\\]+)Controller::(.+)Action$#', $signature, $match)) { + return null; + } + + foreach ($this->bundles as $name => $namespace) { + if (0 !== strpos($method->class, $namespace)) { + continue; + } + + // controller notation (AcmeBundle:Foo:foo) + return $name.':'.$match[1].':'.$match[2]; + } + + return null; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Metadata/MethodMetadata.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Metadata/MethodMetadata.php new file mode 100644 index 0000000..6bec7ce --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Metadata/MethodMetadata.php @@ -0,0 +1,84 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Metadata; + +use Metadata\MethodMetadata as BaseMethodMetadata; + +/** + * Contains method metadata information + * + * @author Johannes M. Schmitt + */ +class MethodMetadata extends BaseMethodMetadata +{ + public $roles = array(); + public $paramPermissions = array(); + public $returnPermissions = array(); + public $runAsRoles = array(); + public $satisfiesParentSecurityPolicy = false; + + /** + * Adds a parameter restriction + * + * @param integer $index 0-based + * @param array $permissions + */ + public function addParamPermissions($index, array $permissions) + { + $this->paramPermissions[$index] = $permissions; + } + + public function isDeclaredOnInterface() + { + foreach ($this->reflection->getDeclaringClass()->getInterfaces() as $interface) { + if ($interface->hasMethod($this->name)) { + return true; + } + } + + return false; + } + + /** + * This allows to merge in metadata from an interface + * + * @param MethodMetadata $method + * @return void + */ + public function merge(MethodMetadata $method) + { + if (!$this->roles) { + $this->roles = $method->roles; + } + + if (!$this->returnPermissions) { + $this->returnPermissions = $method->returnPermissions; + } + + if (!$this->runAsRoles) { + $this->runAsRoles = $method->runAsRoles; + } + + foreach ($method->paramPermissions as $index => $permissions) { + if (!isset($this->paramPermissions[$index])) { + $this->paramPermissions[$index] = $permissions; + } + } + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/README b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/README new file mode 100644 index 0000000..72bab21 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/README @@ -0,0 +1,8 @@ +For documentation, see: + + Resources/doc + + +For license, see: + + Resources/meta/LICENSE \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Resources/config/security_expressions.xml b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Resources/config/security_expressions.xml new file mode 100644 index 0000000..493e2ea --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Resources/config/security_expressions.xml @@ -0,0 +1,84 @@ + + + + + + JMS\SecurityExtraBundle\Security\Acl\Expression\PermissionEvaluator + JMS\SecurityExtraBundle\Security\Acl\Expression\HasPermissionFunctionCompiler + + JMS\SecurityExtraBundle\Security\Authorization\Expression\LazyLoadingExpressionVoter + JMS\SecurityExtraBundle\Security\Authorization\Expression\ContainerAwareExpressionHandler + + JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler + JMS\SecurityExtraBundle\Security\Authorization\Expression\Expression + + JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\ContainerAwareVariableCompiler + JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\ParameterExpressionCompiler + + JMS\SecurityExtraBundle\Metadata\Driver\ConfigDriver + + JMS\SecurityExtraBundle\Twig\SecurityExtension + + + + + + + + + + %kernel.bundles% + %security.access.method_access_control% + + + + + + + + + + + + + + + + + + + + security.expressions.compiler + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Resources/config/services.xml b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Resources/config/services.xml new file mode 100644 index 0000000..0ad446c --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Resources/config/services.xml @@ -0,0 +1,99 @@ + + + + + + + + JMS\SecurityExtraBundle\Security\Authorization\Interception\MethodSecurityInterceptor + + + JMS\SecurityExtraBundle\Security\Authorization\RunAsManager + JMS\SecurityExtraBundle\Security\Authentication\Provider\RunAsAuthenticationProvider + RunAsToken + ROLE_ + + JMS\SecurityExtraBundle\Security\Authorization\AfterInvocation\AfterInvocationManager + JMS\SecurityExtraBundle\Security\Authorization\AfterInvocation\AclAfterInvocationProvider + + JMS\SecurityExtraBundle\Security\Authorization\Voter\IddqdVoter + + Metadata\MetadataFactory + Metadata\Driver\LazyLoadingDriver + Metadata\Driver\DriverChain + JMS\SecurityExtraBundle\Metadata\Driver\AnnotationDriver + Metadata\Cache\FileCache + + + + + %security.run_as.key% + %security.run_as.role_prefix% + + + + + + + + + + + + + + + %security.access.secure_all_services% + %security.access.method_access_control% + + + + + + + + + + + + + + + + + + + + + + + + + + + + + security.extra.metadata_driver + + + + + + + + %security.extra.cache_dir% + %kernel.debug% + + + + + + \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Resources/doc/index.rst b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Resources/doc/index.rst new file mode 100644 index 0000000..8b41a2f --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Resources/doc/index.rst @@ -0,0 +1,352 @@ +======== +Overview +======== + +This bundle enhances the Symfony2 Security Component by adding several new features. + +Features: + +- powerful expression-based authorization language +- method security authorization +- authorization configuration via annotations + +Installation +------------ +Add the following to your ``deps`` file:: + + [JMSSecurityExtraBundle] + git=https://github.com/schmittjoh/JMSSecurityExtraBundle.git + target=/bundles/JMS/SecurityExtraBundle + + ; Dependencies: + ;-------------- + [metadata] + git=https://github.com/schmittjoh/metadata.git + version=1.1.0 ; <- make sure to get 1.1, not 1.0 + + ; see https://github.com/schmittjoh/JMSAopBundle/blob/master/Resources/doc/index.rst + [JMSAopBundle] + git=https://github.com/schmittjoh/JMSAopBundle.git + target=/bundles/JMS/AopBundle + + [cg-library] + git=https://github.com/schmittjoh/cg-library.git + + ; This dependency is optional (you need it if you are using non-service controllers): + ; see https://github.com/schmittjoh/JMSDiExtraBundle/blob/master/Resources/doc/index.rst + [JMSDiExtraBundle] + git=https://github.com/schmittjoh/JMSDiExtraBundle.git + target=/bundles/JMS/DiExtraBundle + +Then register the bundle with your kernel:: + + // in AppKernel::registerBundles() + $bundles = array( + // ... + new JMS\AopBundle\JMSAopBundle(), + new JMS\SecurityExtraBundle\JMSSecurityExtraBundle(), + new JMS\DiExtraBundle\JMSDiExtraBundle($this), + // ... + ); + +Make sure that you also register the namespaces with the autoloader:: + + // app/autoload.php + $loader->registerNamespaces(array( + // ... + 'JMS' => __DIR__.'/../vendor/bundles', + 'Metadata' => __DIR__.'/../vendor/metadata/src', + 'CG' => __DIR__.'/../vendor/cg-library/src', + // ... + )); + +Configuration +------------- + +Below, you find the default configuration:: + + # app/config/config.yml + jms_security_extra: + # Whether you want to secure all services (true), or only secure specific + # services (false); see also below + secure_all_services: false + + # Enabling this setting will add an additional special attribute "IS_IDDQD". + # Anybody with this attribute will effectively bypass all security checks. + enable_iddqd_attribute: false + + # Enables expression language + expressions: false + + # Allows you to disable some, or all built-in voters + voters: + disable_authenticated: false + disable_role: false + disable_acl: false + + # Allows you to specify access control rules for specific methods, such + # as controller actions + method_access_control: { } + + +Expression-based Authorization Language +--------------------------------------- +The expression language is a very powerful alternative to the simple attributes +of the security voting system. They allow to perform complex access decision +checks, and because they are compiled down to raw PHP, they are much faster than +the built-in voters. Also they are lazy-loading by nature, so you will also +save some resources for example by not having to initialize the entire ACL system +on each request. + +Programmatic Usage +~~~~~~~~~~~~~~~~~~ +You can execute expressions programmatically by using the ``isGranted`` method +of the SecurityContext. Some examples:: + + use JMS\SecurityExtraBundle\Security\Authorization\Expression\Expression; + + $securityContext->isGranted(array(new Expression('hasRole("A")'))); + $securityContext->isGranted(array(new Expression('hasRole("A") or (hasRole("B") and hasRole("C"))'))); + $securityContext->isGranted(array(new Expression('hasPermission(object, "VIEW")'), $object)); + $securityContext->isGranted(array(new Expression('token.getUsername() == "Johannes"'))); + +Twig Usage +~~~~~~~~~~ +You can check expressions from Twig templates using the ``is_expr_granted`` +function. Some examples:: + + is_expr_granted("hasRole('FOO')") + is_expr_granted("hasPermission(object, 'VIEW')", object) + +Usage in Access Control +~~~~~~~~~~~~~~~~~~~~~~~ +You can also use expressions in the ``access_control``:: + + security: + access_control: + - { path: ^/foo, access: "hasRole('FOO') and hasRole('BAR')" } + +Annotation-based Usage +~~~~~~~~~~~~~~~~~~~~~~ +see @PreAuthorize in the annotation reference + +Reference +~~~~~~~~~ ++-----------------------------------+--------------------------------------------+ +| Expression | Description | ++===================================+============================================+ +| hasRole('ROLE') | Checks whether the token has a certain | +| | role. | ++-----------------------------------+--------------------------------------------+ +| hasAnyRole('ROLE1', 'ROLE2', ...) | Checks whether the token has any of the | +| | given roles. | ++-----------------------------------+--------------------------------------------+ +| isAnonymous() | Checks whether the token is anonymous. | ++-----------------------------------+--------------------------------------------+ +| isRememberMe() | Checks whether the token is remember me. | ++-----------------------------------+--------------------------------------------+ +| isFullyAuthenticated() | Checks whether the token is fully | +| | authenticated. | ++-----------------------------------+--------------------------------------------+ +| isAuthenticated() | Checks whether the token is not anonymous. | ++-----------------------------------+--------------------------------------------+ +| hasPermission(*var*, 'PERMISSION')| Checks whether the token has the given | +| | permission for the given object (requires | +| | the ACL system). | ++-----------------------------------+--------------------------------------------+ +| token | Variable that refers to the token | +| | which is currently in the security context.| ++-----------------------------------+--------------------------------------------+ +| user | Variable that refers to the user | +| | which is currently in the security context.| ++-----------------------------------+--------------------------------------------+ +| object | Variable that refers to the object for | +| | which access is being requested. | ++-----------------------------------+--------------------------------------------+ +| #*paramName* | Any identifier prefixed with # refers to | +| | a parameter of the same name that is passed| +| | to the method where the expression is used.| ++-----------------------------------+--------------------------------------------+ +| and / && | Binary "and" operator | ++-----------------------------------+--------------------------------------------+ +| or / || | Binary "or" operator | ++-----------------------------------+--------------------------------------------+ +| == | Binary "is equal" operator | ++-----------------------------------+--------------------------------------------+ +| not / ! | Negation operator | ++-----------------------------------+--------------------------------------------+ + +Method Security Authorization +----------------------------- +Generally, you can secure all public, or protected methods which are non-static, +and non-final. Private methods cannot be secured. You can also add metadata for +abstract methods, or interfaces which will then be applied to their concrete +implementations automatically. + +Access Control via DI configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +You can specify access control **expressions** in the DI configuration:: + + # config.yml + jms_security_extra: + method_access_control: + ':loginAction$': 'isAnonymous()' + 'AcmeFooBundle:.*:deleteAction': 'hasRole("ROLE_ADMIN")' + '^MyNamespace\MyService::foo$': 'hasPermission(#user, "VIEW")' + +The pattern is a case-sensitive regular expression which is matched against two notations. +The first match is being used. + +First, your pattern is matched against the notation for non-service controllers. +This obviously is only done if your class is actually a controller, e.g. +``AcmeFooBundle:Add:new`` for a controller named ``AddController`` and a method +named ``newAction`` in a sub-namespace ``Controller`` in a bundle named ``AcmeFooBundle``. + +Last, your pattern is matched against the concatenation of the class name, and +the method name that is being called, e.g. ``My\Fully\Qualified\ClassName::myMethodName``. + +**Note:** If you would like to secure non-service controllers, the +``JMSDiExtraBundle`` must be installed. + +Access Control via Annotations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +If you like to secure a service with annotations, you need to enable annotation +configuration for this service:: + + + + + +In case, you like to configure all services via annotations, you can also set +``secure_all_services`` to true. Then, you do not need to add a tag for each +service. + + +Annotations +----------- +@PreAuthorize +~~~~~~~~~~~~~ +This annotation lets you define an expression (see the expression language +paragraph) which is executed prior to invoking a method:: + + myPrivateService->aMethodOnlyToBeInvokedThroughASpecificChannel(); + } + } + +@SatisfiesParentSecurityPolicy +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This must be defined on a method that overrides a method which has security metadata. +It is there to ensure that you are aware the security of the overridden method cannot +be enforced anymore, and that you must copy over all annotations if you want to keep +them. diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Resources/meta/LICENSE b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Resources/meta/LICENSE new file mode 100644 index 0000000..753842b --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Resources/meta/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Acl/Expression/HasPermissionFunctionCompiler.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Acl/Expression/HasPermissionFunctionCompiler.php new file mode 100644 index 0000000..340617b --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Acl/Expression/HasPermissionFunctionCompiler.php @@ -0,0 +1,63 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Acl\Expression; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ConstantExpression; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\VariableExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\Func\FunctionCompilerInterface; + +class HasPermissionFunctionCompiler implements FunctionCompilerInterface +{ + public function getName() + { + return 'hasPermission'; + } + + public function compilePreconditions(ExpressionCompiler $compiler, FunctionExpression $function) + { + $compiler->verifyItem('token', 'Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + } + + public function compile(ExpressionCompiler $compiler, FunctionExpression $function) + { + $compiler + ->compileInternal(new VariableExpression('permission_evaluator')) + ->write('->hasPermission(') + ->compileInternal(new VariableExpression('token')) + ->write(', ') + ->compileInternal($function->args[0]) + ->write(', ') + ; + + if ($function->args[1] instanceof ConstantExpression) { + $compiler->write(var_export(strtoupper($function->args[1]->value), true).')'); + + return; + } + + $compiler + ->write('strtoupper(') + ->compileInternal($function->args[1]) + ->write('))') + ; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Acl/Expression/PermissionEvaluator.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Acl/Expression/PermissionEvaluator.php new file mode 100644 index 0000000..96111fc --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Acl/Expression/PermissionEvaluator.php @@ -0,0 +1,122 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Acl\Expression; + +use Symfony\Component\Security\Acl\Exception\NoAceFoundException; +use Symfony\Component\Security\Acl\Exception\AclNotFoundException; +use Symfony\Component\Security\Acl\Model\ObjectIdentityInterface; +use Symfony\Component\Security\Acl\Permission\PermissionMapInterface; +use Symfony\Component\Security\Acl\Model\AclProviderInterface; +use Symfony\Component\Security\Acl\Model\SecurityIdentityRetrievalStrategyInterface; +use Symfony\Component\Security\Acl\Model\ObjectIdentityRetrievalStrategyInterface; +use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; + +class PermissionEvaluator +{ + private $aclProvider; + private $oidRetrievalStrategy; + private $sidRetrievalStrategy; + private $permissionMap; + private $allowIfObjectIdentityUnavailable; + private $logger; + + public function __construct(AclProviderInterface $aclProvider, + ObjectIdentityRetrievalStrategyInterface $oidRetrievalStrategy, + SecurityIdentityRetrievalStrategyInterface $sidRetrievalStrategy, + PermissionMapInterface $permissionMap, + $allowIfObjectIdentityUnavailable = true, + LoggerInterface $logger = null) + { + $this->aclProvider = $aclProvider; + $this->oidRetrievalStrategy = $oidRetrievalStrategy; + $this->sidRetrievalStrategy = $sidRetrievalStrategy; + $this->permissionMap = $permissionMap; + $this->allowIfObjectIdentityUnavailable = $allowIfObjectIdentityUnavailable; + $this->logger = $logger; + } + + public function hasPermission(TokenInterface $token, $object, $permission) + { + if (null === $masks = $this->permissionMap->getMasks($permission, $object)) { + return false; + } + + if (null === $object) { + if (null !== $this->logger) { + $this->logger->debug(sprintf('Object identity unavailable. Voting to %s', $this->allowIfObjectIdentityUnavailable? 'grant access' : 'abstain')); + } + + return $this->allowIfObjectIdentityUnavailable ? true : false; + } else if ($object instanceof FieldVote) { + $field = $object->getField(); + $object = $object->getDomainObject(); + } else { + $field = null; + } + + if ($object instanceof ObjectIdentityInterface) { + $oid = $object; + } else if (null === $oid = $this->oidRetrievalStrategy->getObjectIdentity($object)) { + if (null !== $this->logger) { + $this->logger->debug(sprintf('Object identity unavailable. Voting to %s', $this->allowIfObjectIdentityUnavailable? 'grant access' : 'abstain')); + } + + return $this->allowIfObjectIdentityUnavailable ? true : false; + } + + $sids = $this->sidRetrievalStrategy->getSecurityIdentities($token); + + try { + $acl = $this->aclProvider->findAcl($oid, $sids); + + if (null === $field && $acl->isGranted($masks, $sids, false)) { + if (null !== $this->logger) { + $this->logger->debug('ACL found, permission granted. Voting to grant access'); + } + + return true; + } else if (null !== $field && $acl->isFieldGranted($field, $masks, $sids, false)) { + if (null !== $this->logger) { + $this->logger->debug('ACL found, permission granted. Voting to grant access'); + } + + return true; + } + + if (null !== $this->logger) { + $this->logger->debug('ACL found, insufficient permissions. Voting to deny access.'); + } + + return false; + } catch (AclNotFoundException $noAcl) { + if (null !== $this->logger) { + $this->logger->debug('No ACL found for the object identity. Voting to deny access.'); + } + + return false; + } catch (NoAceFoundException $noAce) { + if (null !== $this->logger) { + $this->logger->debug('ACL found, no ACE applicable. Voting to deny access.'); + } + + return false; + } + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Acl/Voter/AclVoter.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Acl/Voter/AclVoter.php new file mode 100644 index 0000000..bad27d8 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Acl/Voter/AclVoter.php @@ -0,0 +1,136 @@ + + */ +class AclVoter implements VoterInterface +{ + private $aclProvider; + private $permissionMap; + private $objectIdentityRetrievalStrategy; + private $securityIdentityRetrievalStrategy; + private $allowIfObjectIdentityUnavailable; + private $logger; + + public function __construct(AclProviderInterface $aclProvider, ObjectIdentityRetrievalStrategyInterface $oidRetrievalStrategy, SecurityIdentityRetrievalStrategyInterface $sidRetrievalStrategy, PermissionMapInterface $permissionMap, LoggerInterface $logger = null, $allowIfObjectIdentityUnavailable = true) + { + $this->aclProvider = $aclProvider; + $this->permissionMap = $permissionMap; + $this->objectIdentityRetrievalStrategy = $oidRetrievalStrategy; + $this->securityIdentityRetrievalStrategy = $sidRetrievalStrategy; + $this->logger = $logger; + $this->allowIfObjectIdentityUnavailable = $allowIfObjectIdentityUnavailable; + } + + public function supportsAttribute($attribute) + { + return $this->permissionMap->contains($attribute); + } + + public function vote(TokenInterface $token, $object, array $attributes) + { + foreach ($attributes as $attribute) { + if (null === $masks = $this->permissionMap->getMasks((string) $attribute, $object)) { + continue; + } + + if (null === $object) { + if (null !== $this->logger) { + $this->logger->debug(sprintf('Object identity unavailable. Voting to %s', $this->allowIfObjectIdentityUnavailable? 'grant access' : 'abstain')); + } + + return $this->allowIfObjectIdentityUnavailable ? self::ACCESS_GRANTED : self::ACCESS_ABSTAIN; + } else if ($object instanceof FieldVote) { + $field = $object->getField(); + $object = $object->getDomainObject(); + } else { + $field = null; + } + + if ($object instanceof ObjectIdentityInterface) { + $oid = $object; + } else if (null === $oid = $this->objectIdentityRetrievalStrategy->getObjectIdentity($object)) { + if (null !== $this->logger) { + $this->logger->debug(sprintf('Object identity unavailable. Voting to %s', $this->allowIfObjectIdentityUnavailable? 'grant access' : 'abstain')); + } + + return $this->allowIfObjectIdentityUnavailable ? self::ACCESS_GRANTED : self::ACCESS_ABSTAIN; + } + + if (!$this->supportsClass($oid->getType())) { + return self::ACCESS_ABSTAIN; + } + + $sids = $this->securityIdentityRetrievalStrategy->getSecurityIdentities($token); + + try { + $acl = $this->aclProvider->findAcl($oid, $sids); + + if (null === $field && $acl->isGranted($masks, $sids, false)) { + if (null !== $this->logger) { + $this->logger->debug('ACL found, permission granted. Voting to grant access'); + } + + return self::ACCESS_GRANTED; + } else if (null !== $field && $acl->isFieldGranted($field, $masks, $sids, false)) { + if (null !== $this->logger) { + $this->logger->debug('ACL found, permission granted. Voting to grant access'); + } + + return self::ACCESS_GRANTED; + } + + if (null !== $this->logger) { + $this->logger->debug('ACL found, insufficient permissions. Voting to deny access.'); + } + + return self::ACCESS_DENIED; + } catch (AclNotFoundException $noAcl) { + if (null !== $this->logger) { + $this->logger->debug('No ACL found for the object identity. Voting to deny access.'); + } + + return self::ACCESS_DENIED; + } catch (NoAceFoundException $noAce) { + if (null !== $this->logger) { + $this->logger->debug('ACL found, no ACE applicable. Voting to deny access.'); + } + + return self::ACCESS_DENIED; + } + } + + // no attribute was supported + return self::ACCESS_ABSTAIN; + } + + /** + * You can override this method when writing a voter for a specific domain + * class. + * + * @param string $class The class name + * + * @return Boolean + */ + public function supportsClass($class) + { + return true; + } +} diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authentication/Provider/RunAsAuthenticationProvider.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authentication/Provider/RunAsAuthenticationProvider.php new file mode 100644 index 0000000..6958805 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authentication/Provider/RunAsAuthenticationProvider.php @@ -0,0 +1,57 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authentication\Provider; + +use Symfony\Component\Security\Core\Exception\BadCredentialsException; +use JMS\SecurityExtraBundle\Security\Authentication\Token\RunAsUserToken; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface; + +/** + * Class which authenticates RunAsTokens. + * + * @author Johannes M. Schmitt + */ +class RunAsAuthenticationProvider implements AuthenticationProviderInterface +{ + private $key; + + public function __construct($key) + { + $this->key = $key; + } + + public function authenticate(TokenInterface $token) + { + if (!$this->supports($token)) { + return null; + } + + if ($token->getKey() === $this->key) { + return $token; + } else { + throw new BadCredentialsException('The keys do not match.'); + } + } + + public function supports(TokenInterface $token) + { + return $token instanceof RunAsUserToken; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authentication/Token/RunAsUserToken.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authentication/Token/RunAsUserToken.php new file mode 100644 index 0000000..0672f2a --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authentication/Token/RunAsUserToken.php @@ -0,0 +1,85 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authentication\Token; + +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Authentication\Token\AbstractToken; + +/** + * This token is automatically generated by the RunAsManager when an invocation + * is supposed to be run with a different Token. + * + * @author Johannes M. Schmitt + */ +class RunAsUserToken extends AbstractToken +{ + private $originalToken; + private $key; + private $credentials; + + public function __construct($key, $user, $credentials, array $roles, TokenInterface $originalToken) + { + parent::__construct($roles); + + $this->originalToken = $originalToken; + $this->credentials = $credentials; + $this->key = $key; + + $this->setUser($user); + $this->setAuthenticated(true); + } + + public function getKey() + { + return $this->key; + } + + public function getOriginalToken() + { + return $this->originalToken; + } + + public function getCredentials() + { + return $this->credentials; + } + + public function eraseCredentials() + { + parent::eraseCredentials(); + + $this->credentials = null; + } + + public function serialize() + { + return serialize(array( + $this->originalToken, + $this->key, + $this->credentials, + parent::serialize(), + )); + } + + public function unserialize($str) + { + list($this->originalToken, $this->key, $this->credentials, $parentStr) = unserialize($str); + parent::unserialize($parentStr); + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/AfterInvocation/AclAfterInvocationProvider.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/AfterInvocation/AclAfterInvocationProvider.php new file mode 100644 index 0000000..a004e92 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/AfterInvocation/AclAfterInvocationProvider.php @@ -0,0 +1,111 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\AfterInvocation; + +use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Symfony\Component\Security\Acl\Exception\AclNotFoundException; +use Symfony\Component\Security\Acl\Exception\NoAceFoundException; +use Symfony\Component\Security\Acl\Model\SecurityIdentityRetrievalStrategyInterface; +use Symfony\Component\Security\Acl\Model\ObjectIdentityRetrievalStrategyInterface; +use Symfony\Component\Security\Acl\Model\AclProviderInterface; +use Symfony\Component\Security\Acl\Permission\PermissionMapInterface; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Exception\AccessDeniedException; + +/** + * This after invocation provider filters returned objects based on ACLs. + * + * @author Johannes M. Schmitt + */ +class AclAfterInvocationProvider implements AfterInvocationProviderInterface +{ + private $aclProvider; + private $oidRetrievalStrategy; + private $sidRetrievalStrategy; + private $permissionMap; + private $logger; + + public function __construct(AclProviderInterface $aclProvider, ObjectIdentityRetrievalStrategyInterface $oidRetrievalStrategy, SecurityIdentityRetrievalStrategyInterface $sidRetrievalStrategy, PermissionMapInterface $permissionMap, LoggerInterface $logger = null) + { + $this->aclProvider = $aclProvider; + $this->oidRetrievalStrategy = $oidRetrievalStrategy; + $this->sidRetrievalStrategy = $sidRetrievalStrategy; + $this->permissionMap = $permissionMap; + $this->logger = $logger; + } + + public function decide(TokenInterface $token, $secureObject, array $attributes, $returnedObject) + { + if (null === $returnedObject) { + if (null !== $this->logger) { + $this->logger->debug('Returned object was null, skipping security check.'); + } + + return null; + } + + foreach ($attributes as $attribute) { + if (!$this->supportsAttribute($attribute)) { + continue; + } + + if (null === $oid = $this->oidRetrievalStrategy->getObjectIdentity($returnedObject)) { + if (null !== $this->logger) { + $this->logger->debug('Returned object was no domain object, skipping security check.'); + } + + return $returnedObject; + } + + $sids = $this->sidRetrievalStrategy->getSecurityIdentities($token); + + try { + $acl = $this->aclProvider->findAcl($oid, $sids); + if ($acl->isGranted($this->permissionMap->getMasks($attribute, $returnedObject), $sids, false)) { + return $returnedObject; + } + + if (null !== $this->logger) { + $this->logger->debug('Token has been denied access for returned object.'); + } + } catch (AclNotFoundException $noAcl) { + throw new AccessDeniedException('No applicable ACL found for domain object.'); + } catch (NoAceFoundException $noAce) { + if (null !== $this->logger) { + $this->logger->debug('No applicable ACE found for the given Token, denying access.'); + } + } + + throw new AccessDeniedException('ACL has denied access for attribute: '.$attribute); + } + + // no attribute was supported + return $returnedObject; + } + + public function supportsAttribute($attribute) + { + return $this->permissionMap->contains($attribute); + } + + public function supportsClass($className) + { + return true; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/AfterInvocation/AfterInvocationManager.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/AfterInvocation/AfterInvocationManager.php new file mode 100644 index 0000000..88beeae --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/AfterInvocation/AfterInvocationManager.php @@ -0,0 +1,77 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\AfterInvocation; + +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; + +/** + * This is the pendant to the AccessDecisionManager which is used to make + * access decisions after a method has been executed. + * + * @author Johannes M. Schmitt + */ +class AfterInvocationManager implements AfterInvocationManagerInterface +{ + private $providers; + + public function __construct(array $providers) + { + $this->providers = $providers; + } + + /** + * {@inheritDoc} + */ + public function decide(TokenInterface $token, $secureInvocation, array $attributes, $returnedObject) + { + foreach ($this->providers as $provider) { + $returnedObject = $provider->decide($token, $secureInvocation, $attributes, $returnedObject); + } + + return $returnedObject; + } + + /** + * {@inheritDoc} + */ + public function supportsAttribute($attribute) + { + foreach ($this->providers as $provider) { + if (true === $provider->supportsAttribute($attribute)) { + return true; + } + } + + return false; + } + + /** + * {@inheritDoc} + */ + public function supportsClass($className) + { + foreach ($this->providers as $provider) { + if (true === $provider->supportsClass($className)) { + return true; + } + } + + return false; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/AfterInvocation/AfterInvocationManagerInterface.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/AfterInvocation/AfterInvocationManagerInterface.php new file mode 100644 index 0000000..c02ec50 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/AfterInvocation/AfterInvocationManagerInterface.php @@ -0,0 +1,56 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\AfterInvocation; + +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; + +/** + * AfterInvocationManagerInterface + * + * @author Johannes M. Schmitt + */ +interface AfterInvocationManagerInterface +{ + /** + * Makes an access decision after the invocation of a method + * + * @param TokenInterface $token + * @param object $secureObject + * @param array $attributes + * @param mixed $returnedValue the value that was returned by the method invocation + * @return mixed the filter return value + */ + function decide(TokenInterface $token, $secureObject, array $attributes, $returnedValue); + + /** + * Determines whether the given attribute is supported + * + * @param string $attribute + * @return Boolean + */ + function supportsAttribute($attribute); + + /** + * Determines whether the given class is supported + * + * @param string $className the class of the secure object + * @return Boolean + */ + function supportsClass($className); +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/AfterInvocation/AfterInvocationProviderInterface.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/AfterInvocation/AfterInvocationProviderInterface.php new file mode 100644 index 0000000..e75466b --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/AfterInvocation/AfterInvocationProviderInterface.php @@ -0,0 +1,33 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\AfterInvocation; + +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; + +/** + * AfterInvocationProviderInterface + * + * @author Johannes M. Schmitt + */ +interface AfterInvocationProviderInterface +{ + function decide(TokenInterface $token, $secureObject, array $attributes, $returnedObject); + function supportsAttribute($attribute); + function supportsClass($className); +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/AndExpression.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/AndExpression.php new file mode 100644 index 0000000..e01d396 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/AndExpression.php @@ -0,0 +1,31 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast; + +class AndExpression implements ExpressionInterface +{ + public $left; + public $right; + + public function __construct(ExpressionInterface $left, ExpressionInterface $right) + { + $this->left = $left; + $this->right = $right; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/ArrayExpression.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/ArrayExpression.php new file mode 100644 index 0000000..cb039bf --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/ArrayExpression.php @@ -0,0 +1,29 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast; + +class ArrayExpression implements ExpressionInterface +{ + public $elements; + + public function __construct(array $elements) + { + $this->elements = $elements; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/ConstantExpression.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/ConstantExpression.php new file mode 100644 index 0000000..963f1ed --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/ConstantExpression.php @@ -0,0 +1,29 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast; + +class ConstantExpression implements ExpressionInterface +{ + public $value; + + public function __construct($value) + { + $this->value = $value; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/ExpressionInterface.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/ExpressionInterface.php new file mode 100644 index 0000000..91af129 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/ExpressionInterface.php @@ -0,0 +1,23 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast; + +interface ExpressionInterface +{ +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/FunctionExpression.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/FunctionExpression.php new file mode 100644 index 0000000..5e52e98 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/FunctionExpression.php @@ -0,0 +1,32 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast; + +class FunctionExpression implements ExpressionInterface +{ + /** READ-ONLY */ + public $name; + public $args; + + public function __construct($name, array $args) + { + $this->name = $name; + $this->args = $args; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/GetItemExpression.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/GetItemExpression.php new file mode 100644 index 0000000..2df5eb0 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/GetItemExpression.php @@ -0,0 +1,31 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast; + +class GetItemExpression +{ + public $array; + public $key; + + public function __construct(ExpressionInterface $array, ExpressionInterface $key) + { + $this->array = $array; + $this->key = $key; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/GetPropertyExpression.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/GetPropertyExpression.php new file mode 100644 index 0000000..fe070ab --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/GetPropertyExpression.php @@ -0,0 +1,31 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast; + +class GetPropertyExpression implements ExpressionInterface +{ + public $object; + public $name; + + public function __construct(ExpressionInterface $obj, $name) + { + $this->object = $obj; + $this->name = $name; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/IsEqualExpression.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/IsEqualExpression.php new file mode 100644 index 0000000..89f83f7 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/IsEqualExpression.php @@ -0,0 +1,31 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast; + +class IsEqualExpression implements ExpressionInterface +{ + public $left; + public $right; + + public function __construct(ExpressionInterface $left, ExpressionInterface $right) + { + $this->left = $left; + $this->right = $right; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/MethodCallExpression.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/MethodCallExpression.php new file mode 100644 index 0000000..22f3274 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/MethodCallExpression.php @@ -0,0 +1,33 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast; + +class MethodCallExpression implements ExpressionInterface +{ + public $object; + public $method; + public $args; + + public function __construct(ExpressionInterface $obj, $method, array $args) + { + $this->object = $obj; + $this->method = $method; + $this->args = $args; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/NotExpression.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/NotExpression.php new file mode 100644 index 0000000..aa730c0 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/NotExpression.php @@ -0,0 +1,29 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast; + +class NotExpression implements ExpressionInterface +{ + public $expr; + + public function __construct(ExpressionInterface $expr) + { + $this->expr = $expr; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/OrExpression.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/OrExpression.php new file mode 100644 index 0000000..a3d1f03 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/OrExpression.php @@ -0,0 +1,31 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast; + +class OrExpression implements ExpressionInterface +{ + public $left; + public $right; + + public function __construct(ExpressionInterface $left, ExpressionInterface $right) + { + $this->left = $left; + $this->right = $right; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/ParameterExpression.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/ParameterExpression.php new file mode 100644 index 0000000..f382e5c --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/ParameterExpression.php @@ -0,0 +1,29 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast; + +class ParameterExpression implements ExpressionInterface +{ + public $name; + + public function __construct($name) + { + $this->name = $name; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/VariableExpression.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/VariableExpression.php new file mode 100644 index 0000000..c48c02e --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Ast/VariableExpression.php @@ -0,0 +1,31 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast; + +class VariableExpression implements ExpressionInterface +{ + public $name; + public $allowNull; + + public function __construct($name, $allowNull = false) + { + $this->name = $name; + $this->allowNull = $allowNull; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/AndExpressionCompiler.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/AndExpressionCompiler.php new file mode 100644 index 0000000..e488a32 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/AndExpressionCompiler.php @@ -0,0 +1,32 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler; + +class AndExpressionCompiler extends BinaryExprCompiler +{ + public function getType() + { + return 'JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\AndExpression'; + } + + protected function getOperator() + { + return '&&'; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/BinaryExprCompiler.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/BinaryExprCompiler.php new file mode 100644 index 0000000..0dcd154 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/BinaryExprCompiler.php @@ -0,0 +1,51 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ExpressionInterface; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler; + +/** + * Base Compiler for Binary Operators. + * + * @author Johannes M. Schmitt + */ +abstract class BinaryExprCompiler implements TypeCompilerInterface +{ + public function compilePreconditions(ExpressionCompiler $compiler, ExpressionInterface $expr) + { + $compiler + ->compilePreconditions($expr->left) + ->compilePreconditions($expr->right) + ; + } + + public function compile(ExpressionCompiler $compiler, ExpressionInterface $expr) + { + $compiler + ->write("(") + ->compileInternal($expr->left) + ->write(") ".$this->getOperator()." (") + ->compileInternal($expr->right) + ->write(")") + ; + } + + abstract protected function getOperator(); +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/ContainerAwareVariableCompiler.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/ContainerAwareVariableCompiler.php new file mode 100644 index 0000000..809ffc2 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/ContainerAwareVariableCompiler.php @@ -0,0 +1,60 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler; + +use Symfony\Component\DependencyInjection\ContainerInterface; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ExpressionInterface; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\VariableExpressionCompiler; + +class ContainerAwareVariableCompiler extends VariableExpressionCompiler +{ + private $serviceMap = array(); + private $parameterMap = array(); + + public function setMaps(array $serviceMap, array $parameterMap) + { + $this->serviceMap = $serviceMap; + $this->parameterMap = $parameterMap; + } + + public function compile(ExpressionCompiler $compiler, ExpressionInterface $expr) + { + if (isset($this->serviceMap[$expr->name])) { + $compiler->write("\$context['container']->get('{$this->serviceMap[$expr->name]}'"); + + if ($expr->allowNull) { + $compiler->write(", ".ContainerInterface::NULL_ON_INVALID_REFERENCE); + } + + $compiler->write(")"); + + return; + } + + if (isset($this->parameterMap[$expr->name])) { + $compiler->write("\$context['container']->getParameter('{$this->parameterMap[$expr->name]}')"); + + return; + } + + parent::compile($compiler, $expr); + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/AuthenticationTrustFunctionCompiler.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/AuthenticationTrustFunctionCompiler.php new file mode 100644 index 0000000..aa98f6c --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/AuthenticationTrustFunctionCompiler.php @@ -0,0 +1,35 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\Func; + +use JMS\SecurityExtraBundle\Exception\InvalidArgumentException; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler; + +abstract class AuthenticationTrustFunctionCompiler implements FunctionCompilerInterface +{ + public function compilePreconditions(ExpressionCompiler $compiler, FunctionExpression $function) + { + if (!empty($function->args)) { + throw new InvalidArgumentException(sprintf('The '.$this->getName().'() function does not accept any arguments, but got "%s".', var_export($function->args, true))); + } + + $compiler->verifyItem('token', 'Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/FunctionCompilerInterface.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/FunctionCompilerInterface.php new file mode 100644 index 0000000..b364f0b --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/FunctionCompilerInterface.php @@ -0,0 +1,29 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\Func; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler; + +interface FunctionCompilerInterface +{ + function getName(); + function compilePreconditions(ExpressionCompiler $compiler, FunctionExpression $function); + function compile(ExpressionCompiler $compiler, FunctionExpression $function); +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/HasAnyRoleFunctionCompiler.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/HasAnyRoleFunctionCompiler.php new file mode 100644 index 0000000..02e71fa --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/HasAnyRoleFunctionCompiler.php @@ -0,0 +1,63 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\Func; + +use JMS\SecurityExtraBundle\Exception\RuntimeException; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler; + +class HasAnyRoleFunctionCompiler implements FunctionCompilerInterface +{ + private $rolesExpr; + + public function getName() + { + return 'hasAnyRole'; + } + + public function compilePreconditions(ExpressionCompiler $compiler, FunctionExpression $function) + { + if (0 === count($function->args)) { + throw new RuntimeException('The function hasAnyRole() expects at least one argument, but got none.'); + } + + $this->rolesExpr = $compiler->getRolesExpr(); + } + + public function compile(ExpressionCompiler $compiler, FunctionExpression $function) + { + $compiler->write("("); + + $first = true; + foreach ($function->args as $arg) { + if (!$first) { + $compiler->write(" || "); + } + $first = false; + + $compiler + ->write("isset({$this->rolesExpr}[") + ->compileInternal($arg) + ->write("])") + ; + } + + $compiler->write(")"); + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/HasRoleFunctionCompiler.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/HasRoleFunctionCompiler.php new file mode 100644 index 0000000..77a9834 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/HasRoleFunctionCompiler.php @@ -0,0 +1,51 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\Func; + +use JMS\SecurityExtraBundle\Exception\RuntimeException; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler; + +class HasRoleFunctionCompiler implements FunctionCompilerInterface +{ + private $rolesExpr; + + public function getName() + { + return 'hasRole'; + } + + public function compilePreconditions(ExpressionCompiler $compiler, FunctionExpression $function) + { + if (1 !== count($function->args)) { + throw new RuntimeException(sprintf('The hasRole() function expects exactly one argument, but got "%s".', var_export($function->args, true))); + } + + $this->rolesExpr = $compiler->getRolesExpr(); + } + + public function compile(ExpressionCompiler $compiler, FunctionExpression $function) + { + $compiler + ->write("isset({$this->rolesExpr}[") + ->compileInternal($function->args[0]) + ->write("])") + ; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/IsAnonymousFunctionCompiler.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/IsAnonymousFunctionCompiler.php new file mode 100644 index 0000000..412825d --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/IsAnonymousFunctionCompiler.php @@ -0,0 +1,39 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\Func; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\VariableExpression; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler; + +class IsAnonymousFunctionCompiler extends AuthenticationTrustFunctionCompiler +{ + public function getName() + { + return 'isAnonymous'; + } + + public function compile(ExpressionCompiler $compiler, FunctionExpression $function) + { + $compiler + ->compileInternal(new VariableExpression('trust_resolver')) + ->write("->isAnonymous(\$context['token'])"); + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/IsAuthenticatedFunctionCompiler.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/IsAuthenticatedFunctionCompiler.php new file mode 100644 index 0000000..ead97d8 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/IsAuthenticatedFunctionCompiler.php @@ -0,0 +1,41 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\Func; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\VariableExpression; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler; + +class IsAuthenticatedFunctionCompiler extends AuthenticationTrustFunctionCompiler +{ + public function getName() + { + return 'isAuthenticated'; + } + + public function compile(ExpressionCompiler $compiler, FunctionExpression $function) + { + $compiler + ->write("!") + ->compileInternal(new VariableExpression('trust_resolver')) + ->write("->isAnonymous(\$context['token'])") + ; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/IsFullyAuthenticatedFunctionCompiler.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/IsFullyAuthenticatedFunctionCompiler.php new file mode 100644 index 0000000..366ef07 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/IsFullyAuthenticatedFunctionCompiler.php @@ -0,0 +1,39 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\Func; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\VariableExpression; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler; + +class IsFullyAuthenticatedFunctionCompiler extends AuthenticationTrustFunctionCompiler +{ + public function getName() + { + return 'isFullyAuthenticated'; + } + + public function compile(ExpressionCompiler $compiler, FunctionExpression $function) + { + $compiler + ->compileInternal(new VariableExpression('trust_resolver')) + ->write("->isFullFledged(\$context['token'])"); + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/IsRememberMeFunctionCompiler.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/IsRememberMeFunctionCompiler.php new file mode 100644 index 0000000..cbba7c8 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/Func/IsRememberMeFunctionCompiler.php @@ -0,0 +1,39 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\Func; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\VariableExpression; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler; + +class IsRememberMeFunctionCompiler extends AuthenticationTrustFunctionCompiler +{ + public function getName() + { + return 'isRememberMe'; + } + + public function compile(ExpressionCompiler $compiler, FunctionExpression $function) + { + $compiler + ->compileInternal(new VariableExpression('trust_resolver')) + ->write("->isRememberMe(\$context['token'])"); + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/IsEqualExpressionCompiler.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/IsEqualExpressionCompiler.php new file mode 100644 index 0000000..93a8b23 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/IsEqualExpressionCompiler.php @@ -0,0 +1,32 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler; + +class IsEqualExpressionCompiler extends BinaryExprCompiler +{ + public function getType() + { + return 'JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\IsEqualExpression'; + } + + protected function getOperator() + { + return '==='; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/NotExpressionCompiler.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/NotExpressionCompiler.php new file mode 100644 index 0000000..1fccae8 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/NotExpressionCompiler.php @@ -0,0 +1,44 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ExpressionInterface; + +class NotExpressionCompiler implements TypeCompilerInterface +{ + public function getType() + { + return 'JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\NotExpression'; + } + + public function compilePreconditions(ExpressionCompiler $compiler, ExpressionInterface $expr) + { + $compiler->compilePreconditions($expr->expr); + } + + public function compile(ExpressionCompiler $compiler, ExpressionInterface $expr) + { + $compiler + ->write('!(') + ->compileInternal($expr->expr) + ->write(')') + ; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/OrExpressionCompiler.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/OrExpressionCompiler.php new file mode 100644 index 0000000..4a4554e --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/OrExpressionCompiler.php @@ -0,0 +1,32 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler; + +class OrExpressionCompiler extends BinaryExprCompiler +{ + public function getType() + { + return 'JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\OrExpression'; + } + + protected function getOperator() + { + return '||'; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/ParameterExpressionCompiler.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/ParameterExpressionCompiler.php new file mode 100644 index 0000000..678a119 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/ParameterExpressionCompiler.php @@ -0,0 +1,80 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\VariableExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ExpressionInterface; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\TypeCompilerInterface; + +class ParameterExpressionCompiler implements TypeCompilerInterface +{ + public function getType() + { + return 'JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ParameterExpression'; + } + + public function compilePreconditions(ExpressionCompiler $compiler, ExpressionInterface $parameter) + { + $compiler->verifyItem('object', 'CG\Proxy\MethodInvocation'); + + if (!isset($compiler->attributes['parameter_mapping_name'])) { + $this->addParameterMapping($compiler); + } + + $compiler + ->writeln("if (!isset(\${$compiler->attributes['parameter_mapping_name']}['{$parameter->name}'])) {") + ->indent() + ->write("throw new RuntimeException(sprintf('There is no parameter with name \"{$parameter->name}\" for method \"%s\".', ") + ->compileInternal(new VariableExpression('object')) + ->writeln("));") + ->outdent() + ->write("}\n\n") + ; + } + + public function compile(ExpressionCompiler $compiler, ExpressionInterface $parameter) + { + $compiler + ->compileInternal(new VariableExpression('object')) + ->write("->arguments[") + ->write("\${$compiler->attributes['parameter_mapping_name']}") + ->write("['{$parameter->name}']]") + ; + } + + private function addParameterMapping(ExpressionCompiler $compiler) + { + $name = $compiler->nextName(); + $indexName = $compiler->nextName(); + $paramName = $compiler->nextName(); + + $compiler + ->setAttribute('parameter_mapping_name', $name) + ->writeln("\$$name = array();") + ->write("foreach (") + ->compileInternal(new VariableExpression('object')) + ->writeln("->reflection->getParameters() as \$$indexName => \$$paramName) {") + ->indent() + ->writeln("\${$name}[\${$paramName}->name] = \$$indexName;") + ->outdent() + ->writeln("}\n") + ; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/TypeCompilerInterface.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/TypeCompilerInterface.php new file mode 100644 index 0000000..949a631 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/TypeCompilerInterface.php @@ -0,0 +1,29 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ExpressionInterface; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler; + +interface TypeCompilerInterface +{ + function getType(); + function compilePreconditions(ExpressionCompiler $compiler, ExpressionInterface $expr); + function compile(ExpressionCompiler $compiler, ExpressionInterface $expr); +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/VariableExpressionCompiler.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/VariableExpressionCompiler.php new file mode 100644 index 0000000..ad1841c --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Compiler/VariableExpressionCompiler.php @@ -0,0 +1,74 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\VariableExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ExpressionInterface; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler; + +class VariableExpressionCompiler implements TypeCompilerInterface +{ + public function getType() + { + return 'JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\VariableExpression'; + } + + public function compilePreconditions(ExpressionCompiler $compiler, ExpressionInterface $expr) + { + if ('user' === $expr->name) { + $compiler + ->setAttribute('user_var_name', $name = $compiler->nextName()) + ->write("\$$name = ") + ->compileInternal(new VariableExpression('token')) + ->write("->getUser();\n\n") + ; + } + } + + public function compile(ExpressionCompiler $compiler, ExpressionInterface $expr) + { + if ('permitAll' === $expr->name) { + $compiler->write('true'); + + return; + } + + if ('denyAll' === $expr->name) { + $compiler->write('false'); + + return; + } + + if ('user' === $expr->name) { + $compiler->write("\${$compiler->attributes['user_var_name']}"); + + return; + } + + if ($expr->allowNull) { + $compiler->write("(isset(\$context['{$expr->name}']) ? "); + } + + $compiler->write("\$context['{$expr->name}']"); + + if ($expr->allowNull) { + $compiler->write(" : null)"); + } + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ContainerAwareExpressionHandler.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ContainerAwareExpressionHandler.php new file mode 100644 index 0000000..f2d29af --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ContainerAwareExpressionHandler.php @@ -0,0 +1,47 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionHandlerInterface; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Lazy-loading container aware expression handler. + * + * @author Johannes M. Schmitt + */ +class ContainerAwareExpressionHandler implements ExpressionHandlerInterface +{ + private $container; + + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + public function createContext(TokenInterface $token, $object) + { + return array( + 'container' => $this->container, + 'token' => $token, + 'object' => $object, + ); + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/DefaultExpressionHandler.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/DefaultExpressionHandler.php new file mode 100644 index 0000000..70e4e13 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/DefaultExpressionHandler.php @@ -0,0 +1,51 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression; + +use Symfony\Component\Security\Core\Role\RoleHierarchyInterface; +use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; + +class DefaultExpressionHandler implements ExpressionHandlerInterface +{ + private $trustResolver; + private $roleHierarchy; + + public function __construct(AuthenticationTrustResolverInterface $trustResolver, + RoleHierarchyInterface $roleHierarchy = null) + { + $this->trustResolver = $trustResolver; + $this->roleHierarchy = $roleHierarchy; + } + + public function createContext(TokenInterface $token, $object) + { + $context = array( + 'token' => $token, + 'object' => $object, + 'trust_resolver' => $this->trustResolver, + ); + + if (null !== $this->roleHierarchy) { + $context['role_hierarchy'] = $this->roleHierarchy; + } + + return $context; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Expression.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Expression.php new file mode 100644 index 0000000..219218d --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/Expression.php @@ -0,0 +1,40 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression; + +final class Expression +{ + /** READ-ONLY */ + public $expression; + + public function __construct($expression) + { + $this->expression = $expression; + } + + public function getHashCode() + { + return sha1($this->expression); + } + + public function __toString() + { + return 'EXPRESSION('.$this->expression.')'; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ExpressionCompiler.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ExpressionCompiler.php new file mode 100644 index 0000000..fbfc69a --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ExpressionCompiler.php @@ -0,0 +1,395 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression; + +use JMS\SecurityExtraBundle\Exception\RuntimeException; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\TypeCompilerInterface; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\IsEqualExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\Func\FunctionCompilerInterface; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ExpressionInterface; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\VariableExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\OrExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\MethodCallExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\GetPropertyExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\GetItemExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ConstantExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ArrayExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\AndExpression; + +class ExpressionCompiler +{ + public $attributes = array(); + + private $indentationLevel = 0; + private $indentationSpaces = 4; + + private $nameCount = 0; + private $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + private $charCount = 52; + private $reservedNames = array('context' => true); + + private $itemExists = array(); + private $itemType = array(); + private $rolesName; + + private $code; + private $parser; + private $typeCompilers; + private $functionCompilers; + + public function __construct() + { + $this->addTypeCompiler(new Compiler\AndExpressionCompiler()); + $this->addTypeCompiler(new Compiler\IsEqualExpressionCompiler()); + $this->addTypeCompiler(new Compiler\OrExpressionCompiler()); + $this->addTypeCompiler(new Compiler\VariableExpressionCompiler()); + $this->addTypeCompiler(new Compiler\NotExpressionCompiler()); + + $this->functionCompilers = array( + 'isAnonymous' => new Compiler\Func\IsAnonymousFunctionCompiler(), + 'isAuthenticated' => new Compiler\Func\IsAuthenticatedFunctionCompiler(), + 'isRememberMe' => new Compiler\Func\IsRememberMeFunctionCompiler(), + 'isFullyAuthenticated' => new Compiler\Func\IsFullyAuthenticatedFunctionCompiler(), + 'hasRole' => new Compiler\Func\HasRoleFunctionCompiler(), + 'hasAnyRole' => new Compiler\Func\HasAnyRoleFunctionCompiler(), + ); + } + + public function setAttribute($name, $value) + { + $this->attributes[$name] = $value; + + return $this; + } + + public function addTypeCompiler(TypeCompilerInterface $compiler) + { + $this->typeCompilers[$compiler->getType()] = $compiler; + } + + public function addFunctionCompiler(FunctionCompilerInterface $compiler) + { + $this->functionCompilers[$compiler->getName()] = $compiler; + } + + public function compileExpression(Expression $expr) + { + return $this->compile($this->getParser()->parse($expr->expression), + $expr->expression); + } + + public function compile(ExpressionInterface $expr, $raw = null) + { + $this->nameCount = 0; + $this->code = ''; + $this->itemExists = $this->itemType = $this->attributes = array(); + $this->rolesName = null; + + if ($raw) { + $this->writeln('// Expression: '.$raw); + } + + $this + ->writeln('return function(array $context) {') + ->indent() + ->compilePreconditions($expr) + ->write('return ') + ->compileInternal($expr) + ->writeln(';') + ->outdent() + ->writeln('};') + ; + + return $this->code; + } + + public function indent() + { + $this->indentationLevel += 1; + + return $this; + } + + public function outdent() + { + $this->indentationLevel -= 1; + + if ($this->indentationLevel < 0) { + throw new RuntimeException('The identation level cannot be less than zero.'); + } + + return $this; + } + + public function writeln($content) + { + $this->write($content."\n"); + + return $this; + } + + public function getRolesExpr() + { + if (null !== $this->rolesName) { + return '$'.$this->rolesName; + } + + $this->verifyItem('token', 'Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + + $this->rolesName = $rolesName = $this->nextName(); + $hierarchyName = $this->nextName(); + $tmpName = $this->nextName(); + $this + ->writeln("\$$rolesName = \$context['token']->getRoles();") + ->write("if (null !== \$$hierarchyName = ") + ->compileInternal(new VariableExpression('role_hierarchy', true)) + ->writeln(") {") + ->indent() + ->writeln("\$$rolesName = \${$hierarchyName}->getReachableRoles(\$$rolesName);") + ->outdent() + ->write("}\n\n") + ->writeln("\$$tmpName = array();") + ->writeln("foreach (\$$rolesName as \$role) {") + ->indent() + ->writeln("\${$tmpName}[\$role->getRole()] = true;") + ->outdent() + ->writeln("}") + ->write("\$$rolesName = \$$tmpName;\n\n") + ; + + return '$'.$rolesName; + } + + public function verifyItem($key, $expectedType = null) + { + if (!isset($this->itemExists[$key])) { + $this->itemExists[$key] = true; + + $this + ->writeln("if (!isset(\$context['$key'])) {") + ->indent() + ->writeln("throw new RuntimeException('The context contains no item with key \"$key\".');") + ->outdent() + ->write("}\n\n") + ; + } + + if (null !== $expectedType) { + if (isset($this->itemType[$key])) { + if ($this->itemType[$key] !== $expectedType) { + throw new RuntimeException(sprintf('Cannot verify that item "%s" is of type "%s" because it is already expected to be of type "%s".', + $key, $expectedType, $this->itemType[$key] + )); + } + + return $this; + } + + $this + ->writeln("if (!\$context['$key'] instanceof $expectedType) {") + ->indent() + ->writeln("throw new RuntimeException(sprintf('The item \"$key\" is expected to be of type \"$expectedType\", but got \"%s\".', get_class(\$context['$key'])));") + ->outdent() + ->write("}\n\n") + ; + } + + return $this; + } + + public function write($content) + { + $lines = explode("\n", $content); + for ($i=0,$c=count($lines); $i<$c; $i++) { + if ($this->indentationLevel > 0 + && !empty($lines[$i]) + && (empty($this->code) || "\n" === substr($this->code, -1))) { + $this->code .= str_repeat(' ', $this->indentationLevel * $this->indentationSpaces); + } + + $this->code .= $lines[$i]; + + if ($i+1 < $c) { + $this->code .= "\n"; + } + } + + return $this; + } + + public function nextName() + { + while (true) { + $name = ''; + $i = $this->nameCount; + + $name .= $this->chars[$i % $this->charCount]; + $i = intval($i / $this->charCount); + + while ($i > 0) { + $i -= 1; + $name .= $this->chars[$i % $this->charCount]; + $i = intval($i / $this->charCount); + } + + $this->nameCount += 1; + + // check that the name is not reserved + if (isset($this->reservedNames[$name])) { + continue; + } + + return $name; + } + } + + public function compilePreconditions(ExpressionInterface $expr) + { + if ($typeCompiler = $this->findTypeCompiler(get_class($expr))) { + $typeCompiler->compilePreconditions($this, $expr); + + return $this; + } + + if ($expr instanceof FunctionExpression) { + $this->getFunctionCompiler($expr->name)->compilePreconditions($this, $expr); + + foreach ($expr->args as $arg) { + $this->compilePreconditions($arg); + } + + return $this; + } + + if ($expr instanceof VariableExpression) { + $this->getVariableCompiler($expr->name)->compilePreconditions($this, $expr); + + return $this; + } + + if ($expr instanceof MethodCallExpression) { + $this->compilePreconditions($expr->object); + + foreach ($expr->args as $arg) { + $this->compilePreconditions($arg); + } + + return $this; + } + + if ($expr instanceof GetPropertyExpression) { + $this->compilePreconditions($expr->object); + + return $this; + } + + return $this; + } + + public function compileInternal(ExpressionInterface $expr) + { + if ($typeCompiler = $this->findTypeCompiler(get_class($expr))) { + $typeCompiler->compile($this, $expr); + + return $this; + } + + if ($expr instanceof ArrayExpression) { + $this->code .= 'array('; + foreach ($expr->elements as $key => $value) { + $this->code .= var_export($key, true).' => '; + $this->compileInternal($value); + $this->code .= ','; + } + $this->code .= ')'; + + return $this; + } + + if ($expr instanceof ConstantExpression) { + $this->code .= var_export($expr->value, true); + + return $this; + } + + if ($expr instanceof FunctionExpression) { + $this->getFunctionCompiler($expr->name)->compile($this, $expr); + + return $this; + } + + if ($expr instanceof GetItemExpression) { + $this->compileInternal($expr->array); + $this->code .= '['.$expr->key.']'; + + return $this; + } + + if ($expr instanceof GetPropertyExpression) { + $this->compileInternal($expr->object); + $this->code .= '->'.$expr->name; + + return $this; + } + + if ($expr instanceof MethodCallExpression) { + $this->compileInternal($expr->object); + $this->code .= '->'.$expr->method.'('; + + $first = true; + foreach ($expr->args as $arg) { + if (!$first) { + $this->code .= ', '; + } + $first = false; + + $this->compileInternal($arg); + } + $this->code .= ')'; + + return $this; + } + + throw new RuntimeException(sprintf('Unknown expression "%s".', get_class($expr))); + } + + public function getFunctionCompiler($name) + { + if (!isset($this->functionCompilers[$name])) { + throw new RuntimeException(sprintf('There is no compiler for function "%s".', $name)); + } + + return $this->functionCompilers[$name]; + } + + private function findTypeCompiler($type) + { + return isset($this->typeCompilers[$type]) ? $this->typeCompilers[$type] : null; + } + + private function getParser() + { + if (null !== $this->parser) { + return $this->parser; + } + + return $this->parser = new ExpressionParser(); + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ExpressionHandlerInterface.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ExpressionHandlerInterface.php new file mode 100644 index 0000000..24e6024 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ExpressionHandlerInterface.php @@ -0,0 +1,26 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression; + +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; + +interface ExpressionHandlerInterface +{ + function createContext(TokenInterface $token, $object); +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ExpressionLexer.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ExpressionLexer.php new file mode 100644 index 0000000..e1f4445 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ExpressionLexer.php @@ -0,0 +1,134 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression; + +use JMS\SecurityExtraBundle\Exception\InvalidArgumentException; + +final class ExpressionLexer +{ + public $token; + public $lookahead; + + private $tokens; + private $pointer; + + const T_STRING = 1; + const T_IDENTIFIER = 2; + const T_NONE = 3; + const T_COMMA = 4; + const T_OPEN_PARENTHESIS = 5; + const T_CLOSE_PARENTHESIS = 6; + const T_AND = 7; + const T_OR = 8; + const T_PARAMETER = 9; + const T_OBJECT_OPERATOR = 10; + const T_OPEN_BRACKET = 11; + const T_CLOSE_BRACKET = 12; + const T_OPEN_BRACE = 13; + const T_CLOSE_BRACE = 14; + const T_COLON = 15; + const T_IS_EQUAL = 16; + const T_NOT = 17; + + public static function getLiteral($type) + { + static $constants; + + if (null === $constants) { + $ref = new \ReflectionClass(get_called_class()); + $constants = $ref->getConstants(); + } + + if (false === $literal = array_search($type, $constants, true)) { + throw new InvalidArgumentException(sprintf('There is no token of value "%s".', $type)); + } + + return $literal; + } + + public function initialize($input) + { + static $pattern = '/(#?[a-z][a-z0-9]*|\'(?:[^\']|(?<=\\\\)\')*\'|"(?:[^"]|(?<=\\\\)")*"|&&|\|\||==)|\s+|(.)/i'; + + $parts = preg_split($pattern, $input, -1, PREG_SPLIT_OFFSET_CAPTURE + | PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); + + $tokens = array(); + foreach ($parts as $part) { + list($value, $position) = $part; + $type = self::T_NONE; + + if ("'" === $value[0] || '"' === $value[0]) { + $type = self::T_STRING; + $value = substr($value, 1, -1); + } else if (',' === $value) { + $type = self::T_COMMA; + } else if ('(' === $value) { + $type = self::T_OPEN_PARENTHESIS; + } else if (')' === $value) { + $type = self::T_CLOSE_PARENTHESIS; + } else if ('[' === $value) { + $type = self::T_OPEN_BRACKET; + } else if (']' === $value) { + $type = self::T_CLOSE_BRACKET; + } else if ('{' === $value) { + $type = self::T_OPEN_BRACE; + } else if ('}' === $value) { + $type = self::T_CLOSE_BRACE; + } else if ('&&' === $value || 'and' === strtolower($value)) { + $type = self::T_AND; + } else if ('||' === $value || 'or' === strtolower($value)) { + $type = self::T_OR; + } else if ('!' === $value || 'not' === strtolower($value)) { + $type = self::T_NOT; + } else if (':' === $value) { + $type = self::T_COLON; + } else if ('.' === $value) { + $type = self::T_OBJECT_OPERATOR; + } else if ('==' === $value) { + $type = self::T_IS_EQUAL; + } else if ('#' === $value[0]) { + $type = self::T_PARAMETER; + $value = substr($value, 1); + } else if (ctype_alpha($value)) { + $type = self::T_IDENTIFIER; + } + + $tokens[] = array( + 'type' => $type, + 'value' => $value, + 'position' => $position, + ); + } + + $this->tokens = $tokens; + $this->pointer = -1; + $this->next(); + } + + public function next() + { + $this->pointer += 1; + $this->token = $this->lookahead; + $this->lookahead = isset($this->tokens[$this->pointer]) ? + $this->tokens[$this->pointer] : null; + + return $this->lookahead !== null; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ExpressionParser.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ExpressionParser.php new file mode 100644 index 0000000..98fd32e --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ExpressionParser.php @@ -0,0 +1,290 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\NotExpression; + +use JMS\SecurityExtraBundle\Exception\RuntimeException; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\IsEqualExpression; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ParameterExpression; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\VariableExpression; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ConstantExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\OrExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\AndExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ArrayExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\GetItemExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\GetPropertyExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\MethodCallExpression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ExpressionInterface; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression; + +final class ExpressionParser +{ + const PRECEDENCE_OR = 10; + const PRECEDENCE_AND = 15; + const PRECEDENCE_IS_EQUAL = 20; + const PRECEDENCE_NOT = 30; + + private $lexer; + + public function __construct() + { + $this->lexer = new ExpressionLexer(); + } + + public function parse($str) + { + $this->lexer->initialize($str); + + return $this->Expression(); + } + + private function Expression($precedence = 0) + { + $expr = $this->Primary(); + + while (true) { + if (ExpressionLexer::T_AND === $this->lexer->lookahead['type'] + && $precedence <= self::PRECEDENCE_AND) { + $this->lexer->next(); + + $expr = new AndExpression($expr, $this->Expression( + self::PRECEDENCE_AND + 1)); + continue; + } + + if (ExpressionLexer::T_OR === $this->lexer->lookahead['type'] + && $precedence <= self::PRECEDENCE_OR) { + $this->lexer->next(); + + $expr = new OrExpression($expr, $this->Expression( + self::PRECEDENCE_OR + 1)); + continue; + } + + if (ExpressionLexer::T_IS_EQUAL === $this->lexer->lookahead['type'] + && $precedence <= self::PRECEDENCE_IS_EQUAL) { + $this->lexer->next(); + + $expr = new IsEqualExpression($expr, $this->Expression( + self::PRECEDENCE_IS_EQUAL + 1)); + continue; + } + + break; + } + + return $expr; + } + + private function Primary() + { + if (ExpressionLexer::T_NOT === $this->lexer->lookahead['type']) { + $this->lexer->next(); + $expr = new NotExpression($this->Expression(self::PRECEDENCE_NOT)); + + return $this->Suffix($expr); + } + + if (ExpressionLexer::T_OPEN_PARENTHESIS === $this->lexer->lookahead['type']) { + $this->lexer->next(); + $expr = $this->Expression(); + $this->match(ExpressionLexer::T_CLOSE_PARENTHESIS); + + return $this->Suffix($expr); + } + + if (ExpressionLexer::T_STRING === $this->lexer->lookahead['type']) { + return new ConstantExpression($this->match(ExpressionLexer::T_STRING)); + } + + if (ExpressionLexer::T_OPEN_BRACE === $this->lexer->lookahead['type']) { + return $this->Suffix($this->MapExpr()); + } + + if (ExpressionLexer::T_OPEN_BRACKET === $this->lexer->lookahead['type']) { + return $this->Suffix($this->ListExpr()); + } + + if (ExpressionLexer::T_IDENTIFIER === $this->lexer->lookahead['type']) { + $name = $this->match(ExpressionLexer::T_IDENTIFIER); + + if (ExpressionLexer::T_OPEN_PARENTHESIS === $this->lexer->lookahead['type']) { + $args = $this->Arguments(); + + return $this->Suffix(new FunctionExpression($name, $args)); + } + + return $this->Suffix(new VariableExpression($name)); + } + + if (ExpressionLexer::T_PARAMETER === $this->lexer->lookahead['type']) { + return $this->Suffix(new ParameterExpression($this->match(ExpressionLexer::T_PARAMETER))); + } + + $this->error('primary expression'); + } + + private function ListExpr() + { + $this->match(ExpressionLexer::T_OPEN_BRACKET); + + $elements = array(); + while (ExpressionLexer::T_CLOSE_BRACKET !== $this->lexer->lookahead['type']) { + $elements[] = $this->Expression(); + + if (ExpressionLexer::T_COMMA !== $this->lexer->lookahead['type']) { + break; + } + $this->lexer->next(); + } + + $this->match(ExpressionLexer::T_CLOSE_BRACKET); + + return new ArrayExpression($elements); + } + + private function MapExpr() + { + $this->match(ExpressionLexer::T_OPEN_BRACE); + + $entries = array(); + while (ExpressionLexer::T_CLOSE_BRACE !== $this->lexer->lookahead['type']) { + $key = $this->match(ExpressionLexer::T_STRING); + $this->match(ExpressionLexer::T_COLON); + $entries[$key] = $this->Expression(); + + if (ExpressionLexer::T_COMMA !== $this->lexer->lookahead['type']) { + break; + } + + $this->lexer->next(); + } + + $this->match(ExpressionLexer::T_CLOSE_BRACE); + + return new ArrayExpression($entries); + } + + private function Suffix(ExpressionInterface $expr) + { + while (true) { + if (ExpressionLexer::T_OBJECT_OPERATOR === $this->lexer->lookahead['type']) { + $this->lexer->next(); + $name = $this->match(ExpressionLexer::T_IDENTIFIER); + + if (ExpressionLexer::T_OPEN_PARENTHESIS === $this->lexer->lookahead['type']) { + $args = $this->Arguments(); + $expr = new MethodCallExpression($expr, $name, $args); + continue; + } + + $expr = new GetPropertyExpression($expr, $name); + continue; + } + + if (ExpressionLexer::T_OPEN_BRACKET === $this->lexer->lookahead['type']) { + $this->lexer->next(); + $key = $this->Expression(); + $this->match(ExpressionLexer::T_CLOSE_BRACKET); + $expr = new GetItemExpression($expr, $key); + continue; + } + + break; + } + + return $expr; + } + + private function FunctionCall() + { + $name = $this->match(ExpressionLexer::T_IDENTIFIER); + $args = $this->Arguments(); + + return new FunctionExpression($name, $args); + } + + private function Arguments() + { + $this->match(ExpressionLexer::T_OPEN_PARENTHESIS); + $args = array(); + + while (ExpressionLexer::T_CLOSE_PARENTHESIS !== $this->lexer->lookahead['type']) { + $args[] = $this->Expression(); + + if (ExpressionLexer::T_COMMA !== $this->lexer->lookahead['type']) { + break; + } + + $this->match(ExpressionLexer::T_COMMA); + } + $this->match(ExpressionLexer::T_CLOSE_PARENTHESIS); + + return $args; + } + + private function Value() + { + return $this->matchAny(array(ExpressionLexer::T_STRING)); + } + + private function matchAny(array $types) + { + if (null !== $this->lexer->lookahead) { + foreach ($types as $type) { + if ($type === $this->lexer->lookahead['type']) { + $this->lexer->next(); + + return $this->lexer->token['value']; + } + } + } + + $this->error(sprintf('one of these tokens "%s"', + implode('", "', array_map(array('JMS\SecurityExtraBundle\Security\Authorization\Expression\Lexer', 'getLiteral'), $types)) + )); + } + + private function match($type) + { + if (null === $this->lexer->lookahead + || $type !== $this->lexer->lookahead['type']) { + $this->error(sprintf('token "%s"', ExpressionLexer::getLiteral($type))); + } + + $this->lexer->next(); + + return $this->lexer->token['value']; + } + + private function error($expected) + { + $actual = null === $this->lexer->lookahead ? 'end of file' + : sprintf('token "%s" with value "%s" at position %d', + ExpressionLexer::getLiteral($this->lexer->lookahead['type']), + $this->lexer->lookahead['value'], + $this->lexer->lookahead['position']); + + throw new RuntimeException(sprintf('Expected %s, but got %s.', $expected, $actual)); + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ExpressionVoter.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ExpressionVoter.php new file mode 100644 index 0000000..cf04742 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/ExpressionVoter.php @@ -0,0 +1,114 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression; + +use JMS\SecurityExtraBundle\Exception\RuntimeException; +use Symfony\Component\Security\Core\Role\RoleHierarchyInterface; +use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface; + +/** + * Expression-based voter. + * + * This voter allows to use complex access expression in a high-performance + * way. This is the preferred voter for any non-simple access checks. + * + * @author Johannes M. Schmitt + */ +class ExpressionVoter implements VoterInterface +{ + private $evaluators = array(); + private $compiler; + private $cacheDir; + private $expressionHandler; + + public function __construct(ExpressionHandlerInterface $expressionHandler) { + $this->expressionHandler = $expressionHandler; + } + + public function setCacheDir($cacheDir) + { + $this->cacheDir = $cacheDir; + } + + public function setCompiler(ExpressionCompiler $compiler) + { + $this->compiler = $compiler; + } + + public function vote(TokenInterface $token, $object, array $attributes) + { + $result = VoterInterface::ACCESS_ABSTAIN; + + foreach ($attributes as $attribute) { + if (!$attribute instanceof Expression) { + continue; + } + + $result = VoterInterface::ACCESS_DENIED; + if (!isset($this->evaluators[$attribute->expression])) { + $this->evaluators[$attribute->expression] = + $this->createEvaluator($attribute); + } + + if (call_user_func($this->evaluators[$attribute->expression], + $this->expressionHandler->createContext($token, $object))) { + return VoterInterface::ACCESS_GRANTED; + } + } + + return $result; + } + + public function supportsAttribute($attribute) + { + return $attribute instanceof Expression; + } + + public function supportsClass($class) + { + return true; + } + + protected function getCompiler() + { + if (null === $this->compiler) { + throw new RuntimeException('A compiler must be set.'); + } + + return $this->compiler; + } + + private function createEvaluator(Expression $expr) + { + if ($this->cacheDir) { + if (is_file($file = $this->cacheDir.'/'.sha1($expr->expression).'.php')) { + return require $file; + } + + $source = $this->getCompiler()->compileExpression($expr); + file_put_contents($file, "getCompiler()->compileExpression($expr)); + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/LazyLoadingExpressionVoter.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/LazyLoadingExpressionVoter.php new file mode 100644 index 0000000..b9d577e --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Expression/LazyLoadingExpressionVoter.php @@ -0,0 +1,39 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Expression; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionVoter; + +class LazyLoadingExpressionVoter extends ExpressionVoter +{ + private $container; + private $compilerId; + + public function setLazyCompiler(ContainerInterface $container, $id) + { + $this->container = $container; + $this->compilerId = $id; + } + + protected function getCompiler() + { + return $this->container->get($this->compilerId); + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Interception/MethodSecurityInterceptor.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Interception/MethodSecurityInterceptor.php new file mode 100644 index 0000000..8d4c63a --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Interception/MethodSecurityInterceptor.php @@ -0,0 +1,150 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Interception; + +use JMS\SecurityExtraBundle\Exception\RuntimeException; +use CG\Core\ClassUtils; + +use CG\Proxy\MethodInterceptorInterface; +use CG\Proxy\MethodInvocation; +use JMS\SecurityExtraBundle\Metadata\MethodMetadata; +use JMS\SecurityExtraBundle\Security\Authentication\Token\RunAsUserToken; +use JMS\SecurityExtraBundle\Security\Authorization\AfterInvocation\AfterInvocationManagerInterface; +use JMS\SecurityExtraBundle\Security\Authorization\RunAsManagerInterface; +use Metadata\MetadataFactoryInterface; +use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface; +use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; +use Symfony\Component\Security\Core\SecurityContext; +use Symfony\Component\Security\Core\Exception\AccessDeniedException; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException; + +/** + * All invocations of secure methods will go through this class. + * + * @author Johannes M. Schmitt + */ +class MethodSecurityInterceptor implements MethodInterceptorInterface +{ + private $alwaysAuthenticate; + private $securityContext; + private $metadataFactory; + private $authenticationManager; + private $accessDecisionManager; + private $afterInvocationManager; + private $runAsManager; + private $logger; + + public function __construct(SecurityContext $securityContext, AuthenticationManagerInterface $authenticationManager, AccessDecisionManagerInterface $accessDecisionManager, + AfterInvocationManagerInterface $afterInvocationManager, RunAsManagerInterface $runAsManager, MetadataFactoryInterface $metadataFactory, LoggerInterface $logger = null) + { + $this->alwaysAuthenticate = false; + $this->securityContext = $securityContext; + $this->metadataFactory = $metadataFactory; + $this->authenticationManager = $authenticationManager; + $this->accessDecisionManager = $accessDecisionManager; + $this->afterInvocationManager = $afterInvocationManager; + $this->runAsManager = $runAsManager; + $this->logger = $logger; + } + + public function setAlwaysAuthenticate($boolean) + { + $this->alwaysAuthenticate = !!$boolean; + } + + public function intercept(MethodInvocation $method) + { + $metadata = $this->metadataFactory->getMetadataForClass($method->reflection->class); + + // no security metadata, proceed + if (empty($metadata) || !isset($metadata->methodMetadata[$method->reflection->name])) { + return $method->proceed(); + } + $metadata = $metadata->methodMetadata[$method->reflection->name]; + + if (null === $token = $this->securityContext->getToken()) { + throw new AuthenticationCredentialsNotFoundException( + 'The security context was not populated with a Token.' + ); + } + + if ($this->alwaysAuthenticate || !$token->isAuthenticated()) { + $token = $this->authenticationManager->authenticate($token); + $this->securityContext->setToken($token); + } + + if (!empty($metadata->roles) && false === $this->accessDecisionManager->decide($token, $metadata->roles, $method)) { + throw new AccessDeniedException('Token does not have the required roles.'); + } + + if (!empty($metadata->paramPermissions)) { + foreach ($method->arguments as $index => $argument) { + if (null !== $argument && isset($metadata->paramPermissions[$index]) && false === $this->accessDecisionManager->decide($token, $metadata->paramPermissions[$index], $argument)) { + throw new AccessDeniedException(sprintf('Token does not have the required permissions for method "%s::%s".', $method->reflection->class, $method->reflection->name)); + } + } + } + + $runAsToken = null; + if (!empty($metadata->runAsRoles)) { + $runAsToken = $this->runAsManager->buildRunAs($token, $method, $metadata->runAsRoles); + + if (null !== $this->logger) { + $this->logger->debug('Populating security context with RunAsToken'); + } + + if (null === $runAsToken) { + throw new RuntimeException('RunAsManager must not return null from buildRunAs().'); + } + + $this->securityContext->setToken($runAsToken); + } + + try { + $returnValue = $method->proceed(); + + if (null !== $runAsToken) { + $this->restoreOriginalToken($runAsToken); + } + + if (empty($metadata->returnPermissions)) { + return $returnValue; + } + + return $this->afterInvocationManager->decide($this->securityContext->getToken(), $method, $metadata->returnPermissions, $returnValue); + } catch (\Exception $failed) { + if (null !== $runAsToken) { + $this->restoreOriginalToken($runAsToken); + } + + throw $failed; + } + } + + private function restoreOriginalToken(RunAsUserToken $runAsToken) + { + if (null !== $this->logger) { + $this->logger->debug('Populating security context with original Token.'); + } + + $this->securityContext->setToken($runAsToken->getOriginalToken()); + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Interception/SecurityPointcut.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Interception/SecurityPointcut.php new file mode 100644 index 0000000..9cba96c --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Interception/SecurityPointcut.php @@ -0,0 +1,92 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Interception; + +use CG\Core\ClassUtils; +use Metadata\MetadataFactoryInterface; +use JMS\AopBundle\Aop\PointcutInterface; + +class SecurityPointcut implements PointcutInterface +{ + private $metadataFactory; + private $secureAllServices; + private $securedClasses = array(); + private $patterns; + + public function __construct(MetadataFactoryInterface $metadataFactory, $secureAllServices = false, array $patterns = array()) + { + $this->metadataFactory = $metadataFactory; + $this->secureAllServices = $secureAllServices; + $this->patterns = $patterns; + } + + public function setSecuredClasses(array $classes) + { + $this->securedClasses = $classes; + } + + public function matchesClass(\ReflectionClass $class) + { + if ($this->secureAllServices) { + return true; + } + + if ('Controller' === substr(ClassUtils::getUserClass($class->name), -10)) { + return true; + } + + foreach ($this->patterns as $pattern => $expr) { + // if not for all patterns the class is specified, then we need to scan all + // classes to catch all methods + if (false === $pos = strpos($pattern, '::')) { + // controller notation is already checked by JMSDiExtraBundle, + // we can safely ignore these patterns here + if (2 === substr_count($pattern, ':')) { + continue; + } + + return true; + } + + if (0 < preg_match('#'.substr($pattern, 0, $pos).'$#', $class->name)) { + return true; + } + } + + foreach ($this->securedClasses as $securedClass) { + if ($class->name === $securedClass || $class->isSubclassOf($securedClass)) { + return true; + } + } + + return false; + } + + public function matchesMethod(\ReflectionMethod $method) + { + $userClass = ClassUtils::getUserClass($method->class); + $metadata = $this->metadataFactory->getMetadataForClass($userClass); + + if (null === $metadata) { + return false; + } + + return isset($metadata->methodMetadata[$method->name]); + } +} diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/RunAsManager.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/RunAsManager.php new file mode 100644 index 0000000..f1884df --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/RunAsManager.php @@ -0,0 +1,79 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization; + +use JMS\SecurityExtraBundle\Security\Authentication\Token\RunAsUserToken; +use Symfony\Component\Security\Core\Role\Role; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; + +/** + * The RunAsManager creates throw-away Tokens which are temporarily injected into + * the security context for the duration of the invocation of a specific method. + * + * @author Johannes M. Schmitt + */ +class RunAsManager implements RunAsManagerInterface +{ + private $key; + private $rolePrefix; + + public function __construct($key, $rolePrefix = 'ROLE_') + { + $this->key = $key; + $this->rolePrefix = $rolePrefix; + } + + /** + * {@inheritDoc} + */ + public function buildRunAs(TokenInterface $token, $secureObject, array $attributes) + { + $roles = array(); + foreach ($attributes as $attribute) + { + if ($this->supportsAttribute($attribute)) { + $roles[] = new Role($attribute); + } + } + + if (0 === count($roles)) { + return null; + } + + $roles = array_merge($roles, $token->getRoles()); + + return new RunAsUserToken($this->key, $token->getUser(), $token->getCredentials(), $roles, $token); + } + + /** + * {@inheritDoc} + */ + public function supportsAttribute($attribute) + { + return !empty($attribute) && 0 === strpos($attribute, $this->rolePrefix); + } + + /** + * {@inheritDoc} + */ + public function supportsClass($className) + { + return true; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/RunAsManagerInterface.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/RunAsManagerInterface.php new file mode 100644 index 0000000..a2b4909 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/RunAsManagerInterface.php @@ -0,0 +1,57 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization; + +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; + +/** + * RunAsManagerInterface + * + * @author Johannes M. Schmitt + */ +interface RunAsManagerInterface +{ + /** + * Creates a temporary RunAsToken. + * + * The returned Token must have a complementing AuthenticationProvider implementation. + * + * @param TokenInterface $token the original Token + * @param object $secureObject the secure object which caused this call + * @param array $attributes an array of attributes to apply to the built token + * @return TokenInterface + */ + function buildRunAs(TokenInterface $token, $secureObject, array $attributes); + + /** + * Whether this RunAsManager supports the given attribute + * + * @param string $attribute + * @return Boolean + */ + function supportsAttribute($attribute); + + /** + * Whether this RunAsManager supports the given class. + * + * @param string $className The class of the secure object which requests RunAs capabilities + * @return Boolean + */ + function supportsClass($className); +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Voter/IddqdVoter.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Voter/IddqdVoter.php new file mode 100644 index 0000000..663cd4e --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Voter/IddqdVoter.php @@ -0,0 +1,61 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Security\Authorization\Voter; + +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface; + +/** + * This voter adds a special role "ROLE_IDDQD" which effectively bypasses any, + * and all security checks. + * + * Most of the time, you will want to use this rule in combination with a + * @RunAs annotation to disable security checks for the invocation of a + * specific method. + * + * @author Johannes M. Schmitt + */ +class IddqdVoter implements VoterInterface +{ + public function vote(TokenInterface $token, $object, array $attributes) + { + return $this->isIddqd($token) ? VoterInterface::ACCESS_GRANTED : VoterInterface::ACCESS_ABSTAIN; + } + + protected function isIddqd(TokenInterface $token) + { + foreach ($token->getRoles() as $role) { + if ('ROLE_IDDQD' === $role->getRole()) { + return true; + } + } + + return false; + } + + public function supportsAttribute($attribute) + { + return true; + } + + public function supportsClass($class) + { + return true; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Twig/SecurityExtension.php b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Twig/SecurityExtension.php new file mode 100644 index 0000000..21ad8aa --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Twig/SecurityExtension.php @@ -0,0 +1,35 @@ +context = $context; + } + + public function getFunctions() + { + return array( + 'is_expr_granted' => new \Twig_Function_Method($this, 'isExprGranted', array( + 'is_safe' => true, + )), + ); + } + + public function isExprGranted($expr, $object = null) + { + return $this->context->isGranted(array(new Expression($expr)), $object); + } + + public function getName() + { + return 'jms_security_extra'; + } +} \ No newline at end of file diff --git a/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/composer.json b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/composer.json new file mode 100644 index 0000000..00e4113 --- /dev/null +++ b/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/composer.json @@ -0,0 +1,25 @@ +{ + "name": "jms/security-extra-bundle", + "description": "Enhances the Symfony2 Security Component by adding several new features", + "keywords": ["annotations","authorization"], + "type": "symfony-bundle", + "license": "Apache", + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "require": { + "symfony/framework-bundle": "2.*", + "jms/metadata": "1.1.*", + "jms/aop-bundle": "1.0.*" + }, + "recommend": { + "jms/di-extra-bundle": "1.0.*" + }, + "autoload": { + "psr-0": { "JMS\\SecurityExtraBundle": "" } + }, + "target-dir": "JMS/SecurityExtraBundle" +} diff --git a/vendor/kriswallsmith/assetic/.travis.yml b/vendor/kriswallsmith/assetic/.travis.yml new file mode 100644 index 0000000..a801b15 --- /dev/null +++ b/vendor/kriswallsmith/assetic/.travis.yml @@ -0,0 +1,16 @@ +language: php + +php: + - 5.3 + - 5.4 + +before_script: + - wget http://getcomposer.org/composer.phar + - php composer.phar install --dev + - git clone https://github.com/kamicane/packager.git vendor/packager --quiet --depth 1 + - git clone https://github.com/leafo/lessphp.git vendor/lessphp --quiet --depth 1 + - git clone https://github.com/mrclay/minify.git vendor/minify --quiet --depth 1 + - svn checkout http://cssmin.googlecode.com/svn/trunk/ vendor/cssmin --quiet + - wget --quiet -O javascript-packer.zip "http://joliclic.free.fr/php/javascript-packer/telechargement.php?id=2&action=telecharger" && mkdir -p vendor/packer && unzip -qq javascript-packer.zip -d vendor/packer; rm javascript-packer.zip + +script: phpunit --configuration phpunit.travis.xml diff --git a/vendor/kriswallsmith/assetic/CHANGELOG-1.0.md b/vendor/kriswallsmith/assetic/CHANGELOG-1.0.md new file mode 100644 index 0000000..91bb9bf --- /dev/null +++ b/vendor/kriswallsmith/assetic/CHANGELOG-1.0.md @@ -0,0 +1,29 @@ +1.0.3 (March 2, 2012) +--------------------- + + * Added "boring" option to Compass filter + * Fixed accumulation of load paths in Compass filter + * Fixed issues in CssImport and CssRewrite filters + +1.0.2 (August 26, 2011) +----------------------- + + * Twig 1.2 compatibility + * Fixed filtering of large LessCSS assets + * Fixed escaping of commands on Windows + * Misc fixes to Compass filter + * Removed default CssEmbed charset + +1.0.1 (July 15, 2011) +--------------------- + + * Fixed Twig error handling + * Removed use of STDIN + * Added inheritance of environment variables + * Fixed Compass on Windows + * Improved escaping of commands + +1.0.0 (July 10, 2011) +--------------------- + + * Initial release diff --git a/vendor/kriswallsmith/assetic/CHANGELOG-1.1.md b/vendor/kriswallsmith/assetic/CHANGELOG-1.1.md new file mode 100755 index 0000000..48ed70d --- /dev/null +++ b/vendor/kriswallsmith/assetic/CHANGELOG-1.1.md @@ -0,0 +1,9 @@ +1.1.0 (???) +--------------------- + + * Added the UglifyJsFilter + * added support for asset variables: + + Asset variables allow you to pre-compile your assets for a finite set of known + variable values, and then to simply deliver the correct asset version at runtime. + For example, this is helpful for assets with language, or browser-specific code. diff --git a/vendor/kriswallsmith/assetic/LICENSE b/vendor/kriswallsmith/assetic/LICENSE new file mode 100644 index 0000000..1060e5b --- /dev/null +++ b/vendor/kriswallsmith/assetic/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010-2012 OpenSky Project Inc + +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/kriswallsmith/assetic/README.md b/vendor/kriswallsmith/assetic/README.md new file mode 100644 index 0000000..e12e341 --- /dev/null +++ b/vendor/kriswallsmith/assetic/README.md @@ -0,0 +1,284 @@ +# Assetic ![project status](http://stillmaintained.com/kriswallsmith/assetic.png) # + +Assetic is an asset management framework for PHP. + +``` php +dump(); +``` + +Assets +------ + +An Assetic asset is something with filterable content that can be loaded and +dumped. An asset also includes metadata, some of which can be manipulated and +some of which is immutable. + +| **Property** | **Accessor** | **Mutator** | +|--------------|-----------------|---------------| +| content | getContent | setContent | +| mtime | getLastModified | n/a | +| source root | getSourceRoot | n/a | +| source path | getSourcePath | n/a | +| target path | getTargetPath | setTargetPath | + +Filters +------- + +Filters can be applied to manipulate assets. + +``` php +dump(); +``` + +The filters applied to the collection will cascade to each asset leaf if you +iterate over it. + +``` php +dump(); +} +``` + +The core provides the following filters in the `Assetic\Filter` namespace: + + * `CoffeeScriptFilter`: compiles CoffeeScript into Javascript + * `CssEmbedFilter`: embeds image data in your stylesheets + * `CssImportFilter`: inlines imported stylesheets + * `CssMinFilter`: minifies CSS + * `CssRewriteFilter`: fixes relative URLs in CSS assets when moving to a new URL + * `GoogleClosure\CompilerApiFilter`: compiles Javascript using the Google Closure Compiler API + * `GoogleClosure\CompilerJarFilter`: compiles Javascript using the Google Closure Compiler JAR + * `JpegoptimFilter`: optimize your JPEGs + * `JpegtranFilter`: optimize your JPEGs + * `LessFilter`: parses LESS into CSS (using less.js with node.js) + * `LessphpFilter`: parses LESS into CSS (using lessphp) + * `OptiPngFilter`: optimize your PNGs + * `PackerFilter`: compresses Javascript using Dean Edwards's Packer + * `PngoutFilter`: optimize your PNGs + * `CompassFilter`: Compass CSS authoring framework + * `Sass\SassFilter`: parses SASS into CSS + * `Sass\ScssFilter`: parses SCSS into CSS + * `SprocketsFilter`: Sprockets Javascript dependency management + * `StylusFilter`: parses STYL into CSS + * `Yui\CssCompressorFilter`: compresses CSS using the YUI compressor + * `Yui\JsCompressorFilter`: compresses Javascript using the YUI compressor + +Asset Manager +------------- + +An asset manager is provided for organizing assets. + +``` php +set('jquery', new FileAsset('/path/to/jquery.js')); +$am->set('base_css', new GlobAsset('/path/to/css/*')); +``` + +The asset manager can also be used to reference assets to avoid duplication. + +``` php +set('my_plugin', new AssetCollection(array( + new AssetReference($am, 'jquery'), + new FileAsset('/path/to/jquery.plugin.js'), +))); +``` + +Filter Manager +-------------- + +A filter manager is also provided for organizing filters. + +``` php +set('sass', new SassFilter('/path/to/parser/sass')); +$fm->set('yui_css', new Yui\CssCompressorFilter('/path/to/yuicompressor.jar')); +``` + +Asset Factory +------------- + +If you'd rather not create all these objects by hand, you can use the asset +factory, which will do most of the work for you. + +``` php +setAssetManager($am); +$factory->setFilterManager($fm); +$factory->setDebug(true); + +$css = $factory->createAsset(array( + '@reset', // load the asset manager's "reset" asset + 'css/src/*.scss', // load every scss files from "/path/to/asset/directory/css/src/" +), array( + 'scss', // filter through the filter manager's "scss" filter + '?yui_css', // don't use this filter in debug mode +)); + +echo $css->dump(); +``` + +Prefixing a filter name with a question mark, as `yui_css` is here, will cause +that filter to be omitted when the factory is in debug mode. + +Caching +------- + +A simple caching mechanism is provided to avoid unnecessary work. + +``` php +dump(); +$js->dump(); +$js->dump(); +``` + +Static Assets +------------- + +Alternatively you can just write filtered assets to your web directory and be +done with it. + +``` php +writeManagerAssets($am); +``` + +Twig +---- + +To use the Assetic [Twig][3] extension you must register it to your Twig +environment: + +``` php +addExtension(new AsseticExtension($factory, $debug)); +``` + +Once in place, the extension exposes a stylesheets and a javascripts tag with a syntax similar +to what the asset factory uses: + +``` html+jinja +{% stylesheets '/path/to/sass/main.sass' filter='sass,?yui_css' output='css/all.css' %} + +{% endstylesheets %} +``` + +This example will render one `link` element on the page that includes a URL +where the filtered asset can be found. + +When the extension is in debug mode, this same tag will render multiple `link` +elements, one for each asset referenced by the `css/src/*.sass` glob. The +specified filters will still be applied, unless they are marked as optional +using the `?` prefix. + +This behavior can also be triggered by setting a `debug` attribute on the tag: + +``` html+jinja +{% stylesheets 'css/*' debug=true %} ... {% stylesheets %} +``` + +These assets need to be written to the web directory so these URLs don't +return 404 errors. + +``` php +setLoader('twig', new TwigFormulaLoader($twig)); + +// loop through all your templates +foreach ($templates as $template) { + $resource = new TwigResource($twigLoader, $template); + $am->addResource($resource, 'twig'); +} + +$writer = new AssetWriter('/path/to/web'); +$writer->writeManagerAssets($am); +``` + +--- + +Assetic is based on the Python [webassets][1] library (available on +[GitHub][2]). + +[1]: http://elsdoerfer.name/docs/webassets +[2]: https://github.com/miracle2k/webassets +[3]: http://twig.sensiolabs.org diff --git a/vendor/kriswallsmith/assetic/composer.json b/vendor/kriswallsmith/assetic/composer.json new file mode 100644 index 0000000..a871c3e --- /dev/null +++ b/vendor/kriswallsmith/assetic/composer.json @@ -0,0 +1,35 @@ +{ + "name": "kriswallsmith/assetic", + "description": "Asset Management for PHP", + "keywords": ["assets", "compression", "minification"], + "homepage": "https://github.com/kriswallsmith/assetic", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Kris Wallsmith", + "email": "kris.wallsmith@gmail.com", + "homepage": "http://kriswallsmith.net/" + } + ], + "require": { + "php": ">=5.3.0", + "symfony/process": "2.1.*" + }, + "require-dev": { + "twig/twig": ">=1.6.0,<2.0", + "leafo/lessphp": "*" + }, + "suggest": { + "twig/twig": "Assetic provides the integration with the Twig templating engine", + "leafo/lessphp": "Assetic provides the integration with the lessphp LESS compiler" + }, + "autoload": { + "psr-0": { "Assetic": "src/" } + }, + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + } +} diff --git a/vendor/kriswallsmith/assetic/docs/en/build.md b/vendor/kriswallsmith/assetic/docs/en/build.md new file mode 100644 index 0000000..d560172 --- /dev/null +++ b/vendor/kriswallsmith/assetic/docs/en/build.md @@ -0,0 +1,32 @@ +Building and Dumping Assets +--------------------------- + +The is the simplest approach to using Assetic. It involves two steps: + + 1. Create a PHP script in your web directory that uses the Assetic OOP API to + create and output an asset. + 2. Reference that file from your template. + +For example, you could create a file in your web directory at +`assets/javascripts.php` with the following code: + + use Assetic\Asset\AssetCollection; + use Assetic\Asset\FileAsset; + use Assetic\Filter\Yui\JsCompressorFilter as YuiCompressorFilter; + + $js = new AssetCollection(array( + new FileAsset(__DIR__.'/jquery.js'), + new FileAsset(__DIR__.'/application.js'), + ), array( + new YuiCompressorFilter('/path/to/yuicompressor.jar'), + )); + + header('Content-Type: application/js'); + echo $js->dump(); + +In your HTML template you would include this generated Javascript using a +simple ` + +Next: [Basic Concepts](concepts.md) diff --git a/vendor/kriswallsmith/assetic/docs/en/concepts.md b/vendor/kriswallsmith/assetic/docs/en/concepts.md new file mode 100644 index 0000000..7af7b1f --- /dev/null +++ b/vendor/kriswallsmith/assetic/docs/en/concepts.md @@ -0,0 +1,129 @@ +In order to use the Assetic OOP API you must first understand the two central +concepts of Assetic: assets and filters. + +### What is an Asset? + +As asset is an object that has content and metadata which can be loaded and +dumped. Your assets will probably fall into three categories: Javascripts, +stylesheets and images. Most assets will be loaded from files in your +filesystem, but they can also be loaded via HTTP, a database, from a string, +or virtually anything else. All that an asset has to do is fulfill Assetic's +basic asset interface. + +### What is a Filter? + +A filter is an object that acts upon an asset's content when that asset is +loaded and/or dumped. Similar to assets, a filter can do virtually anything, +as long as it implements Assetic's filter interface. + +Here is a list of some of the tools that can be applied to assets using a +filter: + + * CoffeeScript + * CssEmbed + * CssMin + * Google Closure Compiler + * jpegoptim + * jpegtran + * Less + * LessPHP + * optipng + * Packager + * pngout + * SASS + * Sprockets (version 1) + * Stylus + * YUI Compressor + +### Using Assets and Filters + +You need to start by creating an asset object. This will probably mean +instantiating a `FileAsset` instance, which takes a filesystem path as its +first argument: + + $asset = new Assetic\Asset\FileAsset('/path/to/main.css'); + +Once you have an asset you can begin adding filters to it by calling +`ensureFilter()`. For example, you can add a filter that applies the YUI +Compressor to the contents of the asset: + + $yui = new Assetic\Filter\Yui\CssCompressorFilter('/path/to/yui.jar'); + $asset->ensureFilter($yui); + +Once you've added as many filters as you'd like you can output the finished +asset to the browser: + + header('Content-Type: text/css'); + echo $asset->dump(); + +### Asset Collections + +It is a good idea to combine assets of the same type into a single file to +avoid unnecessary HTTP requests. You can do this in Assetic using the +`AssetCollection` class. This class is just like any other asset in Assetic's +eyes as it implements the asset interface, but under the hood it allows you to +combine multiple assets into one. + + use Assetic\Asset\AssetCollection; + + $asset = new AssetCollection(array( + new FileAsset('/path/to/js/jquery.js'), + new FileAsset('/path/to/js/jquery.plugin.js'), + new FileAsset('/path/to/js/application.js'), + )); + +### Nested Asset Collections + +The collection class implements the asset interface and all assets passed into +a collection must implement the same interface, which means you can easily +nest collections within one another: + + use Assetic\Asset\AssetCollection; + use Assetic\Asset\GlobAsset; + use Assetic\Asset\HttpAsset; + + $asset = new AssetCollection(array( + new HttpAsset('http://example.com/jquery.min.js'), + new GlobAsset('/path/to/js/*'), + )); + +The `HttpAsset` class is a special asset class that loads a file over HTTP; +`GlobAsset` is a special asset collection class that loads files based on a +filesystem glob -- both implement the asset interface. + +This concept of nesting asset collection become even more powerful when you +start applying different sets of filters to each collection. Imagine some of +your application's stylesheets are written in SASS, while some are written in +vanilla CSS. You can combine all of these into one seamless CSS asset: + + use Assetic\Asset\AssetCollection; + use Assetic\Asset\GlobAsset; + use Assetic\Filter\SassFilter; + use Assetic\Filter\Yui\CssCompressorFilter; + + $css = new AssetCollection(array( + new GlobAsset('/path/to/sass/*.sass', array(new SassFilter())), + new GlobAsset('/path/to/css/*.css'), + ), array( + new YuiCompressorFilter('/path/to/yuicompressor.jar'), + )); + +You'll notice I've also applied the YUI compressor filter to the combined +asset so all CSS will be minified. + +### Iterating over an Asset Collection + +Once you have an asset collection you can iterate over it like you would a +plain old PHP array: + + echo "Source paths:\n"; + foreach ($collection as $asset) { + echo ' - '.$asset->getSourcePath()."\n"; + } + +The asset collection iterates recursively, which means you will only see the +"leaf" assets during iteration. Iteration also includes a smart filter which +ensures you only see each asset once, even if the same asset has been included +multiple times. + +Next: [Defining Assets "On The Fly"](define.md) diff --git a/vendor/kriswallsmith/assetic/docs/en/define.md b/vendor/kriswallsmith/assetic/docs/en/define.md new file mode 100644 index 0000000..3d8d3b1 --- /dev/null +++ b/vendor/kriswallsmith/assetic/docs/en/define.md @@ -0,0 +1,145 @@ +Defining Assets "On The Fly" +---------------------------- + +The second approach to using Assetic involves defining your application's +assets "on the fly" in your templates, instead of in an isolated PHP file. +Using this approach, your PHP template would look something like this: + + + +This call to `assetic_javascripts()` serves a dual purpose. It will be read by +the Assetic "formula loader" which will extract an asset "formula" that can be +used to build, dump and output the asset. It will also be executed when the +template is rendered, at which time the path to the output asset is output. + +Assetic includes the following templating helper functions: + + * `assetic_image()` + * `assetic_javascripts()` + * `assetic_stylesheets()` + +Defining assets on the fly is a much more sophisticated technique and +therefore relies on services to do the heavy lifting. The main one being the +asset factory. + +### Asset Factory + +The asset factory knows how to create asset objects using only arrays and +scalar values as input. This is the same string syntax used by the `assetic_*` +template helper functions. + + use Assetic\Factory\AssetFactory; + + $factory = new AssetFactory('/path/to/web'); + $js = $factory->createAsset(array( + 'js/jquery.js', + 'js/jquery.plugin.js', + 'js/application.js', + )); + +### Filter Manager + +You can also apply filters to asset created by the factory. To do this you +must setup a `FilterManager`, which organizes filters by a name. + + use Assetic\FilterManager; + use Assetic\Filter\GoogleClosure\ApiFilter as ClosureFilter; + + $fm = new FilterManager(); + $fm->set('closure', new ClosureFilter()); + $factory->setFilterManager($fm); + + $js = $factory->createAsset('js/*', 'closure'); + +This code creates an instance of the Google Closure Compiler filter and +assigns it the name `closure` using a filter manager. This filter manager is +then injected into the asset factory, making the filter available as `closure` +when creating assets. + +### Debug Mode + +The asset factory also introduces the concept of a debug mode. This mode +allows you to omit certain filters from assets the factory creates depending +on whether it is enabled or not. + +For example, the YUI Compressor is awesome, but it is only appropriate in a +production environment as it is very difficult to debug minified Javascript. + + use Asset\Factory\AssetFactory; + + $factory = new AssetFactory('/path/to/web', true); // debug mode is on + $factory->setFilterManager($fm); + $js = $factory->createAsset('js/*', '?closure'); + +By prefixing the `closure` filter's name with a question mark, we are telling +the factory this filter is optional and should only be applied with debug mode +is off. + +### Asset Manager and Asset References + +The asset factory provides another special string syntax that allows you to +reference assets you defined elsewhere. These are called "asset references" +and involve an asset manager which, similar to the filter manager, organizes +assets by name. + + use Assetic\AssetManager; + use Assetic\Asset\FileAsset; + use Assetic\Factory\AssetFactory; + + $am = new AssetManager(); + $am->set('jquery', new FileAsset('/path/to/jquery.js')); + + $factory = new AssetFactory('/path/to/web'); + $factory->setAssetManager($am); + + $js = $factory->createAsset(array( + '@jquery', + 'js/application.js', + )); + +### Extracting Assets from Templates + +Once you've defined a set of assets in your templates you must use the +"formula loader" service to extract these asset definitions. + + use Assetic\Factory\Loader\FunctionCallsFormulaLoader; + use Assetic\Factory\Resource\FileResource; + + $loader = new FunctionCallsFormulaLoader($factory); + $formulae = $loader->load(new FileResource('/path/to/template.php')); + +These asset formulae aren't much use by themselves. They each include just +enough information for the asset factory to create the intended asset object. +In order for these to be useful they must be wrapped in the special +`LazyAssetManager`. + +### The Lazy Asset Manager + +This service is a composition of the asset factory and one or more formula +loaders. It acts as the glue between these services behind the scenes, but can +be used just like a normal asset manager on the surface. + + use Assetic\Asset\FileAsset; + use Assetic\Factory\LazyAssetManager; + use Assetic\Factory\Loader\FunctionCallsFormulaLoader; + use Assetic\Factory\Resource\DirectoryResource; + + $am = new LazyAssetManager($factory); + $am->set('jquery', new FileAsset('/path/to/jquery.js')); + $am->setLoader('php', new FunctionCallsFormulaLoader($factory)); + $am->addResource(new DirectoryResource('/path/to/templates', '/\.php$/'), 'php'); + +### Asset Writer + +Finally, once you've create an asset manager that knows about every asset +you've defined in your templates, you must use an asset writer to actually +create the files your templates are going to be referencing. + + use Assetic\AssetWriter; + + $writer = new AssetWriter('/path/to/web'); + $writer->writeManagerAssets($am); + +After running this script, all of the assets in your asset manager will be +loaded into memory, filtered with their configured filters and dumped to your +web directory as static files, ready to be served. diff --git a/vendor/kriswallsmith/assetic/docs/en/index.md b/vendor/kriswallsmith/assetic/docs/en/index.md new file mode 100644 index 0000000..46dc590 --- /dev/null +++ b/vendor/kriswallsmith/assetic/docs/en/index.md @@ -0,0 +1,7 @@ +Table Of Contents +----------------- + + 1. [Introduction](introduction.md) + 2. [Building and Dumping Assets](build.md) + 3. [Basic Concepts](concepts.md) + 4. [Defining Assets "On The Fly"](define.md) diff --git a/vendor/kriswallsmith/assetic/docs/en/introduction.md b/vendor/kriswallsmith/assetic/docs/en/introduction.md new file mode 100644 index 0000000..352f496 --- /dev/null +++ b/vendor/kriswallsmith/assetic/docs/en/introduction.md @@ -0,0 +1,21 @@ +What is Assetic? +---------------- + +Assetic is an asset management framework for PHP 5.3. Assetic enables you to +use a variety of third party tools that will help bring order to your +application's Javascripts, stylesheets and images. + +How Do I Use Assetic? +--------------------- + +There are two distinct approaches you can take when using Assetic: + + 1. Build, dump and output assets in PHP files that you reference directly + from your templates + 2. Defining assets in your templates ("on the fly") and use a loader to + extract, dump and output them + +The first approach is simpler, but the second, with all its moving parts, +offers more flexibility and opportunity for optimization. + +Next: [Building and Dumping Assets](build.md) diff --git a/vendor/kriswallsmith/assetic/docs/ja/build.md b/vendor/kriswallsmith/assetic/docs/ja/build.md new file mode 100644 index 0000000..bee59ba --- /dev/null +++ b/vendor/kriswallsmith/assetic/docs/ja/build.md @@ -0,0 +1,30 @@ +アセットのビルドとダンプ +--------------------------- + +Asseticを使う一番単純な方法は、次の2ステップからなります。 + + 1. 公開領域内にPHPスクリプトを作成し、Assetic OOP APIを使用してアセットの作成・出力を行う + 2. テンプレートから上記のファイルを参照する + +例えば、公開領域内に`assets/javascripts.php`ファイルを作成し、 +下記のようなコードを記述します。 + + use Assetic\Asset\AssetCollection; + use Assetic\Asset\FileAsset; + use Assetic\Filter\Yui\JsCompressorFilter as YuiCompressorFilter; + + $js = new AssetCollection(array( + new FileAsset(__DIR__.'/jquery.js'), + new FileAsset(__DIR__.'/application.js'), + ), array( + new YuiCompressorFilter('/path/to/yuicompressor.jar'), + )); + + header('Content-Type: application/js'); + echo $js->dump(); + +HTMLテンプレート側では、単に` + +Next: [コンセプト](concepts.md) diff --git a/vendor/kriswallsmith/assetic/docs/ja/concepts.md b/vendor/kriswallsmith/assetic/docs/ja/concepts.md new file mode 100644 index 0000000..3479b20 --- /dev/null +++ b/vendor/kriswallsmith/assetic/docs/ja/concepts.md @@ -0,0 +1,121 @@ +Assetic OOP APIを使用するためには、まず、[アセット」と「フィルタ」の2つの重要なコンセプトを理解する必要があります。 + +### アセット + +アセットとは、読み込み、及びダンプが可能な、コンテンツとメタデータを内包しているオブジェクトの事を指します。 +大体の場合において3つのカテゴリー、すなわち、Javascriptとスタイルシート、画像のどれかに属することになるでしょう。 +読み込みの方法としては、ファイルシステムからがほとんどですが、 +HTTPやデータベース経由でも、文字列としてでも読み込みが可能で、事実上あらゆるものが読み込み可能です。 +Asseticのアセットインターフェースを満足させさえすれば良いのです。 + + +### フィルタ + +フィルタは、アセットが読み込まれる、かつ/もしくは、ダンプされる際に、 +アセットコンテンツに対して作用するオブジェクトです。 +アセットと同様に、Asseticのフィルタインターフェースを実装することで、 +どのような作用も可能になります。 + +フィルタを用いて、アセットに適用できるツール群の一覧です。 + + * CoffeeScript + * CssEmbed + * CssMin + * Google Closure Compiler + * jpegoptim + * jpegtran + * Less + * LessPHP + * optipng + * Packager + * pngout + * SASS + * Sprockets (version 1) + * Stylus + * YUI Compressor + + +### アセットとフィルタの使用 + +まずはアセットオブジェクトを作成することから始まります。 +多くの場合は`FileAsset`をインスタンス化し、ファイルシステムのパスを第一引数に渡します。 + + $asset = new Assetic\Asset\FileAsset('/path/to/main.css'); + +アセットオブジェクトを作成したら、`ensureFilter()`を呼び、フィルタを追加します。 +例えば、アセットコンテンツにYUI Compressorを適用してみましょう。 + + $yui = new Assetic\Filter\Yui\CssCompressorFilter('/path/to/yui.jar'); + $asset->ensureFilter($yui); + +任意のフィルタを追加したら、完成したアセットをブラウザに出力してみましょう。 + + header('Content-Type: text/css'); + echo $asset->dump(); + +### アセットコレクション + +1つのファイルに同じ種類のアセットをまとめて、不要なHTTPリクエストを抑えてみるのも良いでしょう。 +Asseticでは`AsseticColletion`クラスを使用することで可能となります。 +Assetic内部的には、このクラス自体は他のアセットと同様に、アセットインターフェースを実装したものですが、 +複数のアセットを1つにまとめることが可能になります。 + + use Assetic\Asset\AssetCollection; + + $asset = new AssetCollection(array( + new FileAsset('/path/to/js/jquery.js'), + new FileAsset('/path/to/js/jquery.plugin.js'), + new FileAsset('/path/to/js/application.js'), + )); + +### ネストしたアセットコレクション + +コレクションクラス自体がアセットインターフェースを実装し、コレクション内のアセットも同様に +アセットインターフェースを実装しているので、簡単にネストすることができます。 + + use Assetic\Asset\AssetCollection; + use Assetic\Asset\GlobAsset; + use Assetic\Asset\HttpAsset; + + $asset = new AssetCollection(array( + new HttpAsset('http://example.com/jquery.min.js'), + new GlobAsset('/path/to/js/*'), + )); + +`HttpAsset`は、HTTP経由でファイルを読み込むアセットクラス。 +`GlobAsset`は、ファイルシステムのglobを基にファイル群を読み込むアセットコレクションクラス。 +両者ともにアセットインターフェースを実装しています。 + +このネストしたアセットコレクションという概念は、コレクションそれぞれに異なる +フィルタ群を適用しようとしたときに、効果を発揮します。 +例えば、スタイルシートがSAASで記述されたものと、vanilla CSSを用いて記述されたものからなる +アプリケーションを考えた場合、次のようにして、全てを1つのシームレスなCSSアセットにまとめることができます。 + + use Assetic\Asset\AssetCollection; + use Assetic\Asset\GlobAsset; + use Assetic\Filter\SassFilter; + use Assetic\Filter\Yui\CssCompressorFilter; + + $css = new AssetCollection(array( + new GlobAsset('/path/to/sass/*.sass', array(new SassFilter())), + new GlobAsset('/path/to/css/*.css'), + ), array( + new YuiCompressorFilter('/path/to/yuicompressor.jar'), + )); + +上記の例では、1つにまとめられたCSSを、さらにYUI compressorフィルタを適用することで、全体を圧縮しています。 + +### アセットコレクションのイテレーション + +アセットコレクションは、旧来のPHP配列のように、イテレートできます。 + + echo "Source paths:\n"; + foreach ($collection as $asset) { + echo ' - '.$asset->getSourcePath()."\n"; + } + +アセットコレクションのイテレーションは再帰的で、「葉」にあたるアセットの取得を行います。 +また、気の利いたフィルタを内蔵しているので、同じアセットがコレクション内に複数存在する場合でも、 +一度だけのインクルードが保証されます。 + +Next: [アセットを「オンザフライ」で定義する](define.md) diff --git a/vendor/kriswallsmith/assetic/docs/ja/define.md b/vendor/kriswallsmith/assetic/docs/ja/define.md new file mode 100644 index 0000000..3b04436 --- /dev/null +++ b/vendor/kriswallsmith/assetic/docs/ja/define.md @@ -0,0 +1,140 @@ +アセットの「オンザフライ」な定義 +---------------------------------------- + +Asseticの使用方法二つ目は、独立したPHPファイルを使用する代わりに、 +テンプレートで「オンザフライ」にアセット定義をする方法です。 +このアプローチでは、PHPテンプレートは下記のようになります。 + + + +`assetic_javascripts()`の呼び出しは2つの目的を兼ねています。 +まず、「フォーミュラローダー」により走査され、アセットの構築、ダンプ、及び出力を行うための「フォーミュラ(処方箋)」が抽出されます。 +また、テンプレートのレンダー時にも実行され、アセットの出力パスが出力されます。 + +Asseticには下記のようなヘルパー関数があります。 + + * `assetic_image()` + * `assetic_javascripts()` + * `assetic_stylesheets()` + +アセットをオンザフライに定義するということは、より高度なテクニックであり、 +そのため、重い仕事をするサービスに依存することになります。 +そのうちの重要なものがアセットファクトリです。 + +### アセットファクトリ + +アセットファクトリは、アセットオブジェクトを、配列とスカラ値のみから、 +どのように作成するのか把握しています。 +`assetic_*`ヘルパー関数で使用する記法と同様のものとなります。 + + use Assetic\Factory\AssetFactory; + + $factory = new AssetFactory('/path/to/web'); + $js = $factory->createAsset(array( + 'js/jquery.js', + 'js/jquery.plugin.js', + 'js/application.js', + )); + +### フィルタマネージャー + +ファクトリによって作成されたアセットに対しても、フィルタを適用することができます。 +そのためには、`FilterManager`を設定して、名前を定義しフィルタを構成します。 + + use Assetic\FilterManager; + use Assetic\Filter\GoogleClosure\ApiFilter as ClosureFilter; + + $fm = new FilterManager(); + $fm->set('closure', new ClosureFilter()); + $factory->setFilterManager($fm); + + $js = $factory->createAsset('js/*', 'closure'); + +上記の例では、Google Closure Compilerフィルタをインスタンス化し、 +フィルタマネージャーを通じて`closure`という名前をつけています。 +このフィルタマネージャーをアセットファクトリに渡すことで、 +アセット作成時には、`closure`という名前でフィルタを使用できるようになります。 + +### デバッグモード + +アセットファクトリは、デバッグモードというコンセプトも取り入れており、 +デバッグモードの設定により、ファクトリが作成するアセットから、 +特定のフィルタを除外することができます。 + +たとえば、YUI Compressorは大変素晴らしいのですが、圧縮されたJavascriptを +デバッグするのは大変難しく、プロダクション環境でのみの使用が適切でしょう。 + + use Asset\Factory\AssetFactory; + + $factory = new AssetFactory('/path/to/web', true); // デバッグモードON + $factory->setFilterManager($fm); + $js = $factory->createAsset('js/*', '?closure'); + +フィルタ名`closure`の前にクエスチョンマークを記述すると、ファクトリに対して、 +このフィルタはオプションであり、 +デバッグモードがOFFの時にのみ適用するように通知することができます。 + +### アセットマネージャーとアセットリファレンス + +アセットファクトリにはもう一つ特別な記法があり、別の場所で定義した +アセットを参照することができるようになります。 +これを「アセットリファレンス」と呼び、アセットマネージャーを通じて、 +フィルタマネージャーと同様の、名前によるアセットの構成が可能です。 + + use Assetic\AssetManager; + use Assetic\Asset\FileAsset; + use Assetic\Factory\AssetFactory; + + $am = new AssetManager(); + $am->set('jquery', new FileAsset('/path/to/jquery.js')); + + $factory = new AssetFactory('/path/to/web'); + $factory->setAssetManager($am); + + $js = $factory->createAsset(array( + '@jquery', + 'js/application.js', + )); + +### テンプレートからのアセット抽出 + +テンプレート内でアセット群を定義したら、「フォーミュラローダー」サービスを使用して、 +アセットの定義を抽出します。 + + use Assetic\Factory\Loader\FunctionCallsFormulaLoader; + use Assetic\Factory\Resource\FileResource; + + $loader = new FunctionCallsFormulaLoader($factory); + $formulae = $loader->load(new FileResource('/path/to/template.php')); + +これらのフォーミュラ自体は、それ自体で使途はあまりなく、 +アセットファクトリが目的のアセットオブジェクトを作成するに足る情報しか持っていません。 +`LazyAssetManager`でラップすることで有益なものとなります。 + +### レイジーなアセットマネージャー + +このサービスは、アセットファクトリと、1つ以上のフォーミュラローダーから成っており、 +裏方のサービス間のグルとして動作しますが、表面上では、通常のアセットマネージャーと同じように使用することができます。 + + use Assetic\Asset\FileAsset; + use Assetic\Factory\LazyAssetManager; + use Assetic\Factory\Loader\FunctionCallsFormulaLoader; + use Assetic\Factory\Resource\DirectoryResource; + + $am = new LazyAssetManager($factory); + $am->set('jquery', new FileAsset('/path/to/jquery.js')); + $am->setLoader('php', new FunctionCallsFormulaLoader($factory)); + $am->addResource(new DirectoryResource('/path/to/templates', '/\.php$/'), 'php'); + +### アセットライター + +作成したアセットマネージャーが、テンプレート内で定義した全てのアセットを把握したら、 +アセットライターを使用して、テンプレートが参照することになる実際のファイルを作成します。 + + use Assetic\AssetWriter; + + $writer = new AssetWriter('/path/to/web'); + $writer->writeManagerAssets($am); + +上記のスクリプトを実行すると、アセットマネージャー内のすべてのアセットがメモリに読み込まれ、 +指定したフィルタが適用された後、公開領域に静的ファイルとしてダンプされ、準備完了となります。 diff --git a/vendor/kriswallsmith/assetic/docs/ja/index.md b/vendor/kriswallsmith/assetic/docs/ja/index.md new file mode 100644 index 0000000..138280d --- /dev/null +++ b/vendor/kriswallsmith/assetic/docs/ja/index.md @@ -0,0 +1,7 @@ +目次 +----- + + 1. [イントロダクション](introduction.md) + 2. [アセットの構築とダンプ](build.md) + 3. [コンセプト](concepts.md) + 4. [アセットを「オンザフライ」で定義する](define.md) diff --git a/vendor/kriswallsmith/assetic/docs/ja/introduction.md b/vendor/kriswallsmith/assetic/docs/ja/introduction.md new file mode 100644 index 0000000..0f45a8e --- /dev/null +++ b/vendor/kriswallsmith/assetic/docs/ja/introduction.md @@ -0,0 +1,18 @@ +Asseticとは +----------------- + +Asseticは、PHP5.3用のアセット管理フレームワークです。 +Asseticを導入することで、Javascriptやスタイルシート、画像をコントロールする +様々なサードパーティー製のツールを使用できるようになります。 + +Asseticの使用方法 +--------------------- + +2つの異なるアプローチがあります。 + + 1. アセットのビルド、ダンプ、出力をPHPファイルで行い、テンプレートからそのファイルを直接参照する方法 + 2. テンプレート内でアセットを(「オンザフライ」に)定義し、抽出やダンプ、出力にローダーを使用する方法 + +前者はいくらかシンプルである一方、後者は動的で柔軟性に富み、最適化が可能となります。 + +Next: [アセットの構築とダンプ](build.md) diff --git a/vendor/kriswallsmith/assetic/phpunit.travis.xml b/vendor/kriswallsmith/assetic/phpunit.travis.xml new file mode 100644 index 0000000..3a27eea --- /dev/null +++ b/vendor/kriswallsmith/assetic/phpunit.travis.xml @@ -0,0 +1,39 @@ + + + + + + ./tests/Assetic/Test/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ./src/Assetic/ + + + diff --git a/vendor/kriswallsmith/assetic/phpunit.xml.dist b/vendor/kriswallsmith/assetic/phpunit.xml.dist new file mode 100644 index 0000000..f22113e --- /dev/null +++ b/vendor/kriswallsmith/assetic/phpunit.xml.dist @@ -0,0 +1,42 @@ + + + + + + ./tests/Assetic/Test/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ./src/Assetic/ + + + diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCache.php b/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCache.php new file mode 100644 index 0000000..9b8a59b --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCache.php @@ -0,0 +1,168 @@ + + */ +class AssetCache implements AssetInterface +{ + private $asset; + private $cache; + + public function __construct(AssetInterface $asset, CacheInterface $cache) + { + $this->asset = $asset; + $this->cache = $cache; + } + + public function ensureFilter(FilterInterface $filter) + { + $this->asset->ensureFilter($filter); + } + + public function getFilters() + { + return $this->asset->getFilters(); + } + + public function clearFilters() + { + $this->asset->clearFilters(); + } + + public function load(FilterInterface $additionalFilter = null) + { + $cacheKey = self::getCacheKey($this->asset, $additionalFilter, 'load'); + if ($this->cache->has($cacheKey)) { + $this->asset->setContent($this->cache->get($cacheKey)); + return; + } + + $this->asset->load($additionalFilter); + $this->cache->set($cacheKey, $this->asset->getContent()); + } + + public function dump(FilterInterface $additionalFilter = null) + { + $cacheKey = self::getCacheKey($this->asset, $additionalFilter, 'dump'); + if ($this->cache->has($cacheKey)) { + return $this->cache->get($cacheKey); + } + + $content = $this->asset->dump($additionalFilter); + $this->cache->set($cacheKey, $content); + + return $content; + } + + public function getContent() + { + return $this->asset->getContent(); + } + + public function setContent($content) + { + $this->asset->setContent($content); + } + + public function getSourceRoot() + { + return $this->asset->getSourceRoot(); + } + + public function getSourcePath() + { + return $this->asset->getSourcePath(); + } + + public function getTargetPath() + { + return $this->asset->getTargetPath(); + } + + public function setTargetPath($targetPath) + { + $this->asset->setTargetPath($targetPath); + } + + public function getLastModified() + { + return $this->asset->getLastModified(); + } + + public function getVars() + { + return $this->asset->getVars(); + } + + public function setValues(array $values) + { + $this->asset->setValues($values); + } + + public function getValues() + { + return $this->asset->getValues(); + } + + /** + * Returns a cache key for the current asset. + * + * The key is composed of everything but an asset's content: + * + * * source root + * * source path + * * target url + * * last modified + * * filters + * + * @param AssetInterface $asset The asset + * @param FilterInterface $additionalFilter Any additional filter being applied + * @param string $salt Salt for the key + * + * @return string A key for identifying the current asset + */ + static private function getCacheKey(AssetInterface $asset, FilterInterface $additionalFilter = null, $salt = '') + { + if ($additionalFilter) { + $asset = clone $asset; + $asset->ensureFilter($additionalFilter); + } + + $cacheKey = $asset->getSourceRoot(); + $cacheKey .= $asset->getSourcePath(); + $cacheKey .= $asset->getTargetPath(); + $cacheKey .= $asset->getLastModified(); + + foreach ($asset->getFilters() as $filter) { + if ($filter instanceof HashableInterface) { + $cacheKey .= $filter->hash(); + } else { + $cacheKey .= serialize($filter); + } + } + + if ($values = $asset->getValues()) { + asort($values); + $cacheKey .= serialize($values); + } + + return md5($cacheKey.$salt); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollection.php b/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollection.php new file mode 100644 index 0000000..491d8dd --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollection.php @@ -0,0 +1,217 @@ + + */ +class AssetCollection implements \IteratorAggregate, AssetCollectionInterface +{ + private $assets; + private $filters; + private $sourceRoot; + private $targetPath; + private $content; + private $clones; + private $vars; + private $values; + + /** + * Constructor. + * + * @param array $assets Assets for the current collection + * @param array $filters Filters for the current collection + * @param string $sourceRoot The root directory + */ + public function __construct($assets = array(), $filters = array(), $sourceRoot = null, array $vars = array()) + { + $this->assets = array(); + foreach ($assets as $asset) { + $this->add($asset); + } + + $this->filters = new FilterCollection($filters); + $this->sourceRoot = $sourceRoot; + $this->clones = new \SplObjectStorage(); + $this->vars = $vars; + $this->values = array(); + } + + public function all() + { + return $this->assets; + } + + public function add(AssetInterface $asset) + { + $this->assets[] = $asset; + } + + public function removeLeaf(AssetInterface $needle, $graceful = false) + { + foreach ($this->assets as $i => $asset) { + $clone = isset($this->clones[$asset]) ? $this->clones[$asset] : null; + if (in_array($needle, array($asset, $clone), true)) { + unset($this->clones[$asset], $this->assets[$i]); + return true; + } elseif ($asset instanceof AssetCollectionInterface && $asset->removeLeaf($needle, true)) { + return true; + } + } + + if ($graceful) { + return false; + } + + throw new \InvalidArgumentException('Leaf not found.'); + } + + public function replaceLeaf(AssetInterface $needle, AssetInterface $replacement, $graceful = false) + { + foreach ($this->assets as $i => $asset) { + $clone = isset($this->clones[$asset]) ? $this->clones[$asset] : null; + if (in_array($needle, array($asset, $clone), true)) { + unset($this->clones[$asset]); + $this->assets[$i] = $replacement; + return true; + } elseif ($asset instanceof AssetCollectionInterface && $asset->replaceLeaf($needle, $replacement, true)) { + return true; + } + } + + if ($graceful) { + return false; + } + + throw new \InvalidArgumentException('Leaf not found.'); + } + + public function ensureFilter(FilterInterface $filter) + { + $this->filters->ensure($filter); + } + + public function getFilters() + { + return $this->filters->all(); + } + + public function clearFilters() + { + $this->filters->clear(); + } + + public function load(FilterInterface $additionalFilter = null) + { + // loop through leaves and load each asset + $parts = array(); + foreach ($this as $asset) { + $asset->load($additionalFilter); + $parts[] = $asset->getContent(); + } + + $this->content = implode("\n", $parts); + } + + public function dump(FilterInterface $additionalFilter = null) + { + // loop through leaves and dump each asset + $parts = array(); + foreach ($this as $asset) { + $parts[] = $asset->dump($additionalFilter); + } + + return implode("\n", $parts); + } + + public function getContent() + { + return $this->content; + } + + public function setContent($content) + { + $this->content = $content; + } + + public function getSourceRoot() + { + return $this->sourceRoot; + } + + public function getSourcePath() + { + } + + public function getTargetPath() + { + return $this->targetPath; + } + + public function setTargetPath($targetPath) + { + $this->targetPath = $targetPath; + } + + /** + * Returns the highest last-modified value of all assets in the current collection. + * + * @return integer|null A UNIX timestamp + */ + public function getLastModified() + { + if (!count($this->assets)) { + return; + } + + $mapper = function (AssetInterface $asset) + { + return $asset->getLastModified(); + }; + + return max(array_map($mapper, $this->assets)); + } + + /** + * Returns an iterator for looping recursively over unique leaves. + */ + public function getIterator() + { + return new \RecursiveIteratorIterator(new AssetCollectionFilterIterator(new AssetCollectionIterator($this, $this->clones))); + } + + public function getVars() + { + return $this->vars; + } + + public function setValues(array $values) + { + $this->values = $values; + + foreach ($this as $asset) { + $asset->setValues(array_intersect_key($values, array_flip($asset->getVars()))); + } + } + + public function getValues() + { + return $this->values; + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollectionInterface.php b/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollectionInterface.php new file mode 100644 index 0000000..710e75a --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollectionInterface.php @@ -0,0 +1,53 @@ + + */ +interface AssetCollectionInterface extends AssetInterface, \Traversable +{ + /** + * Returns all child assets. + * + * @return array An array of AssetInterface objects + */ + function all(); + + /** + * Adds an asset to the current collection. + * + * @param AssetInterface $asset An asset + */ + function add(AssetInterface $asset); + + /** + * Removes a leaf. + * + * @param AssetInterface $needle The leaf to remove + * + * @throws InvalidArgumentException If the asset cannot be found + */ + function removeLeaf(AssetInterface $leaf); + + /** + * Replaces an existing leaf with a new one. + * + * @param AssetInterface $needle The current asset to replace + * @param AssetInterface $replacement The new asset + * + * @throws InvalidArgumentException If the asset cannot be found + */ + function replaceLeaf(AssetInterface $needle, AssetInterface $replacement); +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetInterface.php b/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetInterface.php new file mode 100644 index 0000000..f324317 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetInterface.php @@ -0,0 +1,156 @@ + + */ +interface AssetInterface +{ + /** + * Ensures the current asset includes the supplied filter. + * + * @param FilterInterface $filter A filter + */ + function ensureFilter(FilterInterface $filter); + + /** + * Returns an array of filters currently applied. + * + * @return array An array of filters + */ + function getFilters(); + + /** + * Clears all filters from the current asset. + */ + function clearFilters(); + + /** + * Loads the asset into memory and applies load filters. + * + * You may provide an additional filter to apply during load. + * + * @param FilterInterface $additionalFilter An additional filter + */ + function load(FilterInterface $additionalFilter = null); + + /** + * Applies dump filters and returns the asset as a string. + * + * You may provide an additional filter to apply during dump. + * + * Dumping an asset should not change its state. + * + * If the current asset has not been loaded yet, it should be + * automatically loaded at this time. + * + * @param FilterInterface $additionalFilter An additional filter + * + * @return string The filtered content of the current asset + */ + function dump(FilterInterface $additionalFilter = null); + + /** + * Returns the loaded content of the current asset. + * + * @return string The content + */ + function getContent(); + + /** + * Sets the content of the current asset. + * + * Filters can use this method to change the content of the asset. + * + * @param string $content The asset content + */ + function setContent($content); + + /** + * Returns an absolute path or URL to the source asset's root directory. + * + * This value should be an absolute path to a directory in the filesystem, + * an absolute URL with no path, or null. + * + * For example: + * + * * '/path/to/web' + * * 'http://example.com' + * * null + * + * @return string|null The asset's root + */ + function getSourceRoot(); + + /** + * Returns the relative path for the source asset. + * + * This value can be combined with the asset's source root (if both are + * non-null) to get something compatible with file_get_contents(). + * + * For example: + * + * * 'js/main.js' + * * 'main.js' + * * null + * + * @return string|null The source asset path + */ + function getSourcePath(); + + /** + * Returns the URL for the current asset. + * + * @return string|null A web URL where the asset will be dumped + */ + function getTargetPath(); + + /** + * Sets the URL for the current asset. + * + * @param string $targetPath A web URL where the asset will be dumped + */ + function setTargetPath($targetPath); + + /** + * Returns the time the current asset was last modified. + * + * @return integer|null A UNIX timestamp + */ + function getLastModified(); + + /** + * Returns an array of variable names for this asset. + * + * @return array + */ + function getVars(); + + /** + * Sets the values for the asset's variables. + * + * @param array $values + */ + function setValues(array $values); + + /** + * Returns the current values for this asset. + * + * @return array an array of strings + */ + function getValues(); +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetReference.php b/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetReference.php new file mode 100644 index 0000000..488877a --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetReference.php @@ -0,0 +1,134 @@ + + */ +class AssetReference implements AssetInterface +{ + private $am; + private $name; + private $filters = array(); + + public function __construct(AssetManager $am, $name) + { + $this->am = $am; + $this->name = $name; + } + + public function ensureFilter(FilterInterface $filter) + { + $this->filters[] = $filter; + } + + public function getFilters() + { + $this->flushFilters(); + + return $this->callAsset(__FUNCTION__); + } + + public function clearFilters() + { + $this->filters = array(); + $this->callAsset(__FUNCTION__); + } + + public function load(FilterInterface $additionalFilter = null) + { + $this->flushFilters(); + + return $this->callAsset(__FUNCTION__, array($additionalFilter)); + } + + public function dump(FilterInterface $additionalFilter = null) + { + $this->flushFilters(); + + return $this->callAsset(__FUNCTION__, array($additionalFilter)); + } + + public function getContent() + { + return $this->callAsset(__FUNCTION__); + } + + public function setContent($content) + { + $this->callAsset(__FUNCTION__, array($content)); + } + + public function getSourceRoot() + { + return $this->callAsset(__FUNCTION__); + } + + public function getSourcePath() + { + return $this->callAsset(__FUNCTION__); + } + + public function getTargetPath() + { + return $this->callAsset(__FUNCTION__); + } + + public function setTargetPath($targetPath) + { + $this->callAsset(__FUNCTION__, array($targetPath)); + } + + public function getLastModified() + { + return $this->callAsset(__FUNCTION__); + } + + public function getVars() + { + return $this->callAsset(__FUNCTION__); + } + + public function getValues() + { + return $this->callAsset(__FUNCTION__); + } + + public function setValues(array $values) + { + $this->callAsset(__FUNCTION__, array($values)); + } + + // private + + private function callAsset($method, $arguments = array()) + { + $asset = $this->am->get($this->name); + + return call_user_func_array(array($asset, $method), $arguments); + } + + private function flushFilters() + { + $asset = $this->am->get($this->name); + + while ($filter = array_shift($this->filters)) { + $asset->ensureFilter($filter); + } + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Asset/BaseAsset.php b/vendor/kriswallsmith/assetic/src/Assetic/Asset/BaseAsset.php new file mode 100644 index 0000000..1ce93ae --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Asset/BaseAsset.php @@ -0,0 +1,169 @@ + + */ +abstract class BaseAsset implements AssetInterface +{ + private $filters; + private $sourceRoot; + private $sourcePath; + private $targetPath; + private $content; + private $loaded; + private $vars; + private $values; + + /** + * Constructor. + * + * @param array $filters Filters for the asset + */ + public function __construct($filters = array(), $sourceRoot = null, $sourcePath = null, array $vars = array()) + { + $this->filters = new FilterCollection($filters); + $this->sourceRoot = $sourceRoot; + $this->sourcePath = $sourcePath; + $this->vars = $vars; + $this->values = array(); + $this->loaded = false; + } + + public function __clone() + { + $this->filters = clone $this->filters; + } + + public function ensureFilter(FilterInterface $filter) + { + $this->filters->ensure($filter); + } + + public function getFilters() + { + return $this->filters->all(); + } + + public function clearFilters() + { + $this->filters->clear(); + } + + /** + * Encapsulates asset loading logic. + * + * @param string $content The asset content + * @param FilterInterface $additionalFilter An additional filter + */ + protected function doLoad($content, FilterInterface $additionalFilter = null) + { + $filter = clone $this->filters; + if ($additionalFilter) { + $filter->ensure($additionalFilter); + } + + $asset = clone $this; + $asset->setContent($content); + + $filter->filterLoad($asset); + $this->content = $asset->getContent(); + + $this->loaded = true; + } + + public function dump(FilterInterface $additionalFilter = null) + { + if (!$this->loaded) { + $this->load(); + } + + $filter = clone $this->filters; + if ($additionalFilter) { + $filter->ensure($additionalFilter); + } + + $asset = clone $this; + $filter->filterDump($asset); + + return $asset->getContent(); + } + + public function getContent() + { + return $this->content; + } + + public function setContent($content) + { + $this->content = $content; + } + + public function getSourceRoot() + { + return $this->sourceRoot; + } + + public function getSourcePath() + { + return $this->sourcePath; + } + + public function getTargetPath() + { + return $this->targetPath; + } + + public function setTargetPath($targetPath) + { + if ($this->vars) { + foreach ($this->vars as $var) { + if (false === strpos($targetPath, $var)) { + throw new \RuntimeException(sprintf('The asset target path "%s" must contain the variable "{%s}".', $targetPath, $var)); + } + } + } + + $this->targetPath = $targetPath; + } + + public function getVars() + { + return $this->vars; + } + + public function setValues(array $values) + { + foreach ($values as $var => $v) { + if (!in_array($var, $this->vars, true)) { + throw new \InvalidArgumentException(sprintf('The asset with source path "%s" has no variable named "%s".', $this->sourcePath, $var)); + } + } + + $this->values = $values; + $this->loaded = false; + } + + public function getValues() + { + return $this->values; + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Asset/FileAsset.php b/vendor/kriswallsmith/assetic/src/Assetic/Asset/FileAsset.php new file mode 100644 index 0000000..0bf171c --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Asset/FileAsset.php @@ -0,0 +1,78 @@ + + */ +class FileAsset extends BaseAsset +{ + private $source; + + /** + * Constructor. + * + * @param string $source An absolute path + * @param array $filters An array of filters + * @param string $sourceRoot The source asset root directory + * @param string $sourcePath The source asset path + * + * @throws InvalidArgumentException If the supplied root doesn't match the source when guessing the path + */ + public function __construct($source, $filters = array(), $sourceRoot = null, $sourcePath = null, array $vars = array()) + { + if (null === $sourceRoot) { + $sourceRoot = dirname($source); + if (null === $sourcePath) { + $sourcePath = basename($source); + } + } elseif (null === $sourcePath) { + if (0 !== strpos($source, $sourceRoot)) { + throw new \InvalidArgumentException(sprintf('The source "%s" is not in the root directory "%s"', $source, $sourceRoot)); + } + + $sourcePath = substr($source, strlen($sourceRoot) + 1); + } + + $this->source = $source; + + parent::__construct($filters, $sourceRoot, $sourcePath, $vars); + } + + public function load(FilterInterface $additionalFilter = null) + { + $source = PathUtils::resolvePath($this->source, $this->getVars(), + $this->getValues()); + + if (!is_file($source)) { + throw new \RuntimeException(sprintf('The source file "%s" does not exist.', $source)); + } + + $this->doLoad(file_get_contents($source), $additionalFilter); + } + + public function getLastModified() + { + $source = PathUtils::resolvePath($this->source, $this->getVars(), + $this->getValues()); + + if (!is_file($source)) { + throw new \RuntimeException(sprintf('The source file "%s" does not exist.', $source)); + } + return filemtime($source); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Asset/GlobAsset.php b/vendor/kriswallsmith/assetic/src/Assetic/Asset/GlobAsset.php new file mode 100644 index 0000000..4f8559c --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Asset/GlobAsset.php @@ -0,0 +1,111 @@ + + */ +class GlobAsset extends AssetCollection +{ + private $globs; + private $initialized; + + /** + * Constructor. + * + * @param string|array $globs A single glob path or array of paths + * @param array $filters An array of filters + * @param string $root The root directory + */ + public function __construct($globs, $filters = array(), $root = null, array $vars = array()) + { + $this->globs = (array) $globs; + $this->initialized = false; + + parent::__construct(array(), $filters, $root, $vars); + } + + public function all() + { + if (!$this->initialized) { + $this->initialize(); + } + + return parent::all(); + } + + public function load(FilterInterface $additionalFilter = null) + { + if (!$this->initialized) { + $this->initialize(); + } + + parent::load($additionalFilter); + } + + public function dump(FilterInterface $additionalFilter = null) + { + if (!$this->initialized) { + $this->initialize(); + } + + return parent::dump($additionalFilter); + } + + public function getLastModified() + { + if (!$this->initialized) { + $this->initialize(); + } + + return parent::getLastModified(); + } + + public function getIterator() + { + if (!$this->initialized) { + $this->initialize(); + } + + return parent::getIterator(); + } + + public function setValues(array $values) + { + parent::setValues($values); + $this->initialized = false; + } + + /** + * Initializes the collection based on the glob(s) passed in. + */ + private function initialize() + { + foreach ($this->globs as $glob) { + $glob = PathUtils::resolvePath($glob, $this->getVars(), $this->getValues()); + + if (false !== $paths = glob($glob)) { + foreach ($paths as $path) { + $this->add(new FileAsset($path, array(), $this->getSourceRoot())); + } + } + } + + $this->initialized = true; + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Asset/HttpAsset.php b/vendor/kriswallsmith/assetic/src/Assetic/Asset/HttpAsset.php new file mode 100644 index 0000000..64f2437 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Asset/HttpAsset.php @@ -0,0 +1,79 @@ + + */ +class HttpAsset extends BaseAsset +{ + private $sourceUrl; + private $ignoreErrors; + + /** + * Constructor. + * + * @param string $sourceUrl The source URL + * @param array $filters An array of filters + * + * @throws InvalidArgumentException If the first argument is not an URL + */ + public function __construct($sourceUrl, $filters = array(), $ignoreErrors = false, array $vars = array()) + { + if (0 === strpos($sourceUrl, '//')) { + $sourceUrl = 'http:'.$sourceUrl; + } elseif (false === strpos($sourceUrl, '://')) { + throw new \InvalidArgumentException(sprintf('"%s" is not a valid URL.', $sourceUrl)); + } + + $this->sourceUrl = $sourceUrl; + $this->ignoreErrors = $ignoreErrors; + + list($scheme, $url) = explode('://', $sourceUrl, 2); + list($host, $path) = explode('/', $url, 2); + + parent::__construct($filters, $scheme.'://'.$host, $path, $vars); + } + + public function load(FilterInterface $additionalFilter = null) + { + if (false === $content = @file_get_contents(PathUtils::resolvePath( + $this->sourceUrl, $this->getVars(), $this->getValues()))) { + if ($this->ignoreErrors) { + return; + } else { + throw new \RuntimeException(sprintf('Unable to load asset from URL "%s"', $this->sourceUrl)); + } + } + + $this->doLoad($content, $additionalFilter); + } + + public function getLastModified() + { + if (false !== @file_get_contents($this->sourceUrl, false, stream_context_create(array('http' => array('method' => 'HEAD'))))) { + foreach ($http_response_header as $header) { + if (0 === stripos($header, 'Last-Modified: ')) { + list(, $mtime) = explode(':', $header, 2); + + return strtotime(trim($mtime)); + } + } + } + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionFilterIterator.php b/vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionFilterIterator.php new file mode 100644 index 0000000..f9ad79b --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionFilterIterator.php @@ -0,0 +1,84 @@ + + */ +class AssetCollectionFilterIterator extends \RecursiveFilterIterator +{ + private $visited; + private $sources; + + /** + * Constructor. + * + * @param AssetCollectionIterator $iterator The inner iterator + * @param array $visited An array of visited asset objects + * @param array $sources An array of visited source strings + */ + public function __construct(AssetCollectionIterator $iterator, array $visited = array(), array $sources = array()) + { + parent::__construct($iterator); + + $this->visited = $visited; + $this->sources = $sources; + } + + /** + * Determines whether the current asset is a duplicate. + * + * De-duplication is performed based on either strict equality or by + * matching sources. + * + * @return Boolean Returns true if we have not seen this asset yet + */ + public function accept() + { + $asset = $this->getInnerIterator()->current(true); + $duplicate = false; + + // check strict equality + if (in_array($asset, $this->visited, true)) { + $duplicate = true; + } else { + $this->visited[] = $asset; + } + + // check source + $sourceRoot = $asset->getSourceRoot(); + $sourcePath = $asset->getSourcePath(); + if ($sourceRoot && $sourcePath) { + $source = $sourceRoot.'/'.$sourcePath; + if (in_array($source, $this->sources)) { + $duplicate = true; + } else { + $this->sources[] = $source; + } + } + + return !$duplicate; + } + + /** + * Passes visited objects and source URLs to the child iterator. + */ + public function getChildren() + { + return new self($this->getInnerIterator()->getChildren(), $this->visited, $this->sources); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionIterator.php b/vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionIterator.php new file mode 100644 index 0000000..09330fe --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionIterator.php @@ -0,0 +1,109 @@ + + */ +class AssetCollectionIterator implements \RecursiveIterator +{ + private $assets; + private $filters; + private $output; + private $clones; + + public function __construct(AssetCollectionInterface $coll, \SplObjectStorage $clones) + { + $this->assets = $coll->all(); + $this->filters = $coll->getFilters(); + $this->output = $coll->getTargetPath(); + $this->clones = $clones; + + if (false === $pos = strpos($this->output, '.')) { + $this->output .= '_*'; + } else { + $this->output = substr($this->output, 0, $pos).'_*'.substr($this->output, $pos); + } + } + + /** + * Returns a copy of the current asset with filters and a target URL applied. + * + * @param Boolean $raw Returns the unmodified asset if true + */ + public function current($raw = false) + { + $asset = current($this->assets); + + if ($raw) { + return $asset; + } + + // clone once + if (!isset($this->clones[$asset])) { + $clone = $this->clones[$asset] = clone $asset; + + // generate a target path based on asset name + $name = sprintf('%s_%d', pathinfo($asset->getSourcePath(), PATHINFO_FILENAME) ?: 'part', $this->key() + 1); + $clone->setTargetPath(str_replace('*', $name, $this->output)); + } else { + $clone = $this->clones[$asset]; + } + + // cascade filters + foreach ($this->filters as $filter) { + $clone->ensureFilter($filter); + } + + return $clone; + } + + public function key() + { + return key($this->assets); + } + + public function next() + { + return next($this->assets); + } + + public function rewind() + { + return reset($this->assets); + } + + public function valid() + { + return false !== current($this->assets); + } + + public function hasChildren() + { + return current($this->assets) instanceof AssetCollectionInterface; + } + + /** + * @uses current() + */ + public function getChildren() + { + return new self($this->current(), $this->clones); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Asset/StringAsset.php b/vendor/kriswallsmith/assetic/src/Assetic/Asset/StringAsset.php new file mode 100644 index 0000000..6d6dc5f --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Asset/StringAsset.php @@ -0,0 +1,55 @@ + + */ +class StringAsset extends BaseAsset +{ + private $content; + private $lastModified; + + /** + * Constructor. + * + * @param string $content The content of the asset + * @param array $filters Filters for the asset + * @param string $sourceRoot The source asset root directory + * @param string $sourcePath The source asset path + */ + public function __construct($content, $filters = array(), $sourceRoot = null, $sourcePath = null) + { + $this->content = $content; + + parent::__construct($filters, $sourceRoot, $sourcePath); + } + + public function load(FilterInterface $additionalFilter = null) + { + $this->doLoad($this->content, $additionalFilter); + } + + public function setLastModified($lastModified) + { + $this->lastModified = $lastModified; + } + + public function getLastModified() + { + return $this->lastModified; + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/AssetManager.php b/vendor/kriswallsmith/assetic/src/Assetic/AssetManager.php new file mode 100644 index 0000000..230e4fc --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/AssetManager.php @@ -0,0 +1,79 @@ + + */ +class AssetManager +{ + private $assets = array(); + + /** + * Gets an asset by name. + * + * @param string $name The asset name + * + * @return AssetInterface The asset + * + * @throws InvalidArgumentException If there is no asset by that name + */ + public function get($name) + { + if (!isset($this->assets[$name])) { + throw new \InvalidArgumentException(sprintf('There is no "%s" asset.', $name)); + } + + return $this->assets[$name]; + } + + /** + * Checks if the current asset manager has a certain asset. + * + * @param string $name an asset name + * + * @return Boolean True if the asset has been set, false if not + */ + public function has($name) + { + return isset($this->assets[$name]); + } + + /** + * Registers an asset to the current asset manager. + * + * @param string $name The asset name + * @param AssetInterface $asset The asset + */ + public function set($name, AssetInterface $asset) + { + if (!ctype_alnum(str_replace('_', '', $name))) { + throw new \InvalidArgumentException(sprintf('The name "%s" is invalid.', $name)); + } + + $this->assets[$name] = $asset; + } + + /** + * Returns an array of asset names. + * + * @return array An array of asset names + */ + public function getNames() + { + return array_keys($this->assets); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/AssetWriter.php b/vendor/kriswallsmith/assetic/src/Assetic/AssetWriter.php new file mode 100644 index 0000000..75f1ae5 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/AssetWriter.php @@ -0,0 +1,107 @@ + + * @author Johannes M. Schmitt + */ +class AssetWriter +{ + private $dir; + private $varValues; + + /** + * Constructor. + * + * @param string $dir The base web directory + */ + public function __construct($dir, array $varValues = array()) + { + foreach ($varValues as $var => $values) { + foreach ($values as $value) { + if (!is_string($value)) { + throw new \InvalidArgumentException(sprintf('All variable values must be strings, but got %s for variable "%s".', json_encode($value), $var)); + } + } + } + + $this->dir = $dir; + $this->varValues = $varValues; + } + + public function writeManagerAssets(AssetManager $am) + { + foreach ($am->getNames() as $name) { + $this->writeAsset($am->get($name)); + } + } + + public function writeAsset(AssetInterface $asset) + { + foreach ($this->getCombinations($asset->getVars()) as $combination) { + $asset->setValues($combination); + + static::write($this->dir.'/'.PathUtils::resolvePath( + $asset->getTargetPath(), $asset->getVars(), $asset->getValues()), + $asset->dump()); + } + } + + private function getCombinations(array $vars) + { + if (!$vars) { + return array(array()); + } + + $combinations = array(); + $nbValues = array(); + foreach ($this->varValues as $var => $values) { + if (!in_array($var, $vars, true)) { + continue; + } + + $nbValues[$var] = count($values); + } + + for ($i=array_product($nbValues),$c=$i*2; $i<$c; $i++) { + $k = $i; + $combination = array(); + + foreach ($vars as $var) { + $combination[$var] = $this->varValues[$var][$k % $nbValues[$var]]; + $k = intval($k/$nbValues[$var]); + } + + $combinations[] = $combination; + } + + return $combinations; + } + + static protected function write($path, $contents) + { + if (!is_dir($dir = dirname($path)) && false === @mkdir($dir, 0777, true)) { + throw new \RuntimeException('Unable to create directory '.$dir); + } + + if (false === @file_put_contents($path, $contents)) { + throw new \RuntimeException('Unable to write file '.$path); + } + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Cache/ApcCache.php b/vendor/kriswallsmith/assetic/src/Assetic/Cache/ApcCache.php new file mode 100644 index 0000000..2285588 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Cache/ApcCache.php @@ -0,0 +1,66 @@ + + */ +class ApcCache implements CacheInterface +{ + public $ttl = 0; + + /** + * @see CacheInterface::has() + */ + public function has($key) + { + return apc_exists($key); + } + + /** + * @see CacheInterface::get() + */ + public function get($key) + { + $value = apc_fetch($key, $success); + + if (!$success) { + throw new \RuntimeException('There is no cached value for ' . $key); + } + + return $value; + } + + /** + * @see CacheInterface::set() + */ + public function set($key, $value) + { + $store = apc_store($key, $value, $this->ttl); + + if (!$store) { + throw new \RuntimeException('Unable to store "' . $key . '" for ' . $this->ttl . ' seconds.'); + } + + return $store; + } + + /** + * @see CacheInterface::remove() + */ + public function remove($key) + { + return apc_delete($key); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Cache/CacheInterface.php b/vendor/kriswallsmith/assetic/src/Assetic/Cache/CacheInterface.php new file mode 100644 index 0000000..8b9334d --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Cache/CacheInterface.php @@ -0,0 +1,53 @@ + + */ +interface CacheInterface +{ + /** + * Checks if the cache has a value for a key. + * + * @param string $key A unique key + * + * @return Boolean Whether the cache has a value for this key + */ + function has($key); + + /** + * Returns the value for a key. + * + * @param string $key A unique key + * + * @return string|null The value in the cache + */ + function get($key); + + /** + * Sets a value in the cache. + * + * @param string $key A unique key + * @param string $value The value to cache + */ + function set($key, $value); + + /** + * Removes a value from the cache. + * + * @param string $key A unique key + */ + function remove($key); +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Cache/ConfigCache.php b/vendor/kriswallsmith/assetic/src/Assetic/Cache/ConfigCache.php new file mode 100644 index 0000000..de60c9e --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Cache/ConfigCache.php @@ -0,0 +1,123 @@ + + */ +class ConfigCache +{ + private $dir; + + /** + * Construct. + * + * @param string $dir The cache directory + */ + public function __construct($dir) + { + $this->dir = $dir; + } + + /** + * Checks of the cache has a file. + * + * @param string $resource A cache key + * + * @return Boolean True if a file exists + */ + public function has($resource) + { + return file_exists($this->getSourcePath($resource)); + } + + /** + * Writes a value to a file. + * + * @param string $resource A cache key + * @param mixed $value A value to cache + */ + public function set($resource, $value) + { + $path = $this->getSourcePath($resource); + + if (!is_dir($dir = dirname($path)) && false === @mkdir($dir, 0777, true)) { + // @codeCoverageIgnoreStart + throw new \RuntimeException('Unable to create directory '.$dir); + // @codeCoverageIgnoreEnd + } + + if (false === @file_put_contents($path, sprintf("getSourcePath($resource); + + if (!file_exists($path)) { + throw new \RuntimeException('There is no cached value for '.$resource); + } + + return include $path; + } + + /** + * Returns a timestamp for when the cache was created. + * + * @param string $resource A cache key + * + * @return integer A UNIX timestamp + */ + public function getTimestamp($resource) + { + $path = $this->getSourcePath($resource); + + if (!file_exists($path)) { + throw new \RuntimeException('There is no cached value for '.$resource); + } + + if (false === $mtime = @filemtime($path)) { + // @codeCoverageIgnoreStart + throw new \RuntimeException('Unable to determine file mtime for '.$path); + // @codeCoverageIgnoreEnd + } + + return $mtime; + } + + /** + * Returns the path where the file corresponding to the supplied cache key can be included from. + * + * @param string $resource A cache key + * + * @return string A file path + */ + private function getSourcePath($resource) + { + $key = md5($resource); + + return $this->dir.'/'.$key[0].'/'.$key.'.php'; + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Cache/ExpiringCache.php b/vendor/kriswallsmith/assetic/src/Assetic/Cache/ExpiringCache.php new file mode 100644 index 0000000..9e95b6d --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Cache/ExpiringCache.php @@ -0,0 +1,60 @@ + + */ +class ExpiringCache implements CacheInterface +{ + private $cache; + private $lifetime; + + public function __construct(CacheInterface $cache, $lifetime) + { + $this->cache = $cache; + $this->lifetime = $lifetime; + } + + public function has($key) + { + if ($this->cache->has($key)) { + if (time() < $this->cache->get($key.'.expires')) { + return true; + } + + $this->cache->remove($key.'.expires'); + $this->cache->remove($key); + } + + return false; + } + + public function get($key) + { + return $this->cache->get($key); + } + + public function set($key, $value) + { + $this->cache->set($key.'.expires', time() + $this->lifetime); + $this->cache->set($key, $value); + } + + public function remove($key) + { + $this->cache->remove($key.'.expires'); + $this->cache->remove($key); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Cache/FilesystemCache.php b/vendor/kriswallsmith/assetic/src/Assetic/Cache/FilesystemCache.php new file mode 100644 index 0000000..45cfbdb --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Cache/FilesystemCache.php @@ -0,0 +1,65 @@ + + */ +class FilesystemCache implements CacheInterface +{ + private $dir; + + public function __construct($dir) + { + $this->dir = $dir; + } + + public function has($key) + { + return file_exists($this->dir.'/'.$key); + } + + public function get($key) + { + $path = $this->dir.'/'.$key; + + if (!file_exists($path)) { + throw new \RuntimeException('There is no cached value for '.$key); + } + + return file_get_contents($path); + } + + public function set($key, $value) + { + if (!is_dir($this->dir) && false === @mkdir($this->dir, 0777, true)) { + throw new \RuntimeException('Unable to create directory '.$this->dir); + } + + $path = $this->dir.'/'.$key; + + if (false === @file_put_contents($path, $value)) { + throw new \RuntimeException('Unable to write file '.$path); + } + } + + public function remove($key) + { + $path = $this->dir.'/'.$key; + + if (file_exists($path) && false === @unlink($path)) { + throw new \RuntimeException('Unable to remove file '.$path); + } + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Exception/Exception.php b/vendor/kriswallsmith/assetic/src/Assetic/Exception/Exception.php new file mode 100644 index 0000000..1d1e928 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Exception/Exception.php @@ -0,0 +1,21 @@ + + */ +interface Exception +{ +} \ No newline at end of file diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Exception/FilterException.php b/vendor/kriswallsmith/assetic/src/Assetic/Exception/FilterException.php new file mode 100644 index 0000000..82203de --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Exception/FilterException.php @@ -0,0 +1,73 @@ + + */ +class FilterException extends \RuntimeException implements Exception +{ + private $originalMessage; + private $input; + + public static function fromProcess(Process $proc) + { + $message = sprintf("An error occurred while running:\n%s", $proc->getCommandLine()); + + $errorOutput = $proc->getErrorOutput(); + if (!empty($errorOutput)) { + $message .= "\n\nError Output:\n".str_replace("\r", '', $errorOutput); + } + + $output = $proc->getOutput(); + if (!empty($output)) { + $message .= "\n\nOutput:\n".str_replace("\r", '', $output); + } + + return new self($message); + } + + public function __construct($message, $code = 0, \Exception $previous = null) + { + parent::__construct($message, $code, $previous); + + $this->originalMessage = $message; + } + + public function setInput($input) + { + $this->input = $input; + $this->updateMessage(); + + return $this; + } + + public function getInput() + { + return $this->input; + } + + private function updateMessage() + { + $message = $this->originalMessage; + + if (!empty($this->input)) { + $message .= "\n\nInput:\n".$this->input; + } + + $this->message = $message; + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticExtension.php b/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticExtension.php new file mode 100644 index 0000000..6d91443 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticExtension.php @@ -0,0 +1,76 @@ +factory = $factory; + $this->functions = array(); + $this->valueSupplier = $valueSupplier; + + foreach ($functions as $function => $options) { + if (is_integer($function) && is_string($options)) { + $this->functions[$options] = array('filter' => $options); + } else { + $this->functions[$function] = $options + array('filter' => $function); + } + } + } + + public function getTokenParsers() + { + return array( + new AsseticTokenParser($this->factory, 'javascripts', 'js/*.js'), + new AsseticTokenParser($this->factory, 'stylesheets', 'css/*.css'), + new AsseticTokenParser($this->factory, 'image', 'images/*', true), + ); + } + + public function getFunctions() + { + $functions = array(); + foreach ($this->functions as $function => $filter) { + $functions[$function] = new AsseticFilterFunction($function); + } + + return $functions; + } + + public function getGlobals() + { + return array( + 'assetic' => array( + 'debug' => $this->factory->isDebug(), + 'vars' => null !== $this->valueSupplier ? $this->valueSupplier->getValues() : array(), + ), + ); + } + + public function getFilterInvoker($function) + { + return new AsseticFilterInvoker($this->factory, $this->functions[$function]); + } + + public function getName() + { + return 'assetic'; + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterFunction.php b/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterFunction.php new file mode 100644 index 0000000..c5c79a8 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterFunction.php @@ -0,0 +1,29 @@ +filter = $filter; + + parent::__construct($options); + } + + public function compile() + { + return sprintf('$this->env->getExtension(\'assetic\')->getFilterInvoker(\'%s\')->invoke', $this->filter); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterInvoker.php b/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterInvoker.php new file mode 100644 index 0000000..78accd5 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterInvoker.php @@ -0,0 +1,61 @@ + + */ +class AsseticFilterInvoker +{ + private $factory; + private $filters; + private $options; + + public function __construct($factory, $filter) + { + $this->factory = $factory; + + if (is_array($filter) && isset($filter['filter'])) { + $this->filters = (array) $filter['filter']; + $this->options = isset($filter['options']) ? (array) $filter['options'] : array(); + } else { + $this->filters = (array) $filter; + $this->options = array(); + } + } + + public function getFactory() + { + return $this->factory; + } + + public function getFilters() + { + return $this->filters; + } + + public function getOptions() + { + return $this->options; + } + + public function invoke($input, array $options = array()) + { + $asset = $this->factory->createAsset($input, $this->filters, $options + $this->options); + + return $asset->getTargetPath(); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticNode.php b/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticNode.php new file mode 100644 index 0000000..c60daee --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticNode.php @@ -0,0 +1,166 @@ + $body); + + $attributes = array_replace( + array('debug' => null, 'combine' => null, 'var_name' => 'asset_url'), + $attributes, + array('asset' => $asset, 'inputs' => $inputs, 'filters' => $filters, 'name' => $name) + ); + + parent::__construct($nodes, $attributes, $lineno, $tag); + } + + public function compile(\Twig_Compiler $compiler) + { + $compiler->addDebugInfo($this); + + $combine = $this->getAttribute('combine'); + $debug = $this->getAttribute('debug'); + + if (null === $combine && null !== $debug) { + $combine = !$debug; + } + + if (null === $combine) { + $compiler + ->write("if (isset(\$context['assetic']['debug']) && \$context['assetic']['debug']) {\n") + ->indent() + ; + + $this->compileDebug($compiler); + + $compiler + ->outdent() + ->write("} else {\n") + ->indent() + ; + + $this->compileAsset($compiler, $this->getAttribute('asset'), $this->getAttribute('name')); + + $compiler + ->outdent() + ->write("}\n") + ; + } elseif ($combine) { + $this->compileAsset($compiler, $this->getAttribute('asset'), $this->getAttribute('name')); + } else { + $this->compileDebug($compiler); + } + + $compiler + ->write('unset($context[') + ->repr($this->getAttribute('var_name')) + ->raw("]);\n") + ; + } + + protected function compileDebug(\Twig_Compiler $compiler) + { + $i = 0; + foreach ($this->getAttribute('asset') as $leaf) { + $leafName = $this->getAttribute('name').'_'.$i++; + $this->compileAsset($compiler, $leaf, $leafName); + } + } + + protected function compileAsset(\Twig_Compiler $compiler, AssetInterface $asset, $name) + { + if ($vars = $asset->getVars()) { + $compiler->write("// check variable conditions\n"); + + foreach ($vars as $var) { + $compiler + ->write("if (!isset(\$context['assetic']['vars']['$var'])) {\n") + ->indent() + ->write("throw new \RuntimeException(sprintf('The asset \"".$name."\" expected variable \"".$var."\" to be set, but got only these vars: %s. Did you set-up a value supplier?', isset(\$context['assetic']['vars']) && \$context['assetic']['vars'] ? implode(', ', \$context['assetic']['vars']) : '# none #'));\n") + ->outdent() + ->write("}\n") + ; + } + + $compiler->raw("\n"); + } + + $compiler + ->write("// asset \"$name\"\n") + ->write('$context[') + ->repr($this->getAttribute('var_name')) + ->raw('] = ') + ; + + $this->compileAssetUrl($compiler, $asset, $name); + + $compiler + ->raw(";\n") + ->subcompile($this->getNode('body')) + ; + } + + protected function compileAssetUrl(\Twig_Compiler $compiler, AssetInterface $asset, $name) + { + if (!$vars = $asset->getVars()) { + $compiler->repr($asset->getTargetPath()); + + return; + } + + $compiler + ->raw("strtr(") + ->string($asset->getTargetPath()) + ->raw(", array("); + ; + + $first = true; + foreach ($vars as $var) { + if (!$first) { + $compiler->raw(", "); + } + $first = false; + + $compiler + ->string("{".$var."}") + ->raw(" => \$context['assetic']['vars']['$var']") + ; + } + + $compiler + ->raw("))") + ; + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticTokenParser.php b/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticTokenParser.php new file mode 100644 index 0000000..c63fd06 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticTokenParser.php @@ -0,0 +1,150 @@ +factory = $factory; + $this->tag = $tag; + $this->output = $output; + $this->single = $single; + $this->extensions = $extensions; + } + + public function parse(\Twig_Token $token) + { + $inputs = array(); + $filters = array(); + $name = null; + $attributes = array( + 'output' => $this->output, + 'var_name' => 'asset_url', + 'vars' => array(), + ); + + $stream = $this->parser->getStream(); + while (!$stream->test(\Twig_Token::BLOCK_END_TYPE)) { + if ($stream->test(\Twig_Token::STRING_TYPE)) { + // '@jquery', 'js/src/core/*', 'js/src/extra.js' + $inputs[] = $stream->next()->getValue(); + } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'filter')) { + // filter='yui_js' + $stream->next(); + $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); + $filters = array_merge($filters, array_filter(array_map('trim', explode(',', $stream->expect(\Twig_Token::STRING_TYPE)->getValue())))); + } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'output')) { + // output='js/packed/*.js' OR output='js/core.js' + $stream->next(); + $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); + $attributes['output'] = $stream->expect(\Twig_Token::STRING_TYPE)->getValue(); + } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'name')) { + // name='core_js' + $stream->next(); + $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); + $name = $stream->expect(\Twig_Token::STRING_TYPE)->getValue(); + } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'as')) { + // as='the_url' + $stream->next(); + $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); + $attributes['var_name'] = $stream->expect(\Twig_Token::STRING_TYPE)->getValue(); + } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'debug')) { + // debug=true + $stream->next(); + $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); + $attributes['debug'] = 'true' == $stream->expect(\Twig_Token::NAME_TYPE, array('true', 'false'))->getValue(); + } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'combine')) { + // combine=true + $stream->next(); + $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); + $attributes['combine'] = 'true' == $stream->expect(\Twig_Token::NAME_TYPE, array('true', 'false'))->getValue(); + } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'vars')) { + // vars=['locale','browser'] + $stream->next(); + $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); + $stream->expect(\Twig_Token::PUNCTUATION_TYPE, '['); + + while ($stream->test(\Twig_Token::STRING_TYPE)) { + $attributes['vars'][] = $stream->expect(\Twig_Token::STRING_TYPE)->getValue(); + + if (!$stream->test(\Twig_Token::PUNCTUATION_TYPE, ',')) { + break; + } + + $stream->next(); + } + + $stream->expect(\Twig_Token::PUNCTUATION_TYPE, ']'); + } elseif ($stream->test(\Twig_Token::NAME_TYPE, $this->extensions)) { + // an arbitrary configured attribute + $key = $stream->next()->getValue(); + $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); + $attributes[$key] = $stream->expect(\Twig_Token::STRING_TYPE)->getValue(); + } else { + $token = $stream->getCurrent(); + throw new \Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s"', \Twig_Token::typeToEnglish($token->getType(), $token->getLine()), $token->getValue()), $token->getLine()); + } + } + + $stream->expect(\Twig_Token::BLOCK_END_TYPE); + + $endtag = 'end'.$this->getTag(); + $test = function(\Twig_Token $token) use($endtag) { return $token->test($endtag); }; + $body = $this->parser->subparse($test, true); + + $stream->expect(\Twig_Token::BLOCK_END_TYPE); + + if ($this->single && 1 < count($inputs)) { + $inputs = array_slice($inputs, -1); + } + + if (!$name) { + $name = $this->factory->generateAssetName($inputs, $filters, $attributes); + } + + $asset = $this->factory->createAsset($inputs, $filters, $attributes + array('name' => $name)); + + return $this->createNode($asset, $body, $inputs, $filters, $name, $attributes, $token->getLine(), $this->getTag()); + } + + public function getTag() + { + return $this->tag; + } + + protected function createNode(AssetInterface $asset, \Twig_NodeInterface $body, array $inputs, array $filters, $name, array $attributes = array(), $lineno = 0, $tag = null) + { + return new AsseticNode($asset, $body, $inputs, $filters, $name, $attributes, $lineno, $tag); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigFormulaLoader.php b/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigFormulaLoader.php new file mode 100644 index 0000000..6edd25b --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigFormulaLoader.php @@ -0,0 +1,97 @@ + + */ +class TwigFormulaLoader implements FormulaLoaderInterface +{ + private $twig; + + public function __construct(\Twig_Environment $twig) + { + $this->twig = $twig; + } + + public function load(ResourceInterface $resource) + { + try { + $tokens = $this->twig->tokenize($resource->getContent(), (string) $resource); + $nodes = $this->twig->parse($tokens); + } catch (\Exception $e) { + return array(); + } + + return $this->loadNode($nodes); + } + + /** + * Loads assets from the supplied node. + * + * @return array An array of asset formulae indexed by name + */ + private function loadNode(\Twig_Node $node) + { + $formulae = array(); + + if ($node instanceof AsseticNode) { + $formulae[$node->getAttribute('name')] = array( + $node->getAttribute('inputs'), + $node->getAttribute('filters'), + array( + 'output' => $node->getAttribute('asset')->getTargetPath(), + 'name' => $node->getAttribute('name'), + 'debug' => $node->getAttribute('debug'), + 'combine' => $node->getAttribute('combine'), + 'vars' => $node->getAttribute('vars'), + ), + ); + } elseif ($node instanceof \Twig_Node_Expression_Function) { + $name = version_compare(\Twig_Environment::VERSION, '1.2.0-DEV', '<') + ? $node->getNode('name')->getAttribute('name') + : $node->getAttribute('name'); + + if ($this->twig->getFunction($name) instanceof AsseticFilterFunction) { + $arguments = array(); + foreach ($node->getNode('arguments') as $argument) { + $arguments[] = eval('return '.$this->twig->compile($argument).';'); + } + + $invoker = $this->twig->getExtension('assetic')->getFilterInvoker($name); + + $inputs = isset($arguments[0]) ? (array) $arguments[0] : array(); + $filters = $invoker->getFilters(); + $options = array_replace($invoker->getOptions(), isset($arguments[1]) ? $arguments[1] : array()); + + if (!isset($options['name'])) { + $options['name'] = $invoker->getFactory()->generateAssetName($inputs, $filters, $options); + } + + $formulae[$options['name']] = array($inputs, $filters, $options); + } + } + + foreach ($node as $child) { + if ($child instanceof \Twig_Node) { + $formulae += $this->loadNode($child); + } + } + + return $formulae; + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigResource.php b/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigResource.php new file mode 100644 index 0000000..58d4b45 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigResource.php @@ -0,0 +1,54 @@ + + */ +class TwigResource implements ResourceInterface +{ + private $loader; + private $name; + + public function __construct(\Twig_LoaderInterface $loader, $name) + { + $this->loader = $loader; + $this->name = $name; + } + + public function getContent() + { + try { + return $this->loader->getSource($this->name); + } catch (\Twig_Error_Loader $e) { + return ''; + } + } + + public function isFresh($timestamp) + { + try { + return $this->loader->isFresh($this->name, $timestamp); + } catch (\Twig_Error_Loader $e) { + return false; + } + } + + public function __toString() + { + return $this->name; + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Factory/AssetFactory.php b/vendor/kriswallsmith/assetic/src/Assetic/Factory/AssetFactory.php new file mode 100644 index 0000000..e946d86 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Factory/AssetFactory.php @@ -0,0 +1,386 @@ + + */ +class AssetFactory +{ + private $root; + private $debug; + private $output; + private $workers; + private $am; + private $fm; + + /** + * Constructor. + * + * @param string $root The default root directory + * @param string $output The default output string + * @param Boolean $debug Filters prefixed with a "?" will be omitted in debug mode + */ + public function __construct($root, $debug = false) + { + $this->root = rtrim($root, '/'); + $this->debug = $debug; + $this->output = 'assetic/*'; + $this->workers = array(); + } + + /** + * Sets debug mode for the current factory. + * + * @param Boolean $debug Debug mode + */ + public function setDebug($debug) + { + $this->debug = $debug; + } + + /** + * Checks if the factory is in debug mode. + * + * @return Boolean Debug mode + */ + public function isDebug() + { + return $this->debug; + } + + /** + * Sets the default output string. + * + * @param string $output The default output string + */ + public function setDefaultOutput($output) + { + $this->output = $output; + } + + /** + * Adds a factory worker. + * + * @param WorkerInterface $worker A worker + */ + public function addWorker(WorkerInterface $worker) + { + $this->workers[] = $worker; + } + + /** + * Returns the current asset manager. + * + * @return AssetManager|null The asset manager + */ + public function getAssetManager() + { + return $this->am; + } + + /** + * Sets the asset manager to use when creating asset references. + * + * @param AssetManager $am The asset manager + */ + public function setAssetManager(AssetManager $am) + { + $this->am = $am; + } + + /** + * Returns the current filter manager. + * + * @return FilterManager|null The filter manager + */ + public function getFilterManager() + { + return $this->fm; + } + + /** + * Sets the filter manager to use when adding filters. + * + * @param FilterManager $fm The filter manager + */ + public function setFilterManager(FilterManager $fm) + { + $this->fm = $fm; + } + + /** + * Creates a new asset. + * + * Prefixing a filter name with a question mark will cause it to be + * omitted when the factory is in debug mode. + * + * Available options: + * + * * output: An output string + * * name: An asset name for interpolation in output patterns + * * debug: Forces debug mode on or off for this asset + * * root: An array or string of more root directories + * + * @param array|string $inputs An array of input strings + * @param array|string $filters An array of filter names + * @param array $options An array of options + * + * @return AssetCollection An asset collection + */ + public function createAsset($inputs = array(), $filters = array(), array $options = array()) + { + if (!is_array($inputs)) { + $inputs = array($inputs); + } + + if (!is_array($filters)) { + $filters = array($filters); + } + + if (!isset($options['output'])) { + $options['output'] = $this->output; + } + + if (!isset($options['vars'])) { + $options['vars'] = array(); + } + + if (!isset($options['debug'])) { + $options['debug'] = $this->debug; + } + + if (!isset($options['root'])) { + $options['root'] = array($this->root); + } else { + if (!is_array($options['root'])) { + $options['root'] = array($options['root']); + } + + $options['root'][] = $this->root; + } + + if (!isset($options['name'])) { + $options['name'] = $this->generateAssetName($inputs, $filters, $options); + } + + $asset = $this->createAssetCollection(array(), $options); + $extensions = array(); + + // inner assets + foreach ($inputs as $input) { + if (is_array($input)) { + // nested formula + $asset->add(call_user_func_array(array($this, 'createAsset'), $input)); + } else { + $asset->add($this->parseInput($input, $options)); + $extensions[pathinfo($input, PATHINFO_EXTENSION)] = true; + } + } + + // filters + foreach ($filters as $filter) { + if ('?' != $filter[0]) { + $asset->ensureFilter($this->getFilter($filter)); + } elseif (!$options['debug']) { + $asset->ensureFilter($this->getFilter(substr($filter, 1))); + } + } + + // append variables + if (!empty($options['vars'])) { + $toAdd = array(); + foreach ($options['vars'] as $var) { + if (false !== strpos($options['output'], '{'.$var.'}')) { + continue; + } + + $toAdd[] = '{'.$var.'}'; + } + + if ($toAdd) { + $options['output'] = str_replace('*', '*.'.implode('.', $toAdd), $options['output']); + } + } + + // append consensus extension if missing + if (1 == count($extensions) && !pathinfo($options['output'], PATHINFO_EXTENSION) && $extension = key($extensions)) { + $options['output'] .= '.'.$extension; + } + + // output --> target url + $asset->setTargetPath(str_replace('*', $options['name'], $options['output'])); + + // apply workers and return + return $this->applyWorkers($asset); + } + + public function generateAssetName($inputs, $filters, $options = array()) + { + foreach (array_diff(array_keys($options), array('output', 'debug', 'root')) as $key) { + unset($options[$key]); + } + + ksort($options); + + return substr(sha1(serialize($inputs).serialize($filters).serialize($options)), 0, 7); + } + + /** + * Parses an input string string into an asset. + * + * The input string can be one of the following: + * + * * A reference: If the string starts with an "at" sign it will be interpreted as a reference to an asset in the asset manager + * * An absolute URL: If the string contains "://" or starts with "//" it will be interpreted as an HTTP asset + * * A glob: If the string contains a "*" it will be interpreted as a glob + * * A path: Otherwise the string is interpreted as a filesystem path + * + * Both globs and paths will be absolutized using the current root directory. + * + * @param string $input An input string + * @param array $options An array of options + * + * @return AssetInterface An asset + */ + protected function parseInput($input, array $options = array()) + { + if ('@' == $input[0]) { + return $this->createAssetReference(substr($input, 1)); + } + + if (false !== strpos($input, '://') || 0 === strpos($input, '//')) { + return $this->createHttpAsset($input, $options['vars']); + } + + if (self::isAbsolutePath($input)) { + if ($root = self::findRootDir($input, $options['root'])) { + $path = ltrim(substr($input, strlen($root)), '/'); + } else { + $path = null; + } + } else { + $root = $this->root; + $path = $input; + $input = $this->root.'/'.$path; + } + if (false !== strpos($input, '*')) { + return $this->createGlobAsset($input, $root, $options['vars']); + } else { + return $this->createFileAsset($input, $root, $path, $options['vars']); + } + } + + protected function createAssetCollection(array $assets = array(), array $options = array()) + { + return new AssetCollection($assets, array(), null, isset($options['vars']) ? $options['vars'] : array()); + } + + protected function createAssetReference($name) + { + if (!$this->am) { + throw new \LogicException('There is no asset manager.'); + } + + return new AssetReference($this->am, $name); + } + + protected function createHttpAsset($sourceUrl, $vars) + { + return new HttpAsset($sourceUrl, array(), false, $vars); + } + + protected function createGlobAsset($glob, $root = null, $vars) + { + return new GlobAsset($glob, array(), $root, $vars); + } + + protected function createFileAsset($source, $root = null, $path = null, $vars) + { + return new FileAsset($source, array(), $root, $path, $vars); + } + + protected function getFilter($name) + { + if (!$this->fm) { + throw new \LogicException('There is no filter manager.'); + } + + return $this->fm->get($name); + } + + /** + * Filters an asset collection through the factory workers. + * + * Each leaf asset will be processed first, followed by the asset + * collection itself. + * + * @param AssetCollectionInterface $asset An asset collection + */ + private function applyWorkers(AssetCollectionInterface $asset) + { + foreach ($asset as $leaf) { + foreach ($this->workers as $worker) { + $retval = $worker->process($leaf); + + if ($retval instanceof AssetInterface && $leaf !== $retval) { + $asset->replaceLeaf($leaf, $retval); + } + } + } + + foreach ($this->workers as $worker) { + $retval = $worker->process($asset); + + if ($retval instanceof AssetInterface) { + $asset = $retval; + } + } + + return $asset instanceof AssetCollectionInterface ? $asset : $this->createAssetCollection(array($asset)); + } + + static private function isAbsolutePath($path) + { + return '/' == $path[0] || '\\' == $path[0] || (3 < strlen($path) && ctype_alpha($path[0]) && $path[1] == ':' && ('\\' == $path[2] || '/' == $path[2])); + } + + /** + * Loops through the root directories and returns the first match. + * + * @param string $path An absolute path + * @param array $roots An array of root directories + * + * @return string|null The matching root directory, if found + */ + static private function findRootDir($path, array $roots) + { + foreach ($roots as $root) { + if (0 === strpos($path, $root)) { + return $root; + } + } + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Factory/LazyAssetManager.php b/vendor/kriswallsmith/assetic/src/Assetic/Factory/LazyAssetManager.php new file mode 100644 index 0000000..9a5fa13 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Factory/LazyAssetManager.php @@ -0,0 +1,204 @@ + + */ +class LazyAssetManager extends AssetManager +{ + private $factory; + private $loaders; + private $resources; + private $formulae; + private $loaded; + private $loading; + + /** + * Constructor. + * + * @param AssetFactory $factory The asset factory + * @param array $loaders An array of loaders indexed by alias + */ + public function __construct(AssetFactory $factory, $loaders = array()) + { + $this->factory = $factory; + $this->loaders = array(); + $this->resources = array(); + $this->formulae = array(); + $this->loaded = false; + $this->loading = false; + + foreach ($loaders as $alias => $loader) { + $this->setLoader($alias, $loader); + } + } + + /** + * Adds a loader to the asset manager. + * + * @param string $alias An alias for the loader + * @param FormulaLoaderInterface $loader A loader + */ + public function setLoader($alias, FormulaLoaderInterface $loader) + { + $this->loaders[$alias] = $loader; + $this->loaded = false; + } + + /** + * Adds a resource to the asset manager. + * + * @param ResourceInterface $resource A resource + * @param string $loader The loader alias for this resource + */ + public function addResource(ResourceInterface $resource, $loader) + { + $this->resources[$loader][] = $resource; + $this->loaded = false; + } + + /** + * Returns an array of resources. + * + * @return array An array of resources + */ + public function getResources() + { + $resources = array(); + foreach ($this->resources as $r) { + $resources = array_merge($resources, $r); + } + + return $resources; + } + + /** + * Checks for an asset formula. + * + * @param string $name An asset name + * + * @return Boolean If there is a formula + */ + public function hasFormula($name) + { + if (!$this->loaded) { + $this->load(); + } + + return isset($this->formulae[$name]); + } + + /** + * Returns an asset's formula. + * + * @param string $name An asset name + * + * @return array The formula + * + * @throws InvalidArgumentException If there is no formula by that name + */ + public function getFormula($name) + { + if (!$this->loaded) { + $this->load(); + } + + if (!isset($this->formulae[$name])) { + throw new \InvalidArgumentException(sprintf('There is no "%s" formula.', $name)); + } + + return $this->formulae[$name]; + } + + /** + * Sets a formula on the asset manager. + * + * @param string $name An asset name + * @param array $formula A formula + */ + public function setFormula($name, array $formula) + { + $this->formulae[$name] = $formula; + } + + /** + * Loads formulae from resources. + * + * @throws LogicException If a resource has been added to an invalid loader + */ + public function load() + { + if ($this->loading) { + return; + } + + if ($diff = array_diff(array_keys($this->resources), array_keys($this->loaders))) { + throw new \LogicException('The following loader(s) are not registered: '.implode(', ', $diff)); + } + + $this->loading = true; + + foreach ($this->resources as $loader => $resources) { + foreach ($resources as $resource) { + $this->formulae = array_replace($this->formulae, $this->loaders[$loader]->load($resource)); + } + } + + $this->loaded = true; + $this->loading = false; + } + + public function get($name) + { + if (!$this->loaded) { + $this->load(); + } + + if (!parent::has($name) && isset($this->formulae[$name])) { + list($inputs, $filters, $options) = $this->formulae[$name]; + $options['name'] = $name; + parent::set($name, $this->factory->createAsset($inputs, $filters, $options)); + } + + return parent::get($name); + } + + public function has($name) + { + if (!$this->loaded) { + $this->load(); + } + + return isset($this->formulae[$name]) || parent::has($name); + } + + public function getNames() + { + if (!$this->loaded) { + $this->load(); + } + + return array_unique(array_merge(parent::getNames(), array_keys($this->formulae))); + } + + public function isDebug() + { + return $this->factory->isDebug(); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/BasePhpFormulaLoader.php b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/BasePhpFormulaLoader.php new file mode 100644 index 0000000..a205a03 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/BasePhpFormulaLoader.php @@ -0,0 +1,159 @@ + + */ +abstract class BasePhpFormulaLoader implements FormulaLoaderInterface +{ + protected $factory; + protected $prototypes; + + public function __construct(AssetFactory $factory) + { + $this->factory = $factory; + $this->prototypes = array(); + + foreach ($this->registerPrototypes() as $prototype => $options) { + $this->addPrototype($prototype, $options); + } + } + + public function addPrototype($prototype, array $options = array()) + { + $tokens = token_get_all('prototypes[$prototype] = array($tokens, $options); + } + + public function load(ResourceInterface $resource) + { + if (!$nbProtos = count($this->prototypes)) { + throw new \LogicException('There are no prototypes registered.'); + } + + $buffers = array_fill(0, $nbProtos, ''); + $bufferLevels = array_fill(0, $nbProtos, 0); + $buffersInWildcard = array(); + + $tokens = token_get_all($resource->getContent()); + $calls = array(); + + while ($token = array_shift($tokens)) { + $current = self::tokenToString($token); + // loop through each prototype (by reference) + foreach (array_keys($this->prototypes) as $i) { + $prototype =& $this->prototypes[$i][0]; + $options = $this->prototypes[$i][1]; + $buffer =& $buffers[$i]; + $level =& $bufferLevels[$i]; + + if (isset($buffersInWildcard[$i])) { + switch ($current) { + case '(': ++$level; break; + case ')': --$level; break; + } + + $buffer .= $current; + + if (!$level) { + $calls[] = array($buffer.';', $options); + $buffer = ''; + unset($buffersInWildcard[$i]); + } + } elseif ($current == self::tokenToString(current($prototype))) { + $buffer .= $current; + if ('*' == self::tokenToString(next($prototype))) { + $buffersInWildcard[$i] = true; + ++$level; + } + } else { + reset($prototype); + unset($buffersInWildcard[$i]); + $buffer = ''; + } + } + } + + $formulae = array(); + foreach ($calls as $call) { + $formulae += call_user_func_array(array($this, 'processCall'), $call); + } + + return $formulae; + } + + private function processCall($call, array $protoOptions = array()) + { + $tmp = tempnam(sys_get_temp_dir(), 'assetic'); + file_put_contents($tmp, implode("\n", array( + 'registerSetupCode(), + $call, + 'echo serialize($_call);', + ))); + $args = unserialize(shell_exec('php '.escapeshellarg($tmp))); + unlink($tmp); + + $inputs = isset($args[0]) ? self::argumentToArray($args[0]) : array(); + $filters = isset($args[1]) ? self::argumentToArray($args[1]) : array(); + $options = isset($args[2]) ? $args[2] : array(); + + if (!isset($options['debug'])) { + $options['debug'] = $this->factory->isDebug(); + } + + if (!is_array($options)) { + throw new \RuntimeException('The third argument must be omitted, null or an array.'); + } + + // apply the prototype options + $options += $protoOptions; + + if (!isset($options['name'])) { + $options['name'] = $this->factory->generateAssetName($inputs, $filters, $options); + } + + return array($options['name'] => array($inputs, $filters, $options)); + } + + /** + * Returns an array of prototypical calls and options. + * + * @return array Prototypes and options + */ + abstract protected function registerPrototypes(); + + /** + * Returns setup code for the reflection scriptlet. + * + * @return string Some PHP setup code + */ + abstract protected function registerSetupCode(); + + static protected function tokenToString($token) + { + return is_array($token) ? $token[1] : $token; + } + + static protected function argumentToArray($argument) + { + return is_array($argument) ? $argument : array_filter(array_map('trim', explode(',', $argument))); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/CachedFormulaLoader.php b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/CachedFormulaLoader.php new file mode 100644 index 0000000..174fdd2 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/CachedFormulaLoader.php @@ -0,0 +1,68 @@ + + */ +class CachedFormulaLoader implements FormulaLoaderInterface +{ + private $loader; + private $configCache; + private $debug; + + /** + * Constructor. + * + * When the loader is in debug mode it will ensure the cached formulae + * are fresh before returning them. + * + * @param FormulaLoaderInterface $loader A formula loader + * @param ConfigCache $configCache A config cache + * @param Boolean $debug The debug mode + */ + public function __construct(FormulaLoaderInterface $loader, ConfigCache $configCache, $debug = false) + { + $this->loader = $loader; + $this->configCache = $configCache; + $this->debug = $debug; + } + + public function load(ResourceInterface $resources) + { + if (!$resources instanceof IteratorResourceInterface) { + $resources = array($resources); + } + + $formulae = array(); + + foreach ($resources as $resource) { + $id = (string) $resource; + if (!$this->configCache->has($id) || ($this->debug && !$resource->isFresh($this->configCache->getTimestamp($id)))) { + $formulae += $this->loader->load($resource); + $this->configCache->set($id, $formulae); + } else { + $formulae += $this->configCache->get($id); + } + } + + return $formulae; + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FormulaLoaderInterface.php b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FormulaLoaderInterface.php new file mode 100644 index 0000000..f1e877d --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FormulaLoaderInterface.php @@ -0,0 +1,34 @@ + + */ +interface FormulaLoaderInterface +{ + /** + * Loads formulae from a resource. + * + * Formulae should be loaded the same regardless of the current debug + * mode. Debug considerations should happen downstream. + * + * @param ResourceInterface $resource A resource + * + * @return array An array of formulae + */ + function load(ResourceInterface $resource); +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FunctionCallsFormulaLoader.php b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FunctionCallsFormulaLoader.php new file mode 100644 index 0000000..9147806 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FunctionCallsFormulaLoader.php @@ -0,0 +1,53 @@ + + */ +class FunctionCallsFormulaLoader extends BasePhpFormulaLoader +{ + protected function registerPrototypes() + { + return array( + 'assetic_javascripts(*)' => array('output' => 'js/*.js'), + 'assetic_stylesheets(*)' => array('output' => 'css/*.css'), + 'assetic_image(*)' => array('output' => 'images/*'), + ); + } + + protected function registerSetupCode() + { + return <<<'EOF' +function assetic_javascripts() +{ + global $_call; + $_call = func_get_args(); +} + +function assetic_stylesheets() +{ + global $_call; + $_call = func_get_args(); +} + +function assetic_image() +{ + global $_call; + $_call = func_get_args(); +} + +EOF; + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/CoalescingDirectoryResource.php b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/CoalescingDirectoryResource.php new file mode 100644 index 0000000..07f880e --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/CoalescingDirectoryResource.php @@ -0,0 +1,112 @@ + + */ +class CoalescingDirectoryResource implements IteratorResourceInterface +{ + private $directories; + + public function __construct($directories) + { + $this->directories = array(); + + foreach ($directories as $directory) { + $this->addDirectory($directory); + } + } + + public function addDirectory(IteratorResourceInterface $directory) + { + $this->directories[] = $directory; + } + + public function isFresh($timestamp) + { + foreach ($this->getFileResources() as $file) { + if (!$file->isFresh($timestamp)) { + return false; + } + } + + return true; + } + + public function getContent() + { + $parts = array(); + foreach ($this->getFileResources() as $file) { + $parts[] = $file->getContent(); + } + + return implode("\n", $parts); + } + + /** + * Returns a string to uniquely identify the current resource. + * + * @return string An identifying string + */ + public function __toString() + { + $parts = array(); + foreach ($this->directories as $directory) { + $parts[] = (string) $directory; + } + + return implode(',', $parts); + } + + public function getIterator() + { + return new \ArrayIterator($this->getFileResources()); + } + + /** + * Returns the relative version of a filename. + * + * @param ResourceInterface $file The file + * @param ResourceInterface $directory The directory + * + * @return string The name to compare with files from other directories + */ + protected function getRelativeName(ResourceInterface $file, ResourceInterface $directory) + { + return substr((string) $file, strlen((string) $directory)); + } + + /** + * Performs the coalesce. + * + * @return array An array of file resources + */ + private function getFileResources() + { + $paths = array(); + + foreach ($this->directories as $directory) { + foreach ($directory as $file) { + $relative = $this->getRelativeName($file, $directory); + + if (!isset($paths[$relative])) { + $paths[$relative] = $file; + } + } + } + + return array_values($paths); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/DirectoryResource.php b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/DirectoryResource.php new file mode 100644 index 0000000..3580d20 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/DirectoryResource.php @@ -0,0 +1,133 @@ + + */ +class DirectoryResource implements IteratorResourceInterface +{ + private $path; + private $pattern; + + /** + * Constructor. + * + * @param string $path A directory path + * @param string $pattern A filename pattern + */ + public function __construct($path, $pattern = null) + { + if (DIRECTORY_SEPARATOR != substr($path, -1)) { + $path .= DIRECTORY_SEPARATOR; + } + + $this->path = $path; + $this->pattern = $pattern; + } + + public function isFresh($timestamp) + { + if (!is_dir($this->path) || filemtime($this->path) > $timestamp) { + return false; + } + + foreach ($this as $resource) { + if (!$resource->isFresh($timestamp)) { + return false; + } + } + + return true; + } + + /** + * Returns the combined content of all inner resources. + */ + public function getContent() + { + $content = array(); + foreach ($this as $resource) { + $content[] = $resource->getContent(); + } + + return implode("\n", $content); + } + + public function __toString() + { + return $this->path; + } + + public function getIterator() + { + return is_dir($this->path) + ? new DirectoryResourceIterator($this->getInnerIterator()) + : new \EmptyIterator(); + } + + protected function getInnerIterator() + { + return new DirectoryResourceFilterIterator(new \RecursiveDirectoryIterator($this->path), $this->pattern); + } +} + +/** + * An iterator that converts file objects into file resources. + * + * @author Kris Wallsmith + * @access private + */ +class DirectoryResourceIterator extends \RecursiveIteratorIterator +{ + public function current() + { + return new FileResource(parent::current()->getPathname()); + } +} + +/** + * Filters files by a basename pattern. + * + * @author Kris Wallsmith + * @access private + */ +class DirectoryResourceFilterIterator extends \RecursiveFilterIterator +{ + protected $pattern; + + public function __construct(\RecursiveDirectoryIterator $iterator, $pattern = null) + { + parent::__construct($iterator); + + $this->pattern = $pattern; + } + + public function accept() + { + $file = $this->current(); + $name = $file->getBasename(); + + if ($file->isDir()) { + return '.' != $name[0]; + } else { + return null === $this->pattern || 0 < preg_match($this->pattern, $name); + } + } + + public function getChildren() + { + return new self(new \RecursiveDirectoryIterator($this->current()->getPathname()), $this->pattern); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/FileResource.php b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/FileResource.php new file mode 100644 index 0000000..1486f3e --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/FileResource.php @@ -0,0 +1,47 @@ + + */ +class FileResource implements ResourceInterface +{ + private $path; + + /** + * Constructor. + * + * @param string $path The path to a file + */ + public function __construct($path) + { + $this->path = $path; + } + + public function isFresh($timestamp) + { + return file_exists($this->path) && filemtime($this->path) <= $timestamp; + } + + public function getContent() + { + return file_exists($this->path) ? file_get_contents($this->path) : ''; + } + + public function __toString() + { + return $this->path; + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/IteratorResourceInterface.php b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/IteratorResourceInterface.php new file mode 100644 index 0000000..02d797f --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/IteratorResourceInterface.php @@ -0,0 +1,21 @@ + + */ +interface IteratorResourceInterface extends ResourceInterface, \IteratorAggregate +{ +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/ResourceInterface.php b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/ResourceInterface.php new file mode 100644 index 0000000..d53ffcd --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/ResourceInterface.php @@ -0,0 +1,43 @@ + + */ +interface ResourceInterface +{ + /** + * Checks if a timestamp represents the latest resource. + * + * @param integer $timestamp A UNIX timestamp + * + * @return Boolean True if the timestamp is up to date + */ + function isFresh($timestamp); + + /** + * Returns the content of the resource. + * + * @return string The content + */ + function getContent(); + + /** + * Returns a unique string for the current resource. + * + * @return string A unique string to identity the current resource + */ + function __toString(); +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/EnsureFilterWorker.php b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/EnsureFilterWorker.php new file mode 100644 index 0000000..189cab8 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/EnsureFilterWorker.php @@ -0,0 +1,60 @@ + + * @todo A better asset-matcher mechanism + */ +class EnsureFilterWorker implements WorkerInterface +{ + const CHECK_SOURCE = 1; + const CHECK_TARGET = 2; + + private $pattern; + private $filter; + private $flags; + + /** + * Constructor. + * + * @param string $pattern A regex for checking the asset's target URL + * @param FilterInterface $filter A filter to apply if the regex matches + * @param integer $flags Flags for what to check + */ + public function __construct($pattern, FilterInterface $filter, $flags = null) + { + if (null === $flags) { + $flags = self::CHECK_SOURCE | self::CHECK_TARGET; + } + + $this->pattern = $pattern; + $this->filter = $filter; + $this->flags = $flags; + } + + public function process(AssetInterface $asset) + { + if ( + (self::CHECK_SOURCE === (self::CHECK_SOURCE & $this->flags) && preg_match($this->pattern, $asset->getSourcePath())) + || + (self::CHECK_TARGET === (self::CHECK_TARGET & $this->flags) && preg_match($this->pattern, $asset->getTargetPath())) + ) { + $asset->ensureFilter($this->filter); + } + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/WorkerInterface.php b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/WorkerInterface.php new file mode 100644 index 0000000..003e4e4 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/WorkerInterface.php @@ -0,0 +1,31 @@ + + */ +interface WorkerInterface +{ + /** + * Processes an asset. + * + * @param AssetInterface $asset An asset + * + * @return AssetInterface|null May optionally return a replacement asset + */ + function process(AssetInterface $asset); +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/BaseCssFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/BaseCssFilter.php new file mode 100644 index 0000000..0447fbc --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/BaseCssFilter.php @@ -0,0 +1,71 @@ + + */ +abstract class BaseCssFilter implements FilterInterface +{ + /** + * Filters all references -- url() and "@import" -- through a callable. + * + * @param string $content The CSS + * @param mixed $callback A PHP callable + * + * @return string The filtered CSS + */ + protected function filterReferences($content, $callback, $limit = -1, & $count = 0) + { + $content = $this->filterUrls($content, $callback, $limit, $count); + $content = $this->filterImports($content, $callback, $limit, $count, false); + + return $content; + } + + /** + * Filters all CSS url()'s through a callable. + * + * @param string $content The CSS + * @param mixed $callback A PHP callable + * @param integer $limit Limit the number of replacements + * @param integer $count Will be populated with the count + * + * @return string The filtered CSS + */ + protected function filterUrls($content, $callback, $limit = -1, & $count = 0) + { + return preg_replace_callback('/url\((["\']?)(?.*?)(\\1)\)/', $callback, $content, $limit, $count); + } + + /** + * Filters all CSS imports through a callable. + * + * @param string $content The CSS + * @param mixed $callback A PHP callable + * @param integer $limit Limit the number of replacements + * @param integer $count Will be populated with the count + * @param Boolean $includeUrl Whether to include url() in the pattern + * + * @return string The filtered CSS + */ + protected function filterImports($content, $callback, $limit = -1, & $count = 0, $includeUrl = true) + { + $pattern = $includeUrl + ? '/@import (?:url\()?(\'|"|)(?[^\'"\)\n\r]*)\1\)?;?/' + : '/@import (?!url\()(\'|"|)(?[^\'"\)\n\r]*)\1;?/'; + + return preg_replace_callback($pattern, $callback, $content, $limit, $count); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/CallablesFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/CallablesFilter.php new file mode 100644 index 0000000..323d11c --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/CallablesFilter.php @@ -0,0 +1,45 @@ + + */ +class CallablesFilter implements FilterInterface +{ + private $loader; + private $dumper; + + public function __construct($loader = null, $dumper = null) + { + $this->loader = $loader; + $this->dumper = $dumper; + } + + public function filterLoad(AssetInterface $asset) + { + if (null !== $callable = $this->loader) { + $callable($asset); + } + } + + public function filterDump(AssetInterface $asset) + { + if (null !== $callable = $this->dumper) { + $callable($asset); + } + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/CoffeeScriptFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/CoffeeScriptFilter.php new file mode 100644 index 0000000..13a54e7 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/CoffeeScriptFilter.php @@ -0,0 +1,73 @@ + + */ +class CoffeeScriptFilter implements FilterInterface +{ + private $coffeePath; + private $nodePath; + + // coffee options + private $bare; + + public function __construct($coffeePath = '/usr/bin/coffee', $nodePath = '/usr/bin/node') + { + $this->coffeePath = $coffeePath; + $this->nodePath = $nodePath; + } + + public function setBare($bare) + { + $this->bare = $bare; + } + + public function filterLoad(AssetInterface $asset) + { + $input = tempnam(sys_get_temp_dir(), 'assetic_coffeescript'); + file_put_contents($input, $asset->getContent()); + + $pb = new ProcessBuilder(array( + $this->nodePath, + $this->coffeePath, + '-cp', + )); + + if ($this->bare) { + $pb->add('--bare'); + } + + $pb->add($input); + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($input); + + if (0 < $code) { + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent($proc->getOutput()); + } + + public function filterDump(AssetInterface $asset) + { + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/CompassFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/CompassFilter.php new file mode 100644 index 0000000..cfd6f5c --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/CompassFilter.php @@ -0,0 +1,346 @@ + + */ +class CompassFilter implements FilterInterface +{ + private $compassPath; + private $scss; + + // sass options + private $unixNewlines; + private $debugInfo; + private $cacheLocation; + private $noCache; + + // compass options + private $force; + private $style; + private $quiet; + private $boring; + private $noLineComments; + private $imagesDir; + private $javascriptsDir; + + // compass configuration file options + private $plugins = array(); + private $loadPaths = array(); + private $httpPath; + private $httpImagesPath; + private $generatedImagesPath; + private $httpJavascriptsPath; + + public function __construct($compassPath = '/usr/bin/compass') + { + $this->compassPath = $compassPath; + $this->cacheLocation = sys_get_temp_dir(); + + if ('cli' !== php_sapi_name()) { + $this->boring = true; + } + } + + public function setScss($scss) + { + $this->scss = $scss; + } + + // sass options setters + public function setUnixNewlines($unixNewlines) + { + $this->unixNewlines = $unixNewlines; + } + + public function setDebugInfo($debugInfo) + { + $this->debugInfo = $debugInfo; + } + + public function setCacheLocation($cacheLocation) + { + $this->cacheLocation = $cacheLocation; + } + + public function setNoCache($noCache) + { + $this->noCache = $noCache; + } + + // compass options setters + public function setForce($force) + { + $this->force = $force; + } + + public function setStyle($style) + { + $this->style = $style; + } + + public function setQuiet($quiet) + { + $this->quiet = $quiet; + } + + public function setBoring($boring) + { + $this->boring = $boring; + } + + public function setNoLineComments($noLineComments) + { + $this->noLineComments = $noLineComments; + } + + public function setImagesDir($imagesDir) + { + $this->imagesDir = $imagesDir; + } + + public function setJavascriptsDir($javascriptsDir) + { + $this->javascriptsDir = $javascriptsDir; + } + + // compass configuration file options setters + public function setPlugins(array $plugins) + { + $this->plugins = $plugins; + } + + public function addPlugin($plugin) + { + $this->plugins[] = $plugin; + } + + public function addLoadPath($loadPath) + { + $this->loadPaths[] = $loadPath; + } + + public function setHttpPath($httpPath) + { + $this->httpPath = $httpPath; + } + + public function setHttpImagesPath($httpImagesPath) + { + $this->httpImagesPath = $httpImagesPath; + } + + public function setGeneratedImagesPath($generatedImagesPath) + { + $this->generatedImagesPath = $generatedImagesPath; + } + + public function setHttpJavascriptsPath($httpJavascriptsPath) + { + $this->httpJavascriptsPath = $httpJavascriptsPath; + } + + public function filterLoad(AssetInterface $asset) + { + $root = $asset->getSourceRoot(); + $path = $asset->getSourcePath(); + + $loadPaths = $this->loadPaths; + if ($root && $path) { + $loadPaths[] = dirname($root.'/'.$path); + } + + // compass does not seems to handle symlink, so we use realpath() + $tempDir = realpath(sys_get_temp_dir()); + + $pb = new ProcessBuilder(array( + $this->compassPath, + 'compile', + $tempDir, + )); + $pb->inheritEnvironmentVariables(); + + if ($this->force) { + $pb->add('--force'); + } + + if ($this->style) { + $pb->add('--output-style')->add($this->style); + } + + if ($this->quiet) { + $pb->add('--quiet'); + } + + if ($this->boring) { + $pb->add('--boring'); + } + + if ($this->noLineComments) { + $pb->add('--no-line-comments'); + } + + // these two options are not passed into the config file + // because like this, compass adapts this to be xxx_dir or xxx_path + // whether it's an absolute path or not + if ($this->imagesDir) { + $pb->add('--images-dir')->add($this->imagesDir); + } + + if ($this->javascriptsDir) { + $pb->add('--javascripts-dir')->add($this->javascriptsDir); + } + + // options in config file + $optionsConfig = array(); + + if (!empty($loadPaths)) { + $optionsConfig['additional_import_paths'] = $loadPaths; + } + + if ($this->unixNewlines) { + $optionsConfig['sass_options']['unix_newlines'] = true; + } + + if ($this->debugInfo) { + $optionsConfig['sass_options']['debug_info'] = true; + } + + if ($this->cacheLocation) { + $optionsConfig['sass_options']['cache_location'] = $this->cacheLocation; + } + + if ($this->noCache) { + $optionsConfig['sass_options']['no_cache'] = true; + } + + if ($this->httpPath) { + $optionsConfig['http_path'] = $this->httpPath; + } + + if ($this->httpImagesPath) { + $optionsConfig['http_images_path'] = $this->httpImagesPath; + } + + if ($this->generatedImagesPath) { + $optionsConfig['generated_images_path'] = $this->generatedImagesPath; + } + + if ($this->httpJavascriptsPath) { + $optionsConfig['http_javascripts_path'] = $this->httpJavascriptsPath; + } + + // options in configuration file + if (count($optionsConfig)) { + $config = array(); + foreach ($this->plugins as $plugin) { + $config[] = sprintf("require '%s'", addcslashes($plugin, '\\')); + } + foreach ($optionsConfig as $name => $value) { + if (!is_array($value)) { + $config[] = sprintf('%s = "%s"', $name, addcslashes($value, '\\')); + } elseif (!empty($value)) { + $config[] = sprintf('%s = %s', $name, $this->formatArrayToRuby($value)); + } + } + + $configFile = tempnam($tempDir, 'assetic_compass'); + file_put_contents($configFile, implode("\n", $config)."\n"); + $pb->add('--config')->add($configFile); + } + + $pb->add('--sass-dir')->add('')->add('--css-dir')->add(''); + + // compass choose the type (sass or scss from the filename) + if (null !== $this->scss) { + $type = $this->scss ? 'scss' : 'sass'; + } elseif ($path) { + // FIXME: what if the extension is something else? + $type = pathinfo($path, PATHINFO_EXTENSION); + } else { + $type = 'scss'; + } + + $tempName = tempnam($tempDir, 'assetic_compass'); + unlink($tempName); // FIXME: don't use tempnam() here + + // input + $input = $tempName.'.'.$type; + + // work-around for https://github.com/chriseppstein/compass/issues/748 + if (defined('PHP_WINDOWS_VERSION_MAJOR')) { + $input = str_replace('\\', '/', $input); + } + + $pb->add($input); + file_put_contents($input, $asset->getContent()); + + // output + $output = $tempName.'.css'; + + // it's not really usefull but... https://github.com/chriseppstein/compass/issues/376 + $pb->setEnv('HOME', sys_get_temp_dir()); + + $proc = $pb->getProcess(); + $code = $proc->run(); + + if (0 < $code) { + unlink($input); + if (isset($configFile)) { + unlink($configFile); + } + + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent(file_get_contents($output)); + + unlink($input); + unlink($output); + if (isset($configFile)) { + unlink($configFile); + } + } + + public function filterDump(AssetInterface $asset) + { + } + + private function formatArrayToRuby($array) + { + $output = array(); + + // does we have an associative array ? + if (count(array_filter(array_keys($array), "is_numeric")) != count($array)) { + foreach($array as $name => $value) { + $output[] = sprintf(' :%s => "%s"', $name, addcslashes($value, '\\')); + } + $output = "{\n".implode(",\n", $output)."\n}"; + } else { + foreach($array as $name => $value) { + $output[] = sprintf(' "%s"', addcslashes($value, '\\')); + } + $output = "[\n".implode(",\n", $output)."\n]"; + } + + return $output; + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssEmbedFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssEmbedFilter.php new file mode 100644 index 0000000..7e8a80b --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssEmbedFilter.php @@ -0,0 +1,139 @@ + + */ +class CssEmbedFilter implements FilterInterface +{ + private $jarPath; + private $javaPath; + private $charset; + private $mhtml; // Enable MHTML mode. + private $mhtmlRoot; // Use as the MHTML root for the file. + private $root; // Prepends to all relative URLs. + private $skipMissing; // Don't throw an error for missing image files. + private $maxUriLength; // Maximum length for a data URI. Defaults to 32768. + private $maxImageSize; // Maximum image size (in bytes) to convert. + + public function __construct($jarPath, $javaPath = '/usr/bin/java') + { + $this->jarPath = $jarPath; + $this->javaPath = $javaPath; + } + + public function setCharset($charset) + { + $this->charset = $charset; + } + + public function setMhtml($mhtml) + { + $this->mhtml = $mhtml; + } + + public function setMhtmlRoot($mhtmlRoot) + { + $this->mhtmlRoot = $mhtmlRoot; + } + + public function setRoot($root) + { + $this->root = $root; + } + + public function setSkipMissing($skipMissing) + { + $this->skipMissing = $skipMissing; + } + + public function setMaxUriLength($maxUriLength) + { + $this->maxUriLength = $maxUriLength; + } + + public function setMaxImageSize($maxImageSize) + { + $this->maxImageSize = $maxImageSize; + } + + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $pb = new ProcessBuilder(array( + $this->javaPath, + '-jar', + $this->jarPath, + )); + + if (null !== $this->charset) { + $pb->add('--charset')->add($this->charset); + } + + if ($this->mhtml) { + $pb->add('--mhtml'); + } + + if (null !== $this->mhtmlRoot) { + $pb->add('--mhtmlroot')->add($this->mhtmlRoot); + } + + // automatically define root if not already defined + if (null === $this->root) { + $root = $asset->getSourceRoot(); + $path = $asset->getSourcePath(); + + if ($root && $path) { + $pb->add('--root')->add(dirname($root.'/'.$path)); + } + } else { + $pb->add('--root')->add($this->root); + } + + if ($this->skipMissing) { + $pb->add('--skip-missing'); + } + + if (null !== $this->maxUriLength) { + $pb->add('--max-uri-length')->add($this->maxUriLength); + } + + if (null !== $this->maxImageSize) { + $pb->add('--max-image-size')->add($this->maxImageSize); + } + + // input + $pb->add($input = tempnam(sys_get_temp_dir(), 'assetic_cssembed')); + file_put_contents($input, $asset->getContent()); + + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($input); + + if (0 < $code) { + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent($proc->getOutput()); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssImportFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssImportFilter.php new file mode 100644 index 0000000..aa1a7d9 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssImportFilter.php @@ -0,0 +1,107 @@ + + */ +class CssImportFilter extends BaseCssFilter +{ + private $importFilter; + + /** + * Constructor. + * + * @param FilterInterface $importFilter Filter for each imported asset + */ + public function __construct(FilterInterface $importFilter = null) + { + $this->importFilter = $importFilter ?: new CssRewriteFilter(); + } + + public function filterLoad(AssetInterface $asset) + { + $importFilter = $this->importFilter; + $sourceRoot = $asset->getSourceRoot(); + $sourcePath = $asset->getSourcePath(); + + $callback = function($matches) use($importFilter, $sourceRoot, $sourcePath) + { + if (!$matches['url'] || null === $sourceRoot) { + return $matches[0]; + } + + $importRoot = $sourceRoot; + + if (false !== strpos($matches['url'], '://')) { + // absolute + list($importScheme, $tmp) = explode('://', $matches['url'], 2); + list($importHost, $importPath) = explode('/', $tmp, 2); + $importRoot = $importScheme.'://'.$importHost; + } elseif (0 === strpos($matches['url'], '//')) { + // protocol-relative + list($importHost, $importPath) = explode('/', substr($matches['url'], 2), 2); + $importHost = '//'.$importHost; + } elseif ('/' == $matches['url'][0]) { + // root-relative + $importPath = substr($matches['url'], 1); + } elseif (null !== $sourcePath) { + // document-relative + $importPath = $matches['url']; + if ('.' != $sourceDir = dirname($sourcePath)) { + $importPath = $sourceDir.'/'.$importPath; + } + } else { + return $matches[0]; + } + + // ignore other imports + if ('css' != pathinfo($importPath, PATHINFO_EXTENSION)) { + return $matches[0]; + } + + $importSource = $importRoot.'/'.$importPath; + if (false !== strpos($importSource, '://') || 0 === strpos($importSource, '//')) { + $import = new HttpAsset($importSource, array($importFilter), true); + } elseif (!file_exists($importSource)) { + // ignore not found imports + return $matches[0]; + } else { + $import = new FileAsset($importSource, array($importFilter), $importRoot, $importPath); + } + + $import->setTargetPath($sourcePath); + + return $import->dump(); + }; + + $content = $asset->getContent(); + $lastHash = md5($content); + + do { + $content = $this->filterImports($content, $callback); + $hash = md5($content); + } while ($lastHash != $hash && $lastHash = $hash); + + $asset->setContent($content); + } + + public function filterDump(AssetInterface $asset) + { + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssMinFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssMinFilter.php new file mode 100644 index 0000000..cc01672 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssMinFilter.php @@ -0,0 +1,74 @@ + + */ +class CssMinFilter implements FilterInterface +{ + private $filters; + private $plugins; + + public function __construct() + { + $this->filters = array(); + $this->plugins = array(); + } + + public function setFilters(array $filters) + { + $this->filters = $filters; + } + + public function setFilter($name, $value) + { + $this->filters[$name] = $value; + } + + public function setPlugins(array $plugins) + { + $this->plugins = $plugins; + } + + public function setPlugin($name, $value) + { + $this->plugins[$name] = $value; + } + + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $filters = $this->filters; + $plugins = $this->plugins; + + if (isset($filters['ImportImports']) && true === $filters['ImportImports']) { + $root = $asset->getSourceRoot(); + $path = $asset->getSourcePath(); + if ($root && $path) { + $filters['ImportImports'] = array('BasePath' => dirname($root.'/'.$path)); + } else { + unset($filters['ImportImports']); + } + } + + $asset->setContent(\CssMin::minify($asset->getContent(), $filters, $plugins)); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssRewriteFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssRewriteFilter.php new file mode 100644 index 0000000..c431437 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssRewriteFilter.php @@ -0,0 +1,94 @@ + + */ +class CssRewriteFilter extends BaseCssFilter +{ + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $sourceBase = $asset->getSourceRoot(); + $sourcePath = $asset->getSourcePath(); + $targetPath = $asset->getTargetPath(); + + if (null === $sourcePath || null === $targetPath || $sourcePath == $targetPath) { + return; + } + + // learn how to get from the target back to the source + if (false !== strpos($sourceBase, '://')) { + list($scheme, $url) = explode('://', $sourceBase.'/'.$sourcePath, 2); + list($host, $path) = explode('/', $url, 2); + + $host = $scheme.'://'.$host.'/'; + $path = false === strpos($path, '/') ? '' : dirname($path); + $path .= '/'; + } else { + // assume source and target are on the same host + $host = ''; + + // pop entries off the target until it fits in the source + if ('.' == dirname($sourcePath)) { + $path = str_repeat('../', substr_count($targetPath, '/')); + } elseif ('.' == $targetDir = dirname($targetPath)) { + $path = dirname($sourcePath).'/'; + } else { + $path = ''; + while (0 !== strpos($sourcePath, $targetDir)) { + if (false !== $pos = strrpos($targetDir, '/')) { + $targetDir = substr($targetDir, 0, $pos); + $path .= '../'; + } else { + $targetDir = ''; + $path .= '../'; + break; + } + } + $path .= ltrim(substr(dirname($sourcePath).'/', strlen($targetDir)), '/'); + } + } + + $content = $this->filterReferences($asset->getContent(), function($matches) use($host, $path) + { + if (false !== strpos($matches['url'], '://') || 0 === strpos($matches['url'], '//') || 0 === strpos($matches['url'], 'data:')) { + // absolute or protocol-relative or data uri + return $matches[0]; + } + + if ('/' == $matches['url'][0]) { + // root relative + return str_replace($matches['url'], $host.$matches['url'], $matches[0]); + } + + // document relative + $url = $matches['url']; + while (0 === strpos($url, '../') && 2 <= substr_count($path, '/')) { + $path = substr($path, 0, strrpos(rtrim($path, '/'), '/') + 1); + $url = substr($url, 3); + } + + return str_replace($matches['url'], $host.$path.$url, $matches[0]); + }); + + $asset->setContent($content); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterCollection.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterCollection.php new file mode 100644 index 0000000..1ee743d --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterCollection.php @@ -0,0 +1,82 @@ + + */ +class FilterCollection implements FilterInterface, \IteratorAggregate, \Countable +{ + private $filters = array(); + + public function __construct($filters = array()) + { + foreach ($filters as $filter) { + $this->ensure($filter); + } + } + + /** + * Checks that the current collection contains the supplied filter. + * + * If the supplied filter is another filter collection, each of its + * filters will be checked. + */ + public function ensure(FilterInterface $filter) + { + if ($filter instanceof \Traversable) { + foreach ($filter as $f) { + $this->ensure($f); + } + } elseif (!in_array($filter, $this->filters, true)) { + $this->filters[] = $filter; + } + } + + public function all() + { + return $this->filters; + } + + public function clear() + { + $this->filters = array(); + } + + public function filterLoad(AssetInterface $asset) + { + foreach ($this->filters as $filter) { + $filter->filterLoad($asset); + } + } + + public function filterDump(AssetInterface $asset) + { + foreach ($this->filters as $filter) { + $filter->filterDump($asset); + } + } + + public function getIterator() + { + return new \ArrayIterator($this->filters); + } + + public function count() + { + return count($this->filters); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterInterface.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterInterface.php new file mode 100644 index 0000000..0d816c2 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterInterface.php @@ -0,0 +1,36 @@ + + */ +interface FilterInterface +{ + /** + * Filters an asset after it has been loaded. + * + * @param AssetInterface $asset An asset + */ + function filterLoad(AssetInterface $asset); + + /** + * Filters an asset just before it's dumped. + * + * @param AssetInterface $asset An asset + */ + function filterDump(AssetInterface $asset); +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/BaseCompilerFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/BaseCompilerFilter.php new file mode 100644 index 0000000..e571158 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/BaseCompilerFilter.php @@ -0,0 +1,84 @@ + + */ +abstract class BaseCompilerFilter implements FilterInterface +{ + // compilation levels + const COMPILE_WHITESPACE_ONLY = 'WHITESPACE_ONLY'; + const COMPILE_SIMPLE_OPTIMIZATIONS = 'SIMPLE_OPTIMIZATIONS'; + const COMPILE_ADVANCED_OPTIMIZATIONS = 'ADVANCED_OPTIMIZATIONS'; + + // formatting modes + const FORMAT_PRETTY_PRINT = 'pretty_print'; + const FORMAT_PRINT_INPUT_DELIMITER = 'print_input_delimiter'; + + // warning levels + const LEVEL_QUIET = 'QUIET'; + const LEVEL_DEFAULT = 'DEFAULT'; + const LEVEL_VERBOSE = 'VERBOSE'; + + protected $compilationLevel; + protected $jsExterns; + protected $externsUrl; + protected $excludeDefaultExterns; + protected $formatting; + protected $useClosureLibrary; + protected $warningLevel; + + public function setCompilationLevel($compilationLevel) + { + $this->compilationLevel = $compilationLevel; + } + + public function setJsExterns($jsExterns) + { + $this->jsExterns = $jsExterns; + } + + public function setExternsUrl($externsUrl) + { + $this->externsUrl = $externsUrl; + } + + public function setExcludeDefaultExterns($excludeDefaultExterns) + { + $this->excludeDefaultExterns = $excludeDefaultExterns; + } + + public function setFormatting($formatting) + { + $this->formatting = $formatting; + } + + public function setUseClosureLibrary($useClosureLibrary) + { + $this->useClosureLibrary = $useClosureLibrary; + } + + public function setWarningLevel($warningLevel) + { + $this->warningLevel = $warningLevel; + } + + public function filterLoad(AssetInterface $asset) + { + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerApiFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerApiFilter.php new file mode 100644 index 0000000..4945961 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerApiFilter.php @@ -0,0 +1,100 @@ + + */ +class CompilerApiFilter extends BaseCompilerFilter +{ + public function filterDump(AssetInterface $asset) + { + $query = array( + 'js_code' => $asset->getContent(), + 'output_format' => 'json', + 'output_info' => 'compiled_code', + ); + + if (null !== $this->compilationLevel) { + $query['compilation_level'] = $this->compilationLevel; + } + + if (null !== $this->jsExterns) { + $query['js_externs'] = $this->jsExterns; + } + + if (null !== $this->externsUrl) { + $query['externs_url'] = $this->externsUrl; + } + + if (null !== $this->excludeDefaultExterns) { + $query['exclude_default_externs'] = $this->excludeDefaultExterns ? 'true' : 'false'; + } + + if (null !== $this->formatting) { + $query['formatting'] = $this->formatting; + } + + if (null !== $this->useClosureLibrary) { + $query['use_closure_library'] = $this->useClosureLibrary ? 'true' : 'false'; + } + + if (null !== $this->warningLevel) { + $query['warning_level'] = $this->warningLevel; + } + + if (preg_match('/1|yes|on|true/i', ini_get('allow_url_fopen'))) { + $context = stream_context_create(array('http' => array( + 'method' => 'POST', + 'header' => 'Content-Type: application/x-www-form-urlencoded', + 'content' => http_build_query($query), + ))); + + $response = file_get_contents('http://closure-compiler.appspot.com/compile', false, $context); + $data = json_decode($response); + + } elseif (defined('CURLOPT_POST') && !in_array('curl_init', explode(',', ini_get('disable_functions')))) { + + $ch = curl_init('http://closure-compiler.appspot.com/compile'); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded')); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $query); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15); + $response = curl_exec($ch); + curl_close($ch); + + $data = json_decode($response); + } else { + throw new \RuntimeException("There is no known way to contact closure compiler available"); + } + + if (isset($data->serverErrors) && 0 < count($data->serverErrors)) { + // @codeCoverageIgnoreStart + throw new \RuntimeException(sprintf('The Google Closure Compiler API threw some server errors: '.print_r($data->serverErrors, true))); + // @codeCoverageIgnoreEnd + } + + if (isset($data->errors) && 0 < count($data->errors)) { + // @codeCoverageIgnoreStart + throw new \RuntimeException(sprintf('The Google Closure Compiler API threw some errors: '.print_r($data->errors, true))); + // @codeCoverageIgnoreEnd + } + + $asset->setContent($data->compiledCode); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerJarFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerJarFilter.php new file mode 100644 index 0000000..a86f06d --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerJarFilter.php @@ -0,0 +1,90 @@ + + */ +class CompilerJarFilter extends BaseCompilerFilter +{ + private $jarPath; + private $javaPath; + + public function __construct($jarPath, $javaPath = '/usr/bin/java') + { + $this->jarPath = $jarPath; + $this->javaPath = $javaPath; + } + + public function filterDump(AssetInterface $asset) + { + $cleanup = array(); + + $pb = new ProcessBuilder(array( + $this->javaPath, + '-jar', + $this->jarPath, + )); + + if (null !== $this->compilationLevel) { + $pb->add('--compilation_level')->add($this->compilationLevel); + } + + if (null !== $this->jsExterns) { + $cleanup[] = $externs = tempnam(sys_get_temp_dir(), 'assetic_google_closure_compiler'); + file_put_contents($externs, $this->jsExterns); + $pb->add('--externs')->add($externs); + } + + if (null !== $this->externsUrl) { + $cleanup[] = $externs = tempnam(sys_get_temp_dir(), 'assetic_google_closure_compiler'); + file_put_contents($externs, file_get_contents($this->externsUrl)); + $pb->add('--externs')->add($externs); + } + + if (null !== $this->excludeDefaultExterns) { + $pb->add('--use_only_custom_externs'); + } + + if (null !== $this->formatting) { + $pb->add('--formatting')->add($this->formatting); + } + + if (null !== $this->useClosureLibrary) { + $pb->add('--manage_closure_dependencies'); + } + + if (null !== $this->warningLevel) { + $pb->add('--warning_level')->add($this->warningLevel); + } + + $pb->add('--js')->add($cleanup[] = $input = tempnam(sys_get_temp_dir(), 'assetic_google_closure_compiler')); + file_put_contents($input, $asset->getContent()); + + $proc = $pb->getProcess(); + $code = $proc->run(); + array_map('unlink', $cleanup); + + if (0 < $code) { + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent($proc->getOutput()); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/GssFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/GssFilter.php new file mode 100644 index 0000000..895b3a2 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/GssFilter.php @@ -0,0 +1,142 @@ + + */ +class GssFilter implements FilterInterface +{ + private $jarPath; + private $javaPath; + private $allowUnrecognizedFunctions; + private $allowedNonStandardFunctions; + private $copyrightNotice; + private $define; + private $gssFunctionMapProvider; + private $inputOrientation; + private $outputOrientation; + private $prettyPrint; + + public function __construct($jarPath, $javaPath = '/usr/bin/java') + { + $this->jarPath = $jarPath; + $this->javaPath = $javaPath; + } + + public function setAllowUnrecognizedFunctions($allowUnrecognizedFunctions) + { + $this->allowUnrecognizedFunctions = $allowUnrecognizedFunctions; + } + + public function setAllowedNonStandardFunctions($allowNonStandardFunctions) + { + $this->allowedNonStandardFunctions = $allowNonStandardFunctions; + } + + public function setCopyrightNotice($copyrightNotice) + { + $this->copyrightNotice = $copyrightNotice; + } + + public function setDefine($define) + { + $this->define = $define; + } + + public function setGssFunctionMapProvider($gssFunctionMapProvider) + { + $this->gssFunctionMapProvider = $gssFunctionMapProvider; + } + + public function setInputOrientation($inputOrientation) + { + $this->inputOrientation = $inputOrientation; + } + + public function setOutputOrientation($outputOrientation) + { + $this->outputOrientation = $outputOrientation; + } + + public function setPrettyPrint($prettyPrint) + { + $this->prettyPrint = $prettyPrint; + } + + public function filterLoad(AssetInterface $asset) + { + $cleanup = array(); + + $pb = new ProcessBuilder(array( + $this->javaPath, + '-jar', + $this->jarPath, + )); + + if (null !== $this->allowUnrecognizedFunctions) { + $pb->add('--allow-unrecognized-functions'); + } + + if (null !== $this->allowedNonStandardFunctions) { + $pb->add('--allowed_non_standard_functions')->add($this->allowedNonStandardFunctions); + } + + if (null !== $this->copyrightNotice) { + $pb->add('--copyright-notice')->add($this->copyrightNotice); + } + + if (null !== $this->define) { + $pb->add('--define')->add($this->define); + } + + if (null !== $this->gssFunctionMapProvider) { + $pb->add('--gss-function-map-provider')->add($this->gssFunctionMapProvider); + } + + if (null !== $this->inputOrientation) { + $pb->add('--input-orientation')->add($this->inputOrientation); + } + + if (null !== $this->outputOrientation) { + $pb->add('--output-orientation')->add($this->outputOrientation); + } + + if (null !== $this->prettyPrint) { + $pb->add('--pretty-print'); + } + + $pb->add($cleanup[] = $input = tempnam(sys_get_temp_dir(), 'assetic_google_closure_stylesheets_compiler')); + file_put_contents($input, $asset->getContent()); + + $proc = $pb->getProcess(); + $code = $proc->run(); + array_map('unlink', $cleanup); + + if (0 < $code) { + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent($proc->getOutput()); + } + + public function filterDump(AssetInterface $asset) + { + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/HashableInterface.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/HashableInterface.php new file mode 100644 index 0000000..6e9aed9 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/HashableInterface.php @@ -0,0 +1,29 @@ + + */ +interface HashableInterface +{ + /** + * Generates a hash for the object + * + * @return string Object hash + */ + function hash(); +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinFilter.php new file mode 100644 index 0000000..1a8a7a7 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinFilter.php @@ -0,0 +1,34 @@ + + */ +class JSMinFilter implements FilterInterface +{ + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $asset->setContent(\JSMin::minify($asset->getContent())); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinPlusFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinPlusFilter.php new file mode 100644 index 0000000..f61d446 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinPlusFilter.php @@ -0,0 +1,34 @@ + + */ +class JSMinPlusFilter implements FilterInterface +{ + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $asset->setContent(\JSMinPlus::minify($asset->getContent())); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegoptimFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegoptimFilter.php new file mode 100644 index 0000000..6b97e6c --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegoptimFilter.php @@ -0,0 +1,81 @@ + + */ +class JpegoptimFilter implements FilterInterface +{ + private $jpegoptimBin; + private $stripAll; + private $max; + + /** + * Constructor. + * + * @param string $jpegoptimBin Path to the jpegoptim binary + */ + public function __construct($jpegoptimBin = '/usr/bin/jpegoptim') + { + $this->jpegoptimBin = $jpegoptimBin; + } + + public function setStripAll($stripAll) + { + $this->stripAll = $stripAll; + } + + public function setMax($max) + { + $this->max = $max; + } + + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $pb = new ProcessBuilder(array($this->jpegoptimBin)); + + if ($this->stripAll) { + $pb->add('--strip-all'); + } + + if ($this->max) { + $pb->add('--max='.$this->max); + } + + $pb->add($input = tempnam(sys_get_temp_dir(), 'assetic_jpegoptim')); + file_put_contents($input, $asset->getContent()); + + $proc = $pb->getProcess(); + $proc->run(); + + if (false !== strpos($proc->getOutput(), 'ERROR')) { + unlink($input); + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent(file_get_contents($input)); + + unlink($input); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegtranFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegtranFilter.php new file mode 100644 index 0000000..95a3547 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegtranFilter.php @@ -0,0 +1,103 @@ + + */ +class JpegtranFilter implements FilterInterface +{ + const COPY_NONE = 'none'; + const COPY_COMMENTS = 'comments'; + const COPY_ALL = 'all'; + + private $jpegtranBin; + private $optimize; + private $copy; + private $progressive; + private $restart; + + /** + * Constructor. + * + * @param string $jpegtranBin Path to the jpegtran binary + */ + public function __construct($jpegtranBin = '/usr/bin/jpegtran') + { + $this->jpegtranBin = $jpegtranBin; + } + + public function setOptimize($optimize) + { + $this->optimize = $optimize; + } + + public function setCopy($copy) + { + $this->copy = $copy; + } + + public function setProgressive($progressive) + { + $this->progressive = $progressive; + } + + public function setRestart($restart) + { + $this->restart = $restart; + } + + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $pb = new ProcessBuilder(array($this->jpegtranBin)); + + if ($this->optimize) { + $pb->add('-optimize'); + } + + if ($this->copy) { + $pb->add('-copy')->add($this->copy); + } + + if ($this->progressive) { + $pb->add('-progressive'); + } + + if (null !== $this->restart) { + $pb->add('-restart')->add($this->restart); + } + + $pb->add($input = tempnam(sys_get_temp_dir(), 'assetic_jpegtran')); + file_put_contents($input, $asset->getContent()); + + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($input); + + if (0 < $code) { + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent($proc->getOutput()); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/LessFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/LessFilter.php new file mode 100644 index 0000000..cd7e32c --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/LessFilter.php @@ -0,0 +1,114 @@ + + */ +class LessFilter implements FilterInterface +{ + private $nodeBin; + private $nodePaths; + private $compress; + + /** + * Constructor. + * + * @param string $nodeBin The path to the node binary + * @param array $nodePaths An array of node paths + */ + public function __construct($nodeBin = '/usr/bin/node', array $nodePaths = array()) + { + $this->nodeBin = $nodeBin; + $this->nodePaths = $nodePaths; + } + + public function setCompress($compress) + { + $this->compress = $compress; + } + + public function filterLoad(AssetInterface $asset) + { + static $format = <<<'EOF' +var less = require('less'); +var sys = require(process.binding('natives').util ? 'util' : 'sys'); + +new(less.Parser)(%s).parse(%s, function(e, tree) { + if (e) { + less.writeError(e); + process.exit(2); + } + + try { + sys.print(tree.toCSS(%s)); + } catch (e) { + less.writeError(e); + process.exit(3); + } +}); + +EOF; + + $root = $asset->getSourceRoot(); + $path = $asset->getSourcePath(); + + // parser options + $parserOptions = array(); + if ($root && $path) { + $parserOptions['paths'] = array(dirname($root.'/'.$path)); + $parserOptions['filename'] = basename($path); + } + + // tree options + $treeOptions = array(); + if (null !== $this->compress) { + $treeOptions['compress'] = $this->compress; + } + + $pb = new ProcessBuilder(); + $pb->inheritEnvironmentVariables(); + + // node.js configuration + if (0 < count($this->nodePaths)) { + $pb->setEnv('NODE_PATH', implode(':', $this->nodePaths)); + } + + $pb->add($this->nodeBin)->add($input = tempnam(sys_get_temp_dir(), 'assetic_less')); + file_put_contents($input, sprintf($format, + json_encode($parserOptions), + json_encode($asset->getContent()), + json_encode($treeOptions) + )); + + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($input); + + if (0 < $code) { + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent($proc->getOutput()); + } + + public function filterDump(AssetInterface $asset) + { + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/LessphpFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/LessphpFilter.php new file mode 100644 index 0000000..590f041 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/LessphpFilter.php @@ -0,0 +1,51 @@ + + * @author Kris Wallsmith + */ +class LessphpFilter implements FilterInterface +{ + private $presets = array(); + + public function setPresets(array $presets) + { + $this->presets = $presets; + } + + public function filterLoad(AssetInterface $asset) + { + $root = $asset->getSourceRoot(); + $path = $asset->getSourcePath(); + + $lc = new \lessc(); + if ($root && $path) { + $lc->importDir = dirname($root.'/'.$path); + } + + $asset->setContent($lc->parse($asset->getContent(), $this->presets)); + } + + public function filterDump(AssetInterface $asset) + { + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/OptiPngFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/OptiPngFilter.php new file mode 100644 index 0000000..19da807 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/OptiPngFilter.php @@ -0,0 +1,75 @@ + + */ +class OptiPngFilter implements FilterInterface +{ + private $optipngBin; + private $level; + + /** + * Constructor. + * + * @param string $optipngBin Path to the optipng binary + */ + public function __construct($optipngBin = '/usr/bin/optipng') + { + $this->optipngBin = $optipngBin; + } + + public function setLevel($level) + { + $this->level = $level; + } + + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $pb = new ProcessBuilder(array($this->optipngBin)); + + if (null !== $this->level) { + $pb->add('-o')->add($this->level); + } + + $pb->add('-out')->add($output = tempnam(sys_get_temp_dir(), 'assetic_optipng')); + unlink($output); + + $pb->add($input = tempnam(sys_get_temp_dir(), 'assetic_optipng')); + file_put_contents($input, $asset->getContent()); + + $proc = $pb->getProcess(); + $code = $proc->run(); + + if (0 < $code) { + unlink($input); + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent(file_get_contents($output)); + + unlink($input); + unlink($output); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/PackagerFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/PackagerFilter.php new file mode 100644 index 0000000..c3a331b --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/PackagerFilter.php @@ -0,0 +1,64 @@ + + */ +class PackagerFilter implements FilterInterface +{ + private $packages; + + public function __construct(array $packages = array()) + { + $this->packages = $packages; + } + + public function addPackage($package) + { + $this->packages[] = $package; + } + + public function filterLoad(AssetInterface $asset) + { + static $manifest = <<getContent()); + + $packager = new \Packager(array_merge(array($package), $this->packages)); + $content = $packager->build(array(), array(), array('Application'.$hash)); + + unlink($package.'/package.yml'); + unlink($package.'/source.js'); + rmdir($package); + + $asset->setContent($content); + } + + public function filterDump(AssetInterface $asset) + { + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/PackerFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/PackerFilter.php new file mode 100644 index 0000000..5d6640b --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/PackerFilter.php @@ -0,0 +1,56 @@ + + */ +class PackerFilter implements FilterInterface +{ + protected $encoding = 'None'; + + protected $fastDecode = true; + + protected $specialChars = false; + + public function setEncoding($encoding) + { + $this->encoding = $encoding; + } + + public function setFastDecode($fastDecode) + { + $this->fastDecode = (bool) $fastDecode; + } + + public function setSpecialChars($specialChars) + { + $this->specialChars = (bool) $specialChars; + } + + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $packer = new \JavaScriptPacker($asset->getContent(), $this->encoding, $this->fastDecode, $this->specialChars); + $asset->setContent($packer->pack()); + } +} \ No newline at end of file diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/PngoutFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/PngoutFilter.php new file mode 100644 index 0000000..8e5169a --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/PngoutFilter.php @@ -0,0 +1,128 @@ + + */ +class PngoutFilter implements FilterInterface +{ + // -c# + const COLOR_GREY = '0'; + const COLOR_RGB = '2'; + const COLOR_PAL = '3'; + const COLOR_GRAY_ALPHA = '4'; + const COLOR_RGB_ALPHA = '6'; + + // -f# + const FILTER_NONE = '0'; + const FILTER_X = '1'; + const FILTER_Y = '2'; + const FILTER_X_Y = '3'; + const FILTER_PAETH = '4'; + const FILTER_MIXED = '5'; + + // -s# + const STRATEGY_XTREME = '0'; + const STRATEGY_INTENSE = '1'; + const STRATEGY_LONGEST_MATCH = '2'; + const STRATEGY_HUFFMAN_ONLY = '3'; + const STRATEGY_UNCOMPRESSED = '4'; + + private $pngoutBin; + private $color; + private $filter; + private $strategy; + private $blockSplitThreshold; + + /** + * Constructor. + * + * @param string $pngoutBin Path to the pngout binary + */ + public function __construct($pngoutBin = '/usr/bin/pngout') + { + $this->pngoutBin = $pngoutBin; + } + + public function setColor($color) + { + $this->color = $color; + } + + public function setFilter($filter) + { + $this->filter = $filter; + } + + public function setStrategy($strategy) + { + $this->strategy = $strategy; + } + + public function setBlockSplitThreshold($blockSplitThreshold) + { + $this->blockSplitThreshold = $blockSplitThreshold; + } + + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $pb = new ProcessBuilder(array($this->pngoutBin)); + + if (null !== $this->color) { + $pb->add('-c'.$this->color); + } + + if (null !== $this->filter) { + $pb->add('-f'.$this->filter); + } + + if (null !== $this->strategy) { + $pb->add('-s'.$this->strategy); + } + + if (null !== $this->blockSplitThreshold) { + $pb->add('-b'.$this->blockSplitThreshold); + } + + $pb->add($input = tempnam(sys_get_temp_dir(), 'assetic_pngout')); + file_put_contents($input, $asset->getContent()); + + $output = tempnam(sys_get_temp_dir(), 'assetic_pngout'); + unlink($output); + $pb->add($output .= '.png'); + + $proc = $pb->getProcess(); + $code = $proc->run(); + + if (0 < $code) { + unlink($input); + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent(file_get_contents($output)); + + unlink($input); + unlink($output); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/SassFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/SassFilter.php new file mode 100644 index 0000000..5a73726 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/SassFilter.php @@ -0,0 +1,169 @@ + + */ +class SassFilter implements FilterInterface +{ + const STYLE_NESTED = 'nested'; + const STYLE_EXPANDED = 'expanded'; + const STYLE_COMPACT = 'compact'; + const STYLE_COMPRESSED = 'compressed'; + + private $sassPath; + private $unixNewlines; + private $scss; + private $style; + private $quiet; + private $debugInfo; + private $lineNumbers; + private $loadPaths = array(); + private $cacheLocation; + private $noCache; + private $compass; + + public function __construct($sassPath = '/usr/bin/sass') + { + $this->sassPath = $sassPath; + $this->cacheLocation = realpath(sys_get_temp_dir()); + } + + public function setUnixNewlines($unixNewlines) + { + $this->unixNewlines = $unixNewlines; + } + + public function setScss($scss) + { + $this->scss = $scss; + } + + public function setStyle($style) + { + $this->style = $style; + } + + public function setQuiet($quiet) + { + $this->quiet = $quiet; + } + + public function setDebugInfo($debugInfo) + { + $this->debugInfo = $debugInfo; + } + + public function setLineNumbers($lineNumbers) + { + $this->lineNumbers = $lineNumbers; + } + + public function addLoadPath($loadPath) + { + $this->loadPaths[] = $loadPath; + } + + public function setCacheLocation($cacheLocation) + { + $this->cacheLocation = $cacheLocation; + } + + public function setNoCache($noCache) + { + $this->noCache = $noCache; + } + + public function setCompass($compass) + { + $this->compass = $compass; + } + + public function filterLoad(AssetInterface $asset) + { + $pb = new ProcessBuilder(array($this->sassPath)); + + $root = $asset->getSourceRoot(); + $path = $asset->getSourcePath(); + + if ($root && $path) { + $pb->add('--load-path')->add(dirname($root.'/'.$path)); + } + + if ($this->unixNewlines) { + $pb->add('--unix-newlines'); + } + + if (true === $this->scss || (null === $this->scss && 'scss' == pathinfo($path, PATHINFO_EXTENSION))) { + $pb->add('--scss'); + } + + if ($this->style) { + $pb->add('--style')->add($this->style); + } + + if ($this->quiet) { + $pb->add('--quiet'); + } + + if ($this->debugInfo) { + $pb->add('--debug-info'); + } + + if ($this->lineNumbers) { + $pb->add('--line-numbers'); + } + + foreach ($this->loadPaths as $loadPath) { + $pb->add('--load-path')->add($loadPath); + } + + if ($this->cacheLocation) { + $pb->add('--cache-location')->add($this->cacheLocation); + } + + if ($this->noCache) { + $pb->add('--no-cache'); + } + + if ($this->compass) { + $pb->add('--compass'); + } + + // input + $pb->add($input = tempnam(sys_get_temp_dir(), 'assetic_sass')); + file_put_contents($input, $asset->getContent()); + + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($input); + + if (0 < $code) { + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent($proc->getOutput()); + } + + public function filterDump(AssetInterface $asset) + { + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/ScssFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/ScssFilter.php new file mode 100644 index 0000000..6044b84 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/ScssFilter.php @@ -0,0 +1,28 @@ + + */ +class ScssFilter extends SassFilter +{ + public function __construct($sassPath = '/usr/bin/sass') + { + parent::__construct($sassPath); + + $this->setScss(true); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/SprocketsFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/SprocketsFilter.php new file mode 100644 index 0000000..29bc71c --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/SprocketsFilter.php @@ -0,0 +1,148 @@ + + */ +class SprocketsFilter implements FilterInterface +{ + private $sprocketsLib; + private $rubyBin; + private $includeDirs; + private $assetRoot; + + /** + * Constructor. + * + * @param string $sprocketsLib Path to the Sprockets lib/ directory + * @param string $rubyBin Path to the ruby binary + */ + public function __construct($sprocketsLib = null, $rubyBin = '/usr/bin/ruby') + { + $this->sprocketsLib = $sprocketsLib; + $this->rubyBin = $rubyBin; + $this->includeDirs = array(); + } + + public function addIncludeDir($directory) + { + $this->includeDirs[] = $directory; + } + + public function setAssetRoot($assetRoot) + { + $this->assetRoot = $assetRoot; + } + + /** + * Hack around a bit, get the job done. + */ + public function filterLoad(AssetInterface $asset) + { + static $format = <<<'EOF' +#!/usr/bin/env ruby + +require %s +%s +options = { :load_path => [], + :source_files => [%s], + :expand_paths => false } + +%ssecretary = Sprockets::Secretary.new(options) +secretary.install_assets if options[:asset_root] +print secretary.concatenation + +EOF; + + $more = ''; + + foreach ($this->includeDirs as $directory) { + $more .= 'options[:load_path] << '.var_export($directory, true)."\n"; + } + + if (null !== $this->assetRoot) { + $more .= 'options[:asset_root] = '.var_export($this->assetRoot, true)."\n"; + } + + if ($more) { + $more .= "\n"; + } + + $tmpAsset = tempnam(sys_get_temp_dir(), 'assetic_sprockets'); + file_put_contents($tmpAsset, $asset->getContent()); + + $input = tempnam(sys_get_temp_dir(), 'assetic_sprockets'); + file_put_contents($input, sprintf($format, + $this->sprocketsLib + ? sprintf('File.join(%s, \'sprockets\')', var_export($this->sprocketsLib, true)) + : '\'sprockets\'', + $this->getHack($asset), + var_export($tmpAsset, true), + $more + )); + + $pb = new ProcessBuilder(array( + $this->rubyBin, + $input, + )); + + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($tmpAsset); + unlink($input); + + if (0 < $code) { + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent($proc->getOutput()); + } + + public function filterDump(AssetInterface $asset) + { + } + + private function getHack(AssetInterface $asset) + { + static $format = <<<'EOF' + +module Sprockets + class Preprocessor + protected + def pathname_for_relative_require_from(source_line) + Sprockets::Pathname.new(@environment, File.join(%s, location_from(source_line))) + end + end +end + +EOF; + + $root = $asset->getSourceRoot(); + $path = $asset->getSourcePath(); + + if ($root && $path) { + return sprintf($format, var_export(dirname($root.'/'.$path), true)); + } + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/StylusFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/StylusFilter.php new file mode 100644 index 0000000..1ecc958 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/StylusFilter.php @@ -0,0 +1,117 @@ + + */ +class StylusFilter implements FilterInterface +{ + private $nodeBin; + private $nodePaths; + private $compress; + + /** + * Constructs filter. + * + * @param string $nodeBin The path to the node binary + * @param array $nodePaths An array of node paths + */ + public function __construct($nodeBin = '/usr/bin/node', array $nodePaths = array()) + { + $this->nodeBin = $nodeBin; + $this->nodePaths = $nodePaths; + } + + /** + * Enable output compression. + * + * @param boolean $compress + */ + public function setCompress($compress) + { + $this->compress = $compress; + } + + /** + * {@inheritdoc} + */ + public function filterLoad(AssetInterface $asset) + { + static $format = <<<'EOF' +var stylus = require('stylus'); +var sys = require(process.binding('natives').util ? 'util' : 'sys'); + +stylus(%s, %s).render(function(e, css){ + if (e) { + throw e; + } + + sys.print(css); + process.exit(0); +}); + +EOF; + + $root = $asset->getSourceRoot(); + $path = $asset->getSourcePath(); + + // parser options + $parserOptions = array(); + if ($root && $path) { + $parserOptions['paths'] = array(dirname($root.'/'.$path)); + $parserOptions['filename'] = basename($path); + } + + if (null !== $this->compress) { + $parserOptions['compress'] = $this->compress; + } + + $pb = new ProcessBuilder(); + $pb->inheritEnvironmentVariables(); + + // node.js configuration + if (0 < count($this->nodePaths)) { + $pb->setEnv('NODE_PATH', implode(':', $this->nodePaths)); + } + + $pb->add($this->nodeBin)->add($input = tempnam(sys_get_temp_dir(), 'assetic_stylus')); + file_put_contents($input, sprintf($format, + json_encode($asset->getContent()), + json_encode($parserOptions) + )); + + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($input); + + if (0 < $code) { + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent($proc->getOutput()); + } + + /** + * {@inheritdoc} + */ + public function filterDump(AssetInterface $asset) + { + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/UglifyJsFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/UglifyJsFilter.php new file mode 100644 index 0000000..c84841a --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/UglifyJsFilter.php @@ -0,0 +1,136 @@ + + */ +class UglifyJsFilter implements FilterInterface +{ + private $uglifyJsPath; + private $nodeJsPath; + + private $noCopyright; + private $beautify; + private $unsafe; + + /** + * @param string $uglifyJsPath Absolute path to the uglifyjs executable + * @param string $nodeJsPath Absolute path to the folder containg node.js executable + */ + public function __construct($uglifyJsPath, $nodeJsPath = null) + { + $this->uglifyJsPath = $uglifyJsPath; + $this->nodeJsPath = $nodeJsPath; + } + + /** + * Removes the first block of comments as well + * @param bool $noCopyright True to enable + */ + public function setNoCopyright($noCopyright) + { + $this->noCopyright = $noCopyright; + } + + /** + * Output indented code + * @param bool $beautify True to enable + */ + public function setBeautify($beautify) + { + $this->beautify = $beautify; + } + + /** + * Enable additional optimizations that are known to be unsafe in some situations. + * @param bool $unsafe True to enable + */ + public function setUnsafe($unsafe) + { + $this->unsafe = $unsafe; + } + + /** + * @see Assetic\Filter\FilterInterface::filterLoad() + */ + public function filterLoad(AssetInterface $asset) + { + } + + /** + * Run the asset through UglifyJs + * + * @see Assetic\Filter\FilterInterface::filterDump() + */ + public function filterDump(AssetInterface $asset) + { + $executables = array(); + + if ($this->nodeJsPath !== null) { + $executables[] = $this->nodeJsPath; + } + + $executables[] = $this->uglifyJsPath; + + $pb = new ProcessBuilder($executables); + + if ($this->noCopyright) { + $pb->add('--no-copyright'); + } + + if ($this->beautify) { + $pb->add('--beautify'); + } + + if ($this->unsafe) { + $pb->add('--unsafe'); + } + + // input and output files + $input = tempnam(sys_get_temp_dir(), 'input'); + $output = tempnam(sys_get_temp_dir(), 'output'); + + file_put_contents($input, $asset->getContent()); + $pb->add('-o')->add($output)->add($input); + + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($input); + + if (0 < $code) { + if (file_exists($output)) { + unlink($output); + } + + if (127 === $code) { + throw new \RuntimeException('Path to node executable could not be resolved.'); + } + + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } elseif (!file_exists($output)) { + throw new \RuntimeException('Error creating output file.'); + } + + $uglifiedJs = file_get_contents($output); + unlink($output); + + $asset->setContent($uglifiedJs); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/BaseCompressorFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/BaseCompressorFilter.php new file mode 100644 index 0000000..3d541d8 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/BaseCompressorFilter.php @@ -0,0 +1,108 @@ + + */ +abstract class BaseCompressorFilter implements FilterInterface +{ + private $jarPath; + private $javaPath; + private $charset; + private $lineBreak; + + public function __construct($jarPath, $javaPath = '/usr/bin/java') + { + $this->jarPath = $jarPath; + $this->javaPath = $javaPath; + } + + public function setCharset($charset) + { + $this->charset = $charset; + } + + public function setLineBreak($lineBreak) + { + $this->lineBreak = $lineBreak; + } + + public function filterLoad(AssetInterface $asset) + { + } + + /** + * Compresses a string. + * + * @param string $content The content to compress + * @param string $type The type of content, either "js" or "css" + * @param array $options An indexed array of additional options + * + * @return string The compressed content + */ + protected function compress($content, $type, $options = array()) + { + $pb = new ProcessBuilder(array( + $this->javaPath, + '-jar', + $this->jarPath, + )); + + foreach ($options as $option) { + $pb->add($option); + } + + if (null !== $this->charset) { + $pb->add('--charset')->add($this->charset); + } + + if (null !== $this->lineBreak) { + $pb->add('--line-break')->add($this->lineBreak); + } + + // input and output files + $tempDir = realpath(sys_get_temp_dir()); + $hash = substr(sha1(time().rand(11111, 99999)), 0, 7); + $input = $tempDir.DIRECTORY_SEPARATOR.$hash.'.'.$type; + $output = $tempDir.DIRECTORY_SEPARATOR.$hash.'-min.'.$type; + file_put_contents($input, $content); + $pb->add('-o')->add($output)->add($input); + + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($input); + + if (0 < $code) { + if (file_exists($output)) { + unlink($output); + } + + throw FilterException::fromProcess($proc)->setInput($content); + } elseif (!file_exists($output)) { + throw new \RuntimeException('Error creating output file.'); + } + + $retval = file_get_contents($output); + unlink($output); + + return $retval; + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/CssCompressorFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/CssCompressorFilter.php new file mode 100644 index 0000000..26f7646 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/CssCompressorFilter.php @@ -0,0 +1,28 @@ + + */ +class CssCompressorFilter extends BaseCompressorFilter +{ + public function filterDump(AssetInterface $asset) + { + $asset->setContent($this->compress($asset->getContent(), 'css')); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/JsCompressorFilter.php b/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/JsCompressorFilter.php new file mode 100644 index 0000000..db48cf5 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/JsCompressorFilter.php @@ -0,0 +1,61 @@ + + */ +class JsCompressorFilter extends BaseCompressorFilter +{ + private $nomunge; + private $preserveSemi; + private $disableOptimizations; + + public function setNomunge($nomunge = true) + { + $this->nomunge = $nomunge; + } + + public function setPreserveSemi($preserveSemi) + { + $this->preserveSemi = $preserveSemi; + } + + public function setDisableOptimizations($disableOptimizations) + { + $this->disableOptimizations = $disableOptimizations; + } + + public function filterDump(AssetInterface $asset) + { + $options = array(); + + if ($this->nomunge) { + $options[] = '--nomunge'; + } + + if ($this->preserveSemi) { + $options[] = '--preserve-semi'; + } + + if ($this->disableOptimizations) { + $options[] = '--disable-optimizations'; + } + + $asset->setContent($this->compress($asset->getContent(), 'js', $options)); + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/FilterManager.php b/vendor/kriswallsmith/assetic/src/Assetic/FilterManager.php new file mode 100644 index 0000000..ddf6cac --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/FilterManager.php @@ -0,0 +1,64 @@ + + */ +class FilterManager +{ + private $filters = array(); + + public function set($alias, FilterInterface $filter) + { + $this->checkName($alias); + + $this->filters[$alias] = $filter; + } + + public function get($alias) + { + if (!isset($this->filters[$alias])) { + throw new \InvalidArgumentException(sprintf('There is no "%s" filter.', $alias)); + } + + return $this->filters[$alias]; + } + + public function has($alias) + { + return isset($this->filters[$alias]); + } + + public function getNames() + { + return array_keys($this->filters); + } + + /** + * Checks that a name is valid. + * + * @param string $name An asset name candidate + * + * @throws InvalidArgumentException If the asset name is invalid + */ + protected function checkName($name) + { + if (!ctype_alnum(str_replace('_', '', $name))) { + throw new \InvalidArgumentException(sprintf('The name "%s" is invalid.', $name)); + } + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Util/PathUtils.php b/vendor/kriswallsmith/assetic/src/Assetic/Util/PathUtils.php new file mode 100644 index 0000000..244d1a7 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Util/PathUtils.php @@ -0,0 +1,31 @@ + + */ +abstract class PathUtils +{ + public static function resolvePath($path, array $vars, array $values) + { + $map = array(); + foreach ($vars as $var) { + if (false === strpos($path, '{'.$var.'}')) { + continue; + } + + if (!isset($values[$var])) { + throw new \InvalidArgumentException(sprintf('The path "%s" contains the variable "%s", but was not given any value for it.', $path, $var)); + } + + $map['{'.$var.'}'] = $values[$var]; + } + + return strtr($path, $map); + } + + private final function __construct() { } +} \ No newline at end of file diff --git a/vendor/kriswallsmith/assetic/src/Assetic/Util/TraversableString.php b/vendor/kriswallsmith/assetic/src/Assetic/Util/TraversableString.php new file mode 100644 index 0000000..9f1a633 --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/Util/TraversableString.php @@ -0,0 +1,44 @@ + + */ +class TraversableString implements \IteratorAggregate, \Countable +{ + private $one; + private $many; + + public function __construct($one, array $many) + { + $this->one = $one; + $this->many = $many; + } + + public function getIterator() + { + return new \ArrayIterator($this->many); + } + + public function count() + { + return count($this->many); + } + + public function __toString() + { + return (string) $this->one; + } +} diff --git a/vendor/kriswallsmith/assetic/src/Assetic/ValueSupplierInterface.php b/vendor/kriswallsmith/assetic/src/Assetic/ValueSupplierInterface.php new file mode 100644 index 0000000..ee87b9b --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/Assetic/ValueSupplierInterface.php @@ -0,0 +1,29 @@ + + */ +interface ValueSupplierInterface +{ + /** + * Returns a map of values. + * + * @return array + */ + function getValues(); +} \ No newline at end of file diff --git a/vendor/kriswallsmith/assetic/src/functions.php b/vendor/kriswallsmith/assetic/src/functions.php new file mode 100644 index 0000000..264589e --- /dev/null +++ b/vendor/kriswallsmith/assetic/src/functions.php @@ -0,0 +1,121 @@ +factory = $factory; +} + +/** + * Returns an array of javascript URLs. + * + * @param array|string $inputs Input strings + * @param array|string $filters Filter names + * @param array $options An array of options + * + * @return array An array of javascript URLs + */ +function assetic_javascripts($inputs = array(), $filters = array(), array $options = array()) +{ + if (!isset($options['output'])) { + $options['output'] = 'js/*.js'; + } + + return _assetic_urls($inputs, $filters, $options); +} + +/** + * Returns an array of stylesheet URLs. + * + * @param array|string $inputs Input strings + * @param array|string $filters Filter names + * @param array $options An array of options + * + * @return array An array of stylesheet URLs + */ +function assetic_stylesheets($inputs = array(), $filters = array(), array $options = array()) +{ + if (!isset($options['output'])) { + $options['output'] = 'css/*.css'; + } + + return _assetic_urls($inputs, $filters, $options); +} + +/** + * Returns an image URL. + * + * @param string $input An input + * @param array|string $filters Filter names + * @param array $options An array of options + * + * @return string An image URL + */ +function assetic_image($input, $filters = array(), array $options = array()) +{ + if (!isset($options['output'])) { + $options['output'] = 'images/*'; + } + + $urls = _assetic_urls($input, $filters, $options); + + return current($urls); +} + +/** + * Returns an array of asset urls. + * + * @param array|string $inputs Input strings + * @param array|string $filters Filter names + * @param array $options An array of options + * + * @return array An array of URLs + */ +function _assetic_urls($inputs = array(), $filters = array(), array $options = array()) +{ + global $_assetic; + + if (!is_array($inputs)) { + $inputs = array_filter(array_map('trim', explode(',', $inputs))); + } + + if (!is_array($filters)) { + $filters = array_filter(array_map('trim', explode(',', $filters))); + } + + $coll = $_assetic->factory->createAsset($inputs, $filters, $options); + + $debug = isset($options['debug']) ? $options['debug'] : $_assetic->factory->isDebug(); + $combine = isset($options['combine']) ? $options['combine'] : !$debug; + + $one = $coll->getTargetPath(); + if ($combine) { + $many = array(); + foreach ($coll as $leaf) { + $many[] = $leaf->getTargetPath(); + } + } else { + $many = array($one); + } + + return new TraversableString($one, $many); +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/AssetCacheTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/AssetCacheTest.php new file mode 100644 index 0000000..9484f2a --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/AssetCacheTest.php @@ -0,0 +1,175 @@ +inner = $this->getMock('Assetic\\Asset\\AssetInterface'); + $this->cache = $this->getMock('Assetic\\Cache\\CacheInterface'); + + $this->asset = new AssetCache($this->inner, $this->cache); + } + + public function testLoadFromCache() + { + $content = 'asdf'; + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + + $this->inner->expects($this->once()) + ->method('getFilters') + ->will($this->returnValue(array($filter))); + $this->cache->expects($this->once()) + ->method('has') + ->with($this->isType('string')) + ->will($this->returnValue(true)); + $this->cache->expects($this->once()) + ->method('get') + ->with($this->isType('string')) + ->will($this->returnValue($content)); + $this->inner->expects($this->once()) + ->method('setContent') + ->with($content); + + $this->asset->load($filter); + } + + public function testLoadToCache() + { + $content = 'asdf'; + + $this->inner->expects($this->once()) + ->method('getFilters') + ->will($this->returnValue(array())); + $this->cache->expects($this->once()) + ->method('has') + ->with($this->isType('string')) + ->will($this->returnValue(false)); + $this->inner->expects($this->once())->method('load'); + $this->inner->expects($this->once()) + ->method('getContent') + ->will($this->returnValue($content)); + $this->cache->expects($this->once()) + ->method('set') + ->with($this->isType('string'), $content); + + $this->asset->load(); + } + + public function testDumpFromCache() + { + $content = 'asdf'; + + $this->inner->expects($this->once()) + ->method('getFilters') + ->will($this->returnValue(array())); + $this->cache->expects($this->once()) + ->method('has') + ->with($this->isType('string')) + ->will($this->returnValue(true)); + $this->cache->expects($this->once()) + ->method('get') + ->with($this->isType('string')) + ->will($this->returnValue($content)); + + $this->assertEquals($content, $this->asset->dump(), '->dump() returns the cached value'); + } + + public function testDumpToCache() + { + $content = 'asdf'; + + $this->inner->expects($this->once()) + ->method('getFilters') + ->will($this->returnValue(array())); + $this->cache->expects($this->once()) + ->method('has') + ->with($this->isType('string')) + ->will($this->returnValue(false)); + $this->inner->expects($this->once()) + ->method('dump') + ->will($this->returnValue($content)); + $this->cache->expects($this->once()) + ->method('set') + ->with($this->isType('string'), $content); + + $this->assertEquals($content, $this->asset->dump(), '->dump() returns the dumped value'); + } + + public function testEnsureFilter() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $this->inner->expects($this->once())->method('ensureFilter'); + $this->asset->ensureFilter($filter); + } + + public function testGetFilters() + { + $this->inner->expects($this->once()) + ->method('getFilters') + ->will($this->returnValue(array())); + + $this->assertInternalType('array', $this->asset->getFilters(), '->getFilters() returns the inner asset filters'); + } + + public function testGetContent() + { + $this->inner->expects($this->once()) + ->method('getContent') + ->will($this->returnValue('asdf')); + + $this->assertEquals('asdf', $this->asset->getContent(), '->getContent() returns the inner asset content'); + } + + public function testSetContent() + { + $this->inner->expects($this->once()) + ->method('setContent') + ->with('asdf'); + + $this->asset->setContent('asdf'); + } + + public function testGetSourceRoot() + { + $this->inner->expects($this->once()) + ->method('getSourceRoot') + ->will($this->returnValue('asdf')); + + $this->assertEquals('asdf', $this->asset->getSourceRoot(), '->getSourceRoot() returns the inner asset source root'); + } + + public function testGetSourcePath() + { + $this->inner->expects($this->once()) + ->method('getSourcePath') + ->will($this->returnValue('asdf')); + + $this->assertEquals('asdf', $this->asset->getSourcePath(), '->getSourcePath() returns the inner asset source path'); + } + + public function testGetLastModified() + { + $this->inner->expects($this->once()) + ->method('getLastModified') + ->will($this->returnValue(123)); + + $this->assertEquals(123, $this->asset->getLastModified(), '->getLastModified() returns the inner asset last modified'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/AssetCollectionTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/AssetCollectionTest.php new file mode 100644 index 0000000..9dd095f --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/AssetCollectionTest.php @@ -0,0 +1,318 @@ +assertInstanceOf('Assetic\\Asset\\AssetInterface', $coll, 'AssetCollection implements AssetInterface'); + } + + public function testLoadFilter() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $filter->expects($this->once())->method('filterLoad'); + + $coll = new AssetCollection(array(new StringAsset('')), array($filter)); + $coll->load(); + } + + public function testDumpFilter() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $filter->expects($this->once())->method('filterDump'); + + $coll = new AssetCollection(array(new StringAsset('')), array($filter)); + $coll->dump(); + } + + public function testNestedCollectionLoad() + { + $content = 'foobar'; + + $count = 0; + $matches = array(); + $filter = new CallablesFilter(function($asset) use ($content, & $matches, & $count) + { + ++$count; + if ($content == $asset->getContent()) { + $matches[] = $asset; + } + }); + + $innerColl = new AssetCollection(array(new StringAsset($content))); + $outerColl = new AssetCollection(array($innerColl), array($filter)); + $outerColl->load(); + + $this->assertEquals(1, count($matches), '->load() applies filters to leaves'); + $this->assertEquals(1, $count, '->load() applies filters to leaves only'); + } + + public function testMixedIteration() + { + $asset = new StringAsset('asset'); + $nestedAsset = new StringAsset('nested'); + $innerColl = new AssetCollection(array($nestedAsset)); + + $contents = array(); + $filter = new CallablesFilter(function($asset) use(& $contents) + { + $contents[] = $asset->getContent(); + }); + + $coll = new AssetCollection(array($asset, $innerColl), array($filter)); + $coll->load(); + + $this->assertEquals(array('asset', 'nested'), $contents, '->load() iterates over multiple levels'); + } + + public function testLoadDedupBySourceUrl() + { + $asset1 = new StringAsset('asset', array(), '/some/dir', 'foo.bar'); + $asset2 = new StringAsset('asset', array(), '/some/dir', 'foo.bar'); + + $coll = new AssetCollection(array($asset1, $asset2)); + $coll->load(); + + $this->assertEquals('asset', $coll->getContent(), '->load() detects duplicate assets based on source URL'); + } + + public function testLoadDedupByStrictEquality() + { + $asset = new StringAsset('foo'); + + $coll = new AssetCollection(array($asset, $asset)); + $coll->load(); + + $this->assertEquals('foo', $coll->getContent(), '->load() detects duplicate assets based on strict equality'); + } + + public function testDumpDedupBySourceUrl() + { + $asset1 = new StringAsset('asset', array(), '/some/dir', 'foo.bar'); + $asset2 = new StringAsset('asset', array(), '/some/dir', 'foo.bar'); + + $coll = new AssetCollection(array($asset1, $asset2)); + $coll->load(); + + $this->assertEquals('asset', $coll->dump(), '->dump() detects duplicate assets based on source URL'); + } + + public function testDumpDedupByStrictEquality() + { + $asset = new StringAsset('foo'); + + $coll = new AssetCollection(array($asset, $asset)); + $coll->load(); + + $this->assertEquals('foo', $coll->dump(), '->dump() detects duplicate assets based on strict equality'); + } + + public function testIterationFilters() + { + $count = 0; + $filter = new CallablesFilter(function() use(&$count) { ++$count; }); + + $coll = new AssetCollection(); + $coll->add(new StringAsset('')); + $coll->ensureFilter($filter); + + foreach ($coll as $asset) { + $asset->dump(); + } + + $this->assertEquals(1, $count, 'collection filters are called when child assets are iterated over'); + } + + public function testSetContent() + { + $coll = new AssetCollection(); + $coll->setContent('asdf'); + + $this->assertEquals('asdf', $coll->getContent(), '->setContent() sets the content'); + } + + /** + * @dataProvider getTimestampsAndExpected + */ + public function testGetLastModified($timestamps, $expected) + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + for ($i = 0; $i < count($timestamps); $i++) { + $asset->expects($this->at($i)) + ->method('getLastModified') + ->will($this->returnValue($timestamps[$i])); + } + + $coll = new AssetCollection(array_fill(0, count($timestamps), $asset)); + + $this->assertEquals($expected, $coll->getLastModified(), '->getLastModifed() returns the highest last modified'); + } + + public function getTimestampsAndExpected() + { + return array( + array(array(1, 2, 3), 3), + array(array(5, 4, 3), 5), + array(array(3, 8, 5), 8), + array(array(3, 8, null), 8), + ); + } + + public function testRecursiveIteration() + { + $asset1 = $this->getMock('Assetic\\Asset\\AssetInterface'); + $asset2 = $this->getMock('Assetic\\Asset\\AssetInterface'); + $asset3 = $this->getMock('Assetic\\Asset\\AssetInterface'); + $asset4 = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $coll3 = new AssetCollection(array($asset1, $asset2)); + $coll2 = new AssetCollection(array($asset3, $coll3)); + $coll1 = new AssetCollection(array($asset4, $coll2)); + + $i = 0; + foreach ($coll1 as $a) { + $i++; + } + + $this->assertEquals(4, $i, 'iteration with a recursive iterator is recursive'); + } + + public function testRecursiveDeduplication() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $coll3 = new AssetCollection(array($asset, $asset)); + $coll2 = new AssetCollection(array($asset, $coll3)); + $coll1 = new AssetCollection(array($asset, $coll2)); + + $i = 0; + foreach ($coll1 as $a) { + $i++; + } + + $this->assertEquals(1, $i, 'deduplication is performed recursively'); + } + + public function testIteration() + { + $asset1 = new StringAsset('asset1', array(), '/some/dir', 'foo.css'); + $asset2 = new StringAsset('asset2', array(), '/some/dir', 'foo.css'); + $asset3 = new StringAsset('asset3', array(), '/some/dir', 'bar.css'); + + $coll = new AssetCollection(array($asset1, $asset2, $asset3)); + + $count = 0; + foreach ($coll as $a) { + ++$count; + } + + $this->assertEquals(2, $count, 'iterator filters duplicates based on url'); + } + + public function testBasenameCollision() + { + $asset1 = new StringAsset('asset1', array(), '/some/dir', 'foo/foo.css'); + $asset2 = new StringAsset('asset2', array(), '/some/dir', 'bar/foo.css'); + + $coll = new AssetCollection(array($asset1, $asset2)); + + $urls = array(); + foreach ($coll as $leaf) { + $urls[] = $leaf->getTargetPath(); + } + + $this->assertEquals(2, count(array_unique($urls)), 'iterator prevents basename collisions'); + } + + public function testEmptyMtime() + { + $coll = new AssetCollection(); + $this->assertNull($coll->getLastModified(), '->getLastModified() returns null on empty collection'); + } + + public function testLeafManipulation() + { + $coll = new AssetCollection(array(new StringAsset('asdf'))); + + foreach ($coll as $leaf) { + $leaf->setTargetPath('asdf'); + } + + foreach ($coll as $leaf) { + $this->assertEquals('asdf', $leaf->getTargetPath(), 'leaf changes persist between iterations'); + } + } + + public function testRemoveLeaf() + { + $coll = new AssetCollection(array( + $leaf = new StringAsset('asdf'), + )); + + $this->assertTrue($coll->removeLeaf($leaf)); + } + + public function testRemoveRecursiveLeaf() + { + $coll = new AssetCollection(array( + new AssetCollection(array( + $leaf = new StringAsset('asdf'), + )) + )); + + $this->assertTrue($coll->removeLeaf($leaf)); + } + + public function testRemoveInvalidLeaf() + { + $this->setExpectedException('InvalidArgumentException'); + + $coll = new AssetCollection(); + $coll->removeLeaf(new StringAsset('asdf')); + } + + public function testReplaceLeaf() + { + $coll = new AssetCollection(array( + $leaf = new StringAsset('asdf'), + )); + + $this->assertTrue($coll->replaceLeaf($leaf, new StringAsset('foo'))); + } + + public function testReplaceRecursiveLeaf() + { + $coll = new AssetCollection(array( + new AssetCollection(array( + $leaf = new StringAsset('asdf'), + )), + )); + + $this->assertTrue($coll->replaceLeaf($leaf, new StringAsset('foo'))); + } + + public function testReplaceInvalidLeaf() + { + $this->setExpectedException('InvalidArgumentException'); + + $coll = new AssetCollection(); + $coll->replaceLeaf(new StringAsset('foo'), new StringAsset('bar')); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/AssetReferenceTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/AssetReferenceTest.php new file mode 100644 index 0000000..3a62b77 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/AssetReferenceTest.php @@ -0,0 +1,126 @@ +am = $this->getMock('Assetic\\AssetManager'); + $this->ref = new AssetReference($this->am, 'foo'); + } + + /** + * @dataProvider getMethodAndRetVal + */ + public function testMethods($method, $returnValue) + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $this->am->expects($this->once()) + ->method('get') + ->with('foo') + ->will($this->returnValue($asset)); + $asset->expects($this->once()) + ->method($method) + ->will($this->returnValue($returnValue)); + + $this->assertEquals($returnValue, $this->ref->$method(), '->'.$method.'() returns the asset value'); + } + + public function getMethodAndRetVal() + { + return array( + array('getContent', 'asdf'), + array('getSourceRoot', 'asdf'), + array('getSourcePath', 'asdf'), + array('getTargetPath', 'asdf'), + array('getLastModified', 123), + ); + } + + public function testLazyFilters() + { + $this->am->expects($this->never())->method('get'); + $this->ref->ensureFilter($this->getMock('Assetic\\Filter\\FilterInterface')); + } + + public function testFilterFlush() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $this->am->expects($this->exactly(2)) + ->method('get') + ->with('foo') + ->will($this->returnValue($asset)); + $asset->expects($this->once())->method('ensureFilter'); + $asset->expects($this->once()) + ->method('getFilters') + ->will($this->returnValue(array())); + + $this->ref->ensureFilter($this->getMock('Assetic\\Filter\\FilterInterface')); + + $this->assertInternalType('array', $this->ref->getFilters(), '->getFilters() flushes and returns filters'); + } + + public function testSetContent() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $this->am->expects($this->once()) + ->method('get') + ->with('foo') + ->will($this->returnValue($asset)); + $asset->expects($this->once()) + ->method('setContent') + ->with('asdf'); + + $this->ref->setContent('asdf'); + } + + public function testLoad() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $this->am->expects($this->exactly(2)) + ->method('get') + ->with('foo') + ->will($this->returnValue($asset)); + $asset->expects($this->once()) + ->method('load') + ->with($filter); + + $this->ref->load($filter); + } + + public function testDump() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $this->am->expects($this->exactly(2)) + ->method('get') + ->with('foo') + ->will($this->returnValue($asset)); + $asset->expects($this->once()) + ->method('dump') + ->with($filter); + + $this->ref->dump($filter); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/FileAssetTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/FileAssetTest.php new file mode 100644 index 0000000..c11d4c0 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/FileAssetTest.php @@ -0,0 +1,72 @@ +assertInstanceOf('Assetic\\Asset\\AssetInterface', $asset, 'Asset implements AssetInterface'); + } + + public function testLazyLoading() + { + $asset = new FileAsset(__FILE__); + $this->assertEmpty($asset->getContent(), 'The asset content is empty before load'); + + $asset->load(); + $this->assertNotEmpty($asset->getContent(), 'The asset content is not empty after load'); + } + + public function testGetLastModifiedType() + { + $asset = new FileAsset(__FILE__); + $this->assertInternalType('integer', $asset->getLastModified(), '->getLastModified() returns an integer'); + } + + public function testGetLastModifiedTypeFileNotFound() + { + $asset = new FileAsset(__DIR__ . "/foo/bar/baz.css"); + + $this->setExpectedException("RuntimeException", "The source file"); + $asset->getLastModified(); + } + + public function testGetLastModifiedValue() + { + $asset = new FileAsset(__FILE__); + $this->assertLessThan(time(), $asset->getLastModified(), '->getLastModified() returns the mtime'); + } + + public function testDefaultBaseAndPath() + { + $asset = new FileAsset(__FILE__); + $this->assertEquals(__DIR__, $asset->getSourceRoot(), '->__construct() defaults base to the asset directory'); + $this->assertEquals(basename(__FILE__), $asset->getSourcePath(), '->__construct() defaults path to the asset basename'); + } + + public function testPathGuessing() + { + $asset = new FileAsset(__FILE__, array(), __DIR__); + $this->assertEquals(basename(__FILE__), $asset->getSourcePath(), '->__construct() guesses the asset path'); + } + + public function testInvalidBase() + { + $this->setExpectedException('InvalidArgumentException'); + + $asset = new FileAsset(__FILE__, array(), __DIR__.'/foo'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/GlobAssetTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/GlobAssetTest.php new file mode 100644 index 0000000..e0d7199 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/GlobAssetTest.php @@ -0,0 +1,61 @@ +assertInstanceOf('Assetic\\Asset\\AssetInterface', $asset, 'Asset implements AssetInterface'); + } + + public function testIteration() + { + $assets = new GlobAsset(__DIR__.'/*.php'); + $this->assertGreaterThan(0, iterator_count($assets), 'GlobAsset initializes for iteration'); + } + + public function testRecursiveIteration() + { + $assets = new GlobAsset(__DIR__.'/*.php'); + $this->assertGreaterThan(0, iterator_count($assets), 'GlobAsset initializes for recursive iteration'); + } + + public function testGetLastModifiedType() + { + $assets = new GlobAsset(__DIR__.'/*.php'); + $this->assertInternalType('integer', $assets->getLastModified(), '->getLastModified() returns an integer'); + } + + public function testGetLastModifiedValue() + { + $assets = new GlobAsset(__DIR__.'/*.php'); + $this->assertLessThan(time(), $assets->getLastModified(), '->getLastModified() returns a file mtime'); + } + + public function testLoad() + { + $assets = new GlobAsset(__DIR__.'/*.php'); + $assets->load(); + + $this->assertNotEmpty($assets->getContent(), '->load() loads contents'); + } + + public function testDump() + { + $assets = new GlobAsset(__DIR__.'/*.php'); + $this->assertNotEmpty($assets->dump(), '->dump() dumps contents'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/HttpAssetTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/HttpAssetTest.php new file mode 100644 index 0000000..960492a --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/HttpAssetTest.php @@ -0,0 +1,58 @@ +markTestSkipped('The OpenSSL extension is not loaded.'); + } + + $asset = new HttpAsset(self::JQUERY); + $this->assertInternalType('integer', $asset->getLastModified(), '->getLastModified() returns an integer'); + } + + public function testProtocolRelativeUrl() + { + $asset = new HttpAsset(substr(self::JQUERY, 6)); + $asset->load(); + $this->assertNotEmpty($asset->getContent()); + } + + public function testMalformedUrl() + { + $this->setExpectedException('InvalidArgumentException'); + + new HttpAsset(__FILE__); + } + + public function testInvalidUrl() + { + $this->setExpectedException('RuntimeException'); + + $asset = new HttpAsset('http://invalid.com/foobar'); + $asset->load(); + } + + public function testSourceMetadata() + { + $asset = new HttpAsset(self::JQUERY); + $this->assertEquals('https://ajax.googleapis.com', $asset->getSourceRoot(), '->__construct() set the source root'); + $this->assertEquals('ajax/libs/jquery/1.6.1/jquery.min.js', $asset->getSourcePath(), '->__construct() set the source path'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/StringAssetTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/StringAssetTest.php new file mode 100644 index 0000000..7994a38 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/StringAssetTest.php @@ -0,0 +1,79 @@ +assertInstanceOf('Assetic\\Asset\\AssetInterface', $asset, 'Asset implements AssetInterface'); + } + + public function testLoadAppliesFilters() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $filter->expects($this->once())->method('filterLoad'); + + $asset = new StringAsset('foo', array($filter)); + $asset->load(); + } + + public function testAutomaticLoad() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $filter->expects($this->once())->method('filterLoad'); + + $asset = new StringAsset('foo', array($filter)); + $asset->dump(); + } + + public function testGetFilters() + { + $asset = new StringAsset(''); + $this->assertInternalType('array', $asset->getFilters(), '->getFilters() returns an array'); + } + + public function testLoadAppliesAdditionalFilter() + { + $asset = new StringAsset(''); + $asset->load(); + + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $filter->expects($this->once()) + ->method('filterLoad') + ->with($asset); + + $asset->load($filter); + } + + public function testDumpAppliesAdditionalFilter() + { + $asset = new StringAsset(''); + + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $filter->expects($this->once()) + ->method('filterDump') + ->with($asset); + + $asset->dump($filter); + } + + public function testLastModified() + { + $asset = new StringAsset(''); + $asset->setLastModified(123); + $this->assertEquals(123, $asset->getLastModified(), '->getLastModified() return the set last modified value'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/AssetManagerTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/AssetManagerTest.php new file mode 100644 index 0000000..d459855 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/AssetManagerTest.php @@ -0,0 +1,53 @@ +am = new AssetManager(); + } + + public function testGetAsset() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + $this->am->set('foo', $asset); + $this->assertSame($asset, $this->am->get('foo'), '->get() returns an asset'); + } + + public function testGetInvalidAsset() + { + $this->setExpectedException('InvalidArgumentException'); + $this->am->get('foo'); + } + + public function testHas() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + $this->am->set('foo', $asset); + + $this->assertTrue($this->am->has('foo'), '->has() returns true if the asset is set'); + $this->assertFalse($this->am->has('bar'), '->has() returns false if the asset is not set'); + } + + public function testInvalidName() + { + $this->setExpectedException('InvalidArgumentException'); + + $this->am->set('@foo', $this->getMock('Assetic\\Asset\\AssetInterface')); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/AssetWriterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/AssetWriterTest.php new file mode 100644 index 0000000..ed8061e --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/AssetWriterTest.php @@ -0,0 +1,206 @@ +dir = sys_get_temp_dir().'/assetic_tests_'.rand(11111, 99999); + mkdir($this->dir); + $this->writer = new AssetWriter($this->dir, array( + 'locale' => array('en', 'de', 'fr'), + 'browser' => array('ie', 'firefox', 'other'), + 'gzip' => array('gzip', '') + )); + } + + protected function tearDown() + { + array_map('unlink', glob($this->dir.'/*')); + rmdir($this->dir); + } + + public function testWriteManagerAssets() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + $am = $this->getMock('Assetic\\AssetManager'); + + $am->expects($this->once()) + ->method('getNames') + ->will($this->returnValue(array('foo'))); + $am->expects($this->once()) + ->method('get') + ->with('foo') + ->will($this->returnValue($asset)); + $asset->expects($this->atLeastOnce()) + ->method('getTargetPath') + ->will($this->returnValue('target_url')); + $asset->expects($this->once()) + ->method('dump') + ->will($this->returnValue('content')); + $asset->expects($this->atLeastOnce()) + ->method('getVars') + ->will($this->returnValue(array())); + $asset->expects($this->atLeastOnce()) + ->method('getValues') + ->will($this->returnValue(array())); + + $this->writer->writeManagerAssets($am); + + $this->assertFileExists($this->dir.'/target_url'); + $this->assertEquals('content', file_get_contents($this->dir.'/target_url')); + } + + public function testWriteAssetWithVars() + { + $asset = $this->getMock('Assetic\Asset\AssetInterface'); + $asset->expects($this->atLeastOnce()) + ->method('getVars') + ->will($this->returnValue(array('locale'))); + + $self = $this; + $expectedValues = array( + array('locale' => 'en'), + array('locale' => 'de'), + array('locale' => 'fr'), + ); + $asset->expects($this->exactly(3)) + ->method('setValues') + ->will($this->returnCallback(function($values) use($self, $expectedValues) { + static $counter = 0; + $self->assertEquals($expectedValues[$counter++], $values); + })); + $asset->expects($this->exactly(3)) + ->method('getValues') + ->will($this->returnCallback(function() use($expectedValues) { + static $counter = 0; + return $expectedValues[$counter++]; + })); + + $asset->expects($this->exactly(3)) + ->method('dump') + ->will($this->onConsecutiveCalls('en', 'de', 'fr')); + + $asset->expects($this->atLeastOnce()) + ->method('getTargetPath') + ->will($this->returnValue('target.{locale}')); + + $this->writer->writeAsset($asset); + + $this->assertFileExists($this->dir.'/target.en'); + $this->assertFileExists($this->dir.'/target.de'); + $this->assertFileExists($this->dir.'/target.fr'); + $this->assertEquals('en', file_get_contents($this->dir.'/target.en')); + $this->assertEquals('de', file_get_contents($this->dir.'/target.de')); + $this->assertEquals('fr', file_get_contents($this->dir.'/target.fr')); + } + + public function testAssetWithInputVars() + { + $asset = new FileAsset(__DIR__.'/Fixture/messages.{locale}.js', + array(), null, null, array('locale')); + $asset->setTargetPath('messages.{locale}.js'); + + $this->writer->writeAsset($asset); + + $this->assertFileExists($this->dir.'/messages.en.js'); + $this->assertFileExists($this->dir.'/messages.de.js'); + $this->assertFileExists($this->dir.'/messages.fr.js'); + $this->assertEquals('var messages = {"text.greeting": "Hello %name%!"};', + file_get_contents($this->dir.'/messages.en.js')); + $this->assertEquals('var messages = {"text.greeting": "Hallo %name%!"};', + file_get_contents($this->dir.'/messages.de.js')); + $this->assertEquals('var messages = {"text.greet": "All\u00f4 %name%!"};', + file_get_contents($this->dir.'/messages.fr.js')); + } + + /** + * @dataProvider getCombinationTests + */ + public function testGetCombinations($vars, $expectedCombinations) + { + $ref = new \ReflectionMethod($this->writer, 'getCombinations'); + $ref->setAccessible(true); + + $this->assertEquals($expectedCombinations, $ref->invoke($this->writer, $vars)); + } + + public function getCombinationTests() + { + $tests = array(); + + // no variables + $tests[] = array( + array(), + array(array()) + ); + + // one variables + $tests[] = array( + array('locale'), + array( + array('locale' => 'en'), + array('locale' => 'de'), + array('locale' => 'fr'), + ) + ); + + // two variables + $tests[] = array( + array('locale', 'browser'), + array( + array('locale' => 'en', 'browser' => 'ie'), + array('locale' => 'de', 'browser' => 'ie'), + array('locale' => 'fr', 'browser' => 'ie'), + array('locale' => 'en', 'browser' => 'firefox'), + array('locale' => 'de', 'browser' => 'firefox'), + array('locale' => 'fr', 'browser' => 'firefox'), + array('locale' => 'en', 'browser' => 'other'), + array('locale' => 'de', 'browser' => 'other'), + array('locale' => 'fr', 'browser' => 'other'), + ) + ); + + // three variables + $tests[] = array( + array('locale', 'browser', 'gzip'), + array( + array('locale' => 'en', 'browser' => 'ie', 'gzip' => 'gzip'), + array('locale' => 'de', 'browser' => 'ie', 'gzip' => 'gzip'), + array('locale' => 'fr', 'browser' => 'ie', 'gzip' => 'gzip'), + array('locale' => 'en', 'browser' => 'firefox', 'gzip' => 'gzip'), + array('locale' => 'de', 'browser' => 'firefox', 'gzip' => 'gzip'), + array('locale' => 'fr', 'browser' => 'firefox', 'gzip' => 'gzip'), + array('locale' => 'en', 'browser' => 'other', 'gzip' => 'gzip'), + array('locale' => 'de', 'browser' => 'other', 'gzip' => 'gzip'), + array('locale' => 'fr', 'browser' => 'other', 'gzip' => 'gzip'), + array('locale' => 'en', 'browser' => 'ie', 'gzip' => ''), + array('locale' => 'de', 'browser' => 'ie', 'gzip' => ''), + array('locale' => 'fr', 'browser' => 'ie', 'gzip' => ''), + array('locale' => 'en', 'browser' => 'firefox', 'gzip' => ''), + array('locale' => 'de', 'browser' => 'firefox', 'gzip' => ''), + array('locale' => 'fr', 'browser' => 'firefox', 'gzip' => ''), + array('locale' => 'en', 'browser' => 'other', 'gzip' => ''), + array('locale' => 'de', 'browser' => 'other', 'gzip' => ''), + array('locale' => 'fr', 'browser' => 'other', 'gzip' => ''), + ) + ); + + return $tests; + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/ApcCacheTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/ApcCacheTest.php new file mode 100644 index 0000000..659c06f --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/ApcCacheTest.php @@ -0,0 +1,42 @@ +markTestSkipped('APC must be installed and enabled.'); + } + } + + public function testCache() + { + $cache = new ApcCache(); + + $this->assertFalse($cache->has('foo')); + + $cache->set('foo', 'bar'); + $this->assertEquals('bar', $cache->get('foo')); + + $this->assertTrue($cache->has('foo')); + + $cache->remove('foo'); + $this->assertFalse($cache->has('foo')); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/ConfigCacheTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/ConfigCacheTest.php new file mode 100644 index 0000000..78ab541 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/ConfigCacheTest.php @@ -0,0 +1,65 @@ +dir = sys_get_temp_dir().'/assetic/tests/config_cache'; + $this->cache = new ConfigCache($this->dir); + } + + protected function tearDown() + { + foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->dir, \FilesystemIterator::SKIP_DOTS)) as $file) { + unlink($file->getPathname()); + } + } + + public function testCache() + { + $this->cache->set('foo', array(1, 2, 3)); + $this->assertEquals(array(1, 2, 3), $this->cache->get('foo'), '->get() returns the ->set() value'); + } + + public function testTimestamp() + { + $this->cache->set('bar', array(4, 5, 6)); + $this->assertInternalType('integer', $time = $this->cache->getTimestamp('bar'), '->getTimestamp() returns an integer'); + $this->assertNotEmpty($time, '->getTimestamp() returns a non-empty number'); + } + + public function testInvalidValue() + { + $this->setExpectedException('RuntimeException'); + $this->cache->get('_invalid'); + } + + public function testInvalidTimestamp() + { + $this->setExpectedException('RuntimeException'); + $this->cache->getTimestamp('_invalid'); + } + + public function testHas() + { + $this->cache->set('foo', 'bar'); + $this->assertTrue($this->cache->has('foo')); + $this->assertFalse($this->cache->has('_invalid')); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/ExpiringCacheTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/ExpiringCacheTest.php new file mode 100644 index 0000000..b67cab3 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/ExpiringCacheTest.php @@ -0,0 +1,111 @@ +inner = $this->getMock('Assetic\\Cache\\CacheInterface'); + $this->lifetime = 3600; + $this->cache = new ExpiringCache($this->inner, $this->lifetime); + } + + public function testHasExpired() + { + $key = 'asdf'; + $expiresKey = 'asdf.expires'; + $thePast = 0; + + $this->inner->expects($this->once()) + ->method('has') + ->with($key) + ->will($this->returnValue(true)); + $this->inner->expects($this->once()) + ->method('get') + ->with($expiresKey) + ->will($this->returnValue($thePast)); + $this->inner->expects($this->at(2)) + ->method('remove') + ->with($expiresKey); + $this->inner->expects($this->at(3)) + ->method('remove') + ->with($key); + + $this->assertFalse($this->cache->has($key), '->has() returns false if an expired value exists'); + } + + public function testHasNotExpired() + { + $key = 'asdf'; + $expiresKey = 'asdf.expires'; + $theFuture = time() * 2; + + $this->inner->expects($this->once()) + ->method('has') + ->with($key) + ->will($this->returnValue(true)); + $this->inner->expects($this->once()) + ->method('get') + ->with($expiresKey) + ->will($this->returnValue($theFuture)); + + $this->assertTrue($this->cache->has($key), '->has() returns true if a value the not expired'); + } + + public function testSetLifetime() + { + $key = 'asdf'; + $expiresKey = 'asdf.expires'; + $value = 'qwerty'; + + $this->inner->expects($this->at(0)) + ->method('set') + ->with($expiresKey, $this->greaterThanOrEqual(time() + $this->lifetime)); + $this->inner->expects($this->at(1)) + ->method('set') + ->with($key, $value); + + $this->cache->set($key, $value); + } + + public function testRemove() + { + $key = 'asdf'; + $expiresKey = 'asdf.expires'; + + $this->inner->expects($this->at(0)) + ->method('remove') + ->with($expiresKey); + $this->inner->expects($this->at(1)) + ->method('remove') + ->with($key); + + $this->cache->remove($key); + } + + public function testGet() + { + $this->inner->expects($this->once()) + ->method('get') + ->with('foo') + ->will($this->returnValue('bar')); + + $this->assertEquals('bar', $this->cache->get('foo'), '->get() returns the cached value'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/FilesystemCacheTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/FilesystemCacheTest.php new file mode 100644 index 0000000..daf41e9 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/FilesystemCacheTest.php @@ -0,0 +1,52 @@ +assertFalse($cache->has('foo')); + + $cache->set('foo', 'bar'); + $this->assertEquals('bar', $cache->get('foo')); + + $this->assertTrue($cache->has('foo')); + + $cache->remove('foo'); + $this->assertFalse($cache->has('foo')); + } + + public function testSetCreatesDir() + { + $dir = sys_get_temp_dir().'/assetic/fscachetest'; + + $tearDown = function() use($dir) + { + array_map('unlink', glob($dir.'/*')); + @rmdir($dir); + }; + + $tearDown(); + + $cache = new FilesystemCache($dir); + $cache->set('foo', 'bar'); + + $this->assertFileExists($dir.'/foo'); + + $tearDown(); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/AsseticExtensionTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/AsseticExtensionTest.php new file mode 100644 index 0000000..360e03a --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/AsseticExtensionTest.php @@ -0,0 +1,204 @@ +markTestSkipped('Twig is not installed.'); + } + + $this->am = $this->getMock('Assetic\\AssetManager'); + $this->fm = $this->getMock('Assetic\\FilterManager'); + + $this->valueSupplier = $this->getMock('Assetic\ValueSupplierInterface'); + + $this->factory = new AssetFactory(__DIR__.'/templates'); + $this->factory->setAssetManager($this->am); + $this->factory->setFilterManager($this->fm); + + $this->twig = new \Twig_Environment(); + $this->twig->setLoader(new \Twig_Loader_Filesystem(__DIR__.'/templates')); + $this->twig->addExtension(new AsseticExtension($this->factory, array(), $this->valueSupplier)); + } + + public function testReference() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + $this->am->expects($this->any()) + ->method('get') + ->with('foo') + ->will($this->returnValue($asset)); + + $xml = $this->renderXml('reference.twig'); + $this->assertEquals(1, count($xml->asset)); + $this->assertStringStartsWith('css/', (string) $xml->asset['url']); + } + + public function testGlob() + { + $xml = $this->renderXml('glob.twig'); + $this->assertEquals(1, count($xml->asset)); + $this->assertStringStartsWith('css/', (string) $xml->asset['url']); + } + + public function testAbsolutePath() + { + $xml = $this->renderXml('absolute_path.twig'); + $this->assertEquals(1, count($xml->asset)); + $this->assertStringStartsWith('css/', (string) $xml->asset['url']); + } + + public function testFilters() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + + $this->fm->expects($this->at(0)) + ->method('get') + ->with('foo') + ->will($this->returnValue($filter)); + $this->fm->expects($this->at(1)) + ->method('get') + ->with('bar') + ->will($this->returnValue($filter)); + + $xml = $this->renderXml('filters.twig'); + $this->assertEquals(1, count($xml->asset)); + $this->assertStringStartsWith('css/', (string) $xml->asset['url']); + } + + public function testOptionalFilter() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + + $this->fm->expects($this->once()) + ->method('get') + ->with('foo') + ->will($this->returnValue($filter)); + + $xml = $this->renderXml('optional_filter.twig'); + $this->assertEquals(1, count($xml->asset)); + $this->assertStringStartsWith('css/', (string) $xml->asset['url']); + } + + public function testOutputPattern() + { + $xml = $this->renderXml('output_pattern.twig'); + $this->assertEquals(1, count($xml->asset)); + $this->assertStringStartsWith('css/packed/', (string) $xml->asset['url']); + $this->assertStringEndsWith('.css', (string) $xml->asset['url']); + } + + public function testOutput() + { + $xml = $this->renderXml('output_url.twig'); + $this->assertEquals(1, count($xml->asset)); + $this->assertEquals('explicit_url.css', (string) $xml->asset['url']); + } + + public function testMixture() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + $this->am->expects($this->any()) + ->method('get') + ->with('foo') + ->will($this->returnValue($asset)); + + $xml = $this->renderXml('mixture.twig'); + $this->assertEquals(1, count($xml->asset)); + $this->assertEquals('packed/mixture', (string) $xml->asset['url']); + } + + public function testDebug() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + + $this->fm->expects($this->once()) + ->method('get') + ->with('bar') + ->will($this->returnValue($filter)); + + $xml = $this->renderXml('debug.twig'); + $this->assertEquals(2, count($xml->asset)); + $this->assertStringStartsWith('css/packed_', (string) $xml->asset[0]['url']); + $this->assertStringEndsWith('.css', (string) $xml->asset[0]['url']); + } + + public function testCombine() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + + $this->fm->expects($this->once()) + ->method('get') + ->with('bar') + ->will($this->returnValue($filter)); + + $xml = $this->renderXml('combine.twig'); + $this->assertEquals(1, count($xml->asset)); + $this->assertEquals('css/packed.css', (string) $xml->asset[0]['url']); + } + + public function testImage() + { + $xml = $this->renderXml('image.twig'); + $this->assertEquals(1, count($xml->image)); + $this->assertStringEndsWith('.png', (string) $xml->image[0]['url']); + } + + public function testFilterFunction() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + + $this->fm->expects($this->once()) + ->method('get') + ->with('some_filter') + ->will($this->returnValue($filter)); + + $this->twig->addExtension(new AsseticExtension($this->factory, array( + 'some_func' => array( + 'filter' => 'some_filter', + 'options' => array('output' => 'css/*.css'), + ), + ))); + + $xml = $this->renderXml('function.twig'); + $this->assertEquals(1, count($xml->asset)); + $this->assertStringEndsWith('.css', (string) $xml->asset[0]['url']); + } + + public function testVariables() + { + $this->valueSupplier->expects($this->once()) + ->method('getValues') + ->will($this->returnValue(array('foo' => 'a', 'bar' => 'b'))); + + $xml = $this->renderXml('variables.twig'); + $this->assertEquals(2, $xml->url->count()); + $this->assertEquals("js/7d0828c_foo_1.a.b.js", (string) $xml->url[0]); + $this->assertEquals("js/7d0828c_variable_input.a_2.a.b.js", (string) $xml->url[1]); + } + + private function renderXml($name, $context = array()) + { + return new \SimpleXMLElement($this->twig->loadTemplate($name)->render($context)); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/TwigFormulaLoaderTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/TwigFormulaLoaderTest.php new file mode 100644 index 0000000..ba0f99c --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/TwigFormulaLoaderTest.php @@ -0,0 +1,97 @@ +markTestSkipped('Twig is not installed.'); + } + + $this->am = $this->getMock('Assetic\\AssetManager'); + $this->fm = $this->getMock('Assetic\\FilterManager'); + + $factory = new AssetFactory(__DIR__.'/templates'); + $factory->setAssetManager($this->am); + $factory->setFilterManager($this->fm); + + $twig = new \Twig_Environment(); + $twig->addExtension(new AsseticExtension($factory, array( + 'some_func' => array( + 'filter' => 'some_filter', + 'options' => array('output' => 'css/*.css'), + ), + ))); + + $this->loader = new TwigFormulaLoader($twig); + } + + public function testMixture() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $expected = array( + 'mixture' => array( + array('foo', 'foo/*', '@foo'), + array(), + array( + 'output' => 'packed/mixture', + 'name' => 'mixture', + 'debug' => false, + 'combine' => null, + 'vars' => array(), + ), + ), + ); + + $resource = $this->getMock('Assetic\\Factory\\Resource\\ResourceInterface'); + $resource->expects($this->once()) + ->method('getContent') + ->will($this->returnValue(file_get_contents(__DIR__.'/templates/mixture.twig'))); + $this->am->expects($this->any()) + ->method('get') + ->with('foo') + ->will($this->returnValue($asset)); + + $formulae = $this->loader->load($resource); + $this->assertEquals($expected, $formulae); + } + + public function testFunction() + { + $expected = array( + 'my_asset' => array( + array('path/to/asset'), + array('some_filter'), + array('output' => 'css/*.css', 'name' => 'my_asset'), + ), + ); + + $resource = $this->getMock('Assetic\\Factory\\Resource\\ResourceInterface'); + $resource->expects($this->once()) + ->method('getContent') + ->will($this->returnValue(file_get_contents(__DIR__.'/templates/function.twig'))); + + $formulae = $this->loader->load($resource); + $this->assertEquals($expected, $formulae); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/TwigResourceTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/TwigResourceTest.php new file mode 100644 index 0000000..771da9f --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/TwigResourceTest.php @@ -0,0 +1,48 @@ +markTestSkipped('Twig is not installed.'); + } + } + + public function testInvalidTemplateNameGetContent() + { + $loader = $this->getMock('Twig_LoaderInterface'); + $loader->expects($this->once()) + ->method('getSource') + ->with('asdf') + ->will($this->throwException(new \Twig_Error_Loader(''))); + + $resource = new TwigResource($loader, 'asdf'); + $this->assertEquals('', $resource->getContent()); + } + + public function testInvalidTemplateNameIsFresh() + { + $loader = $this->getMock('Twig_LoaderInterface'); + $loader->expects($this->once()) + ->method('isFresh') + ->with('asdf', 1234) + ->will($this->throwException(new \Twig_Error_Loader(''))); + + $resource = new TwigResource($loader, 'asdf'); + $this->assertFalse($resource->isFresh(1234)); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/absolute_path.twig b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/absolute_path.twig new file mode 100644 index 0000000..05dc382 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/absolute_path.twig @@ -0,0 +1,3 @@ + +{% stylesheets '/path/to/something.css' as='foo' %}{% endstylesheets %} + diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/combine.twig b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/combine.twig new file mode 100644 index 0000000..e1ab5f9 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/combine.twig @@ -0,0 +1,3 @@ + +{% stylesheets 'foo.css' 'bar.css' filter='?foo,bar' output='css/packed.css' debug=true combine=true %}{% endstylesheets %} + diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/debug.twig b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/debug.twig new file mode 100644 index 0000000..550292e --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/debug.twig @@ -0,0 +1,3 @@ + +{% stylesheets 'foo.css' 'bar.css' filter='?foo,bar' output='css/packed.css' debug=true %}{% endstylesheets %} + diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/filters.twig b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/filters.twig new file mode 100644 index 0000000..d211384 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/filters.twig @@ -0,0 +1,3 @@ + +{% stylesheets 'foo' filter='foo, bar' %}{% endstylesheets %} + diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/function.twig b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/function.twig new file mode 100644 index 0000000..0284197 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/function.twig @@ -0,0 +1,3 @@ + + + diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/glob.twig b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/glob.twig new file mode 100644 index 0000000..4624933 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/glob.twig @@ -0,0 +1,3 @@ + +{% stylesheets 'css/src/*' %}{% endstylesheets %} + diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/image.twig b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/image.twig new file mode 100644 index 0000000..902ecf0 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/image.twig @@ -0,0 +1,3 @@ + +{% image 'images/foo.png' %}{% endimage %} + diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/mixture.twig b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/mixture.twig new file mode 100644 index 0000000..482e6ec --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/mixture.twig @@ -0,0 +1,3 @@ + +{% stylesheets 'foo' 'foo/*' '@foo' output='packed/*' name='mixture' %}{% endstylesheets %} + diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/optional_filter.twig b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/optional_filter.twig new file mode 100644 index 0000000..4a4dbb6 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/optional_filter.twig @@ -0,0 +1,3 @@ + +{% stylesheets 'foo' filter='?foo' %}{% endstylesheets %} + diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/output_pattern.twig b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/output_pattern.twig new file mode 100644 index 0000000..cf85897 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/output_pattern.twig @@ -0,0 +1,3 @@ + +{% stylesheets 'foo' output='css/packed/*.css' %}{% endstylesheets %} + diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/output_url.twig b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/output_url.twig new file mode 100644 index 0000000..51a2a2d --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/output_url.twig @@ -0,0 +1,3 @@ + +{% stylesheets 'foo' output='explicit_url.css' %}{% endstylesheets %} + diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/reference.twig b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/reference.twig new file mode 100644 index 0000000..371c4b7 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/reference.twig @@ -0,0 +1,3 @@ + +{% stylesheets '@foo' %}{% endstylesheets %} + diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/variables.twig b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/variables.twig new file mode 100644 index 0000000..111cff4 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/variables.twig @@ -0,0 +1,5 @@ + + {% javascripts "foo.js" "variable_input.{foo}.js" vars=["foo", "bar"] debug=true %} + {{ asset_url }} + {% endjavascripts %} + \ No newline at end of file diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/AssetFactoryTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/AssetFactoryTest.php new file mode 100644 index 0000000..7bfa8bc --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/AssetFactoryTest.php @@ -0,0 +1,203 @@ +am = $this->getMock('Assetic\\AssetManager'); + $this->fm = $this->getMock('Assetic\\FilterManager'); + + $this->factory = new AssetFactory(__DIR__); + $this->factory->setAssetManager($this->am); + $this->factory->setFilterManager($this->fm); + } + + public function testNoAssetManagerReference() + { + $this->setExpectedException('LogicException', 'There is no asset manager.'); + + $factory = new AssetFactory('.'); + $factory->createAsset(array('@foo')); + } + + public function testNoAssetManagerNotReference() + { + $factory = new AssetFactory('.'); + $this->assertInstanceOf('Assetic\\Asset\\AssetInterface', $factory->createAsset(array('foo'))); + } + + public function testNoFilterManager() + { + $this->setExpectedException('LogicException', 'There is no filter manager.'); + + $factory = new AssetFactory('.'); + $factory->createAsset(array('foo'), array('foo')); + } + + public function testCreateAssetReference() + { + $referenced = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $this->am->expects($this->any()) + ->method('get') + ->with('jquery') + ->will($this->returnValue($referenced)); + + $assets = $this->factory->createAsset(array('@jquery')); + $arr = iterator_to_array($assets); + $this->assertInstanceOf('Assetic\\Asset\\AssetReference', $arr[0], '->createAsset() creates a reference'); + } + + /** + * @dataProvider getHttpUrls + */ + public function testCreateHttpAsset($sourceUrl) + { + $assets = $this->factory->createAsset(array($sourceUrl)); + $arr = iterator_to_array($assets); + $this->assertInstanceOf('Assetic\\Asset\\HttpAsset', $arr[0], '->createAsset() creates an HTTP asset'); + } + + public function getHttpUrls() + { + return array( + array('http://example.com/foo.css'), + array('https://example.com/foo.css'), + array('//example.com/foo.css'), + ); + } + + public function testCreateFileAsset() + { + $assets = $this->factory->createAsset(array(basename(__FILE__))); + $arr = iterator_to_array($assets); + $this->assertInstanceOf('Assetic\\Asset\\FileAsset', $arr[0], '->createAsset() creates a file asset'); + } + + public function testCreateGlobAsset() + { + $assets = $this->factory->createAsset(array('*')); + $arr = iterator_to_array($assets); + $this->assertInstanceOf('Assetic\\Asset\\FileAsset', $arr[0], '->createAsset() uses a glob to create a file assets'); + } + + public function testCreateAssetCollection() + { + $asset = $this->factory->createAsset(array('*', basename(__FILE__))); + $this->assertInstanceOf('Assetic\\Asset\\AssetCollection', $asset, '->createAsset() creates an asset collection'); + } + + public function testFilter() + { + $this->fm->expects($this->once()) + ->method('get') + ->with('foo') + ->will($this->returnValue($this->getMock('Assetic\\Filter\\FilterInterface'))); + + $asset = $this->factory->createAsset(array(), array('foo')); + $this->assertEquals(1, count($asset->getFilters()), '->createAsset() adds filters'); + } + + public function testInvalidFilter() + { + $this->setExpectedException('InvalidArgumentException'); + + $this->fm->expects($this->once()) + ->method('get') + ->with('foo') + ->will($this->throwException(new \InvalidArgumentException())); + + $asset = $this->factory->createAsset(array(), array('foo')); + } + + public function testOptionalInvalidFilter() + { + $this->factory->setDebug(true); + + $asset = $this->factory->createAsset(array(), array('?foo')); + + $this->assertEquals(0, count($asset->getFilters()), '->createAsset() does not add an optional invalid filter'); + } + + public function testIncludingOptionalFilter() + { + $this->fm->expects($this->once()) + ->method('get') + ->with('foo') + ->will($this->returnValue($this->getMock('Assetic\\Filter\\FilterInterface'))); + + $this->factory->createAsset(array('foo.css'), array('?foo')); + } + + public function testWorkers() + { + $worker = $this->getMock('Assetic\\Factory\\Worker\\WorkerInterface'); + + // called once on the collection and once on each leaf + $worker->expects($this->exactly(3)) + ->method('process') + ->with($this->isInstanceOf('Assetic\\Asset\\AssetInterface')); + + $this->factory->addWorker($worker); + $this->factory->createAsset(array('foo.js', 'bar.js')); + } + + public function testWorkerReturn() + { + $worker = $this->getMock('Assetic\\Factory\\Worker\\WorkerInterface'); + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $worker->expects($this->at(2)) + ->method('process') + ->with($this->isInstanceOf('Assetic\\Asset\\AssetCollectionInterface')) + ->will($this->returnValue($asset)); + + $this->factory->addWorker($worker); + $coll = $this->factory->createAsset(array('foo.js', 'bar.js')); + + $this->assertEquals(1, count(iterator_to_array($coll))); + } + + public function testNestedFormula() + { + $this->fm->expects($this->once()) + ->method('get') + ->with('foo') + ->will($this->returnValue($this->getMock('Assetic\\Filter\\FilterInterface'))); + + $inputs = array( + 'css/main.css', + array( + // nested formula + array('css/more.sass'), + array('foo'), + ), + ); + + $asset = $this->factory->createAsset($inputs, array(), array('output' => 'css/*.css')); + + $i = 0; + foreach ($asset as $leaf) { + $i++; + } + + $this->assertEquals(2, $i); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/LazyAssetManagerTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/LazyAssetManagerTest.php new file mode 100644 index 0000000..46cdf94 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/LazyAssetManagerTest.php @@ -0,0 +1,96 @@ +factory = $this->getMockBuilder('Assetic\\Factory\\AssetFactory') + ->disableOriginalConstructor() + ->getMock(); + + $this->am = new LazyAssetManager($this->factory); + } + + public function testGetFromLoader() + { + $resource = $this->getMock('Assetic\\Factory\\Resource\\ResourceInterface'); + $loader = $this->getMock('Assetic\\Factory\\Loader\\FormulaLoaderInterface'); + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $formula = array( + array('js/core.js', 'js/more.js'), + array('?yui_js'), + array('output' => 'js/all.js') + ); + + $loader->expects($this->once()) + ->method('load') + ->with($resource) + ->will($this->returnValue(array('foo' => $formula))); + $this->factory->expects($this->once()) + ->method('createAsset') + ->with($formula[0], $formula[1], $formula[2] + array('name' => 'foo')) + ->will($this->returnValue($asset)); + + $this->am->setLoader('foo', $loader); + $this->am->addResource($resource, 'foo'); + + $this->assertSame($asset, $this->am->get('foo'), '->get() returns an asset from the loader'); + + // test the "once" expectations + $this->am->get('foo'); + } + + public function testGetResources() + { + $resources = array( + $this->getMock('Assetic\\Factory\\Resource\\ResourceInterface'), + $this->getMock('Assetic\\Factory\\Resource\\ResourceInterface'), + ); + + $this->am->addResource($resources[0], 'foo'); + $this->am->addResource($resources[1], 'bar'); + + $ret = $this->am->getResources(); + + foreach ($resources as $resource) { + $this->assertTrue(in_array($resource, $ret, true)); + } + } + + public function testGetResourcesEmpty() + { + $this->am->getResources(); + } + + public function testSetFormula() + { + $this->am->setFormula('foo', array()); + $this->am->load(); + $this->assertTrue($this->am->hasFormula('foo'), '->load() does not remove manually added formulae'); + } + + public function testIsDebug() + { + $this->factory->expects($this->once()) + ->method('isDebug') + ->will($this->returnValue(false)); + + $this->assertSame(false, $this->am->isDebug(), '->isDebug() proxies the factory'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Loader/CachedFormulaLoaderTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Loader/CachedFormulaLoaderTest.php new file mode 100644 index 0000000..5253003 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Loader/CachedFormulaLoaderTest.php @@ -0,0 +1,138 @@ +loader = $this->getMock('Assetic\\Factory\\Loader\\FormulaLoaderInterface'); + $this->configCache = $this->getMockBuilder('Assetic\\Cache\\ConfigCache') + ->disableOriginalConstructor() + ->getMock(); + $this->resource = $this->getMock('Assetic\\Factory\\Resource\\ResourceInterface'); + } + + public function testNotDebug() + { + $expected = array( + 'foo' => array(array(), array(), array()), + 'bar' => array(array(), array(), array()), + ); + + $this->configCache->expects($this->once()) + ->method('has') + ->with($this->isType('string')) + ->will($this->returnValue(false)); + $this->loader->expects($this->once()) + ->method('load') + ->with($this->resource) + ->will($this->returnValue($expected)); + $this->configCache->expects($this->once()) + ->method('set') + ->with($this->isType('string'), $expected); + + $loader = new CachedFormulaLoader($this->loader, $this->configCache); + $this->assertEquals($expected, $loader->load($this->resource), '->load() returns formulae'); + } + + public function testNotDebugCached() + { + $expected = array( + 'foo' => array(array(), array(), array()), + 'bar' => array(array(), array(), array()), + ); + + $this->configCache->expects($this->once()) + ->method('has') + ->with($this->isType('string')) + ->will($this->returnValue(true)); + $this->resource->expects($this->never()) + ->method('isFresh'); + $this->configCache->expects($this->once()) + ->method('get') + ->with($this->isType('string')) + ->will($this->returnValue($expected)); + + $loader = new CachedFormulaLoader($this->loader, $this->configCache); + $this->assertEquals($expected, $loader->load($this->resource), '->load() returns formulae'); + } + + public function testDebugCached() + { + $timestamp = 123; + $expected = array( + 'foo' => array(array(), array(), array()), + 'bar' => array(array(), array(), array()), + ); + + $this->configCache->expects($this->once()) + ->method('has') + ->with($this->isType('string')) + ->will($this->returnValue(true)); + $this->configCache->expects($this->once()) + ->method('getTimestamp') + ->with($this->isType('string')) + ->will($this->returnValue($timestamp)); + $this->resource->expects($this->once()) + ->method('isFresh') + ->with($timestamp) + ->will($this->returnValue(true)); + $this->loader->expects($this->never()) + ->method('load'); + $this->configCache->expects($this->once()) + ->method('get') + ->with($this->isType('string')) + ->will($this->returnValue($expected)); + + $loader = new CachedFormulaLoader($this->loader, $this->configCache, true); + $this->assertEquals($expected, $loader->load($this->resource), '->load() returns formulae'); + } + + public function testDebugCachedStale() + { + $timestamp = 123; + $expected = array( + 'foo' => array(array(), array(), array()), + 'bar' => array(array(), array(), array()), + ); + + $this->configCache->expects($this->once()) + ->method('has') + ->with($this->isType('string')) + ->will($this->returnValue(true)); + $this->configCache->expects($this->once()) + ->method('getTimestamp') + ->with($this->isType('string')) + ->will($this->returnValue($timestamp)); + $this->resource->expects($this->once()) + ->method('isFresh') + ->with($timestamp) + ->will($this->returnValue(false)); + $this->loader->expects($this->once()) + ->method('load') + ->with($this->resource) + ->will($this->returnValue($expected)); + $this->configCache->expects($this->once()) + ->method('set') + ->with($this->isType('string'), $expected); + + $loader = new CachedFormulaLoader($this->loader, $this->configCache, true); + $this->assertEquals($expected, $loader->load($this->resource), '->load() returns formulae'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Loader/FunctionCallsFormulaLoaderTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Loader/FunctionCallsFormulaLoaderTest.php new file mode 100644 index 0000000..6b631bf --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Loader/FunctionCallsFormulaLoaderTest.php @@ -0,0 +1,69 @@ +getMock('Assetic\\Factory\\Resource\\ResourceInterface'); + $factory = $this->getMockBuilder('Assetic\\Factory\\AssetFactory') + ->disableOriginalConstructor() + ->getMock(); + + $resource->expects($this->once()) + ->method('getContent') + ->will($this->returnValue('')); + $factory->expects($this->once()) + ->method('generateAssetName') + ->will($this->returnValue($name)); + + $loader = new FunctionCallsFormulaLoader($factory); + $formulae = $loader->load($resource); + + $this->assertEquals($expected, $formulae); + } + + public function getJavascriptInputs() + { + return array( + array('assetic_javascripts', '"js/core.js"', 'asdf', array('asdf' => array(array('js/core.js'), array(), array('debug' => false, 'output' => 'js/*.js', 'name' => 'asdf', )))), + array('assetic_javascripts', "'js/core.js'", 'asdf', array('asdf' => array(array('js/core.js'), array(), array('debug' => false, 'output' => 'js/*.js', 'name' => 'asdf', )))), + array('assetic_javascripts', "array('js/core.js')", 'asdf', array('asdf' => array(array('js/core.js'), array(), array('debug' => false, 'output' => 'js/*.js', 'name' => 'asdf', )))), + array('assetic_javascripts', 'array("js/core.js")', 'asdf', array('asdf' => array(array('js/core.js'), array(), array('debug' => false, 'output' => 'js/*.js', 'name' => 'asdf', )))), + array('assetic_image', '"images/logo.gif"', 'asdf', array('asdf' => array(array('images/logo.gif'), array(), array('debug' => false, 'output' => 'images/*', 'name' => 'asdf')))), + ); + } + + public function testComplexFormula() + { + $factory = new AssetFactory(__DIR__.'/templates', true); + $loader = new FunctionCallsFormulaLoader($factory); + $resource = new FileResource(__DIR__.'/templates/debug.php'); + $formulae = $loader->load($resource); + + $this->assertEquals(array( + 'test123' => array( + array('foo.css', 'bar.css'), + array('?foo', 'bar'), + array('name' => 'test123', 'output' => 'css/packed.css', 'debug' => true), + ), + ), $formulae); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Loader/templates/debug.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Loader/templates/debug.php new file mode 100644 index 0000000..750c25d --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Loader/templates/debug.php @@ -0,0 +1,8 @@ + + 'test123', 'output' => 'css/packed.css', 'debug' => true)) as $url): ?> + + + diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/CoalescingDirectoryResourceTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/CoalescingDirectoryResourceTest.php new file mode 100644 index 0000000..32e8887 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/CoalescingDirectoryResourceTest.php @@ -0,0 +1,42 @@ +assertEquals(array( + realpath(__DIR__.'/Fixtures/dir1/file1.txt'), + realpath(__DIR__.'/Fixtures/dir1/file2.txt'), + realpath(__DIR__.'/Fixtures/dir2/file3.txt'), + ), $paths, 'files from multiple directories are merged'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/DirectoryResourceTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/DirectoryResourceTest.php new file mode 100644 index 0000000..bbe5cff --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/DirectoryResourceTest.php @@ -0,0 +1,108 @@ +assertTrue($resource->isFresh(time() + 5)); + $this->assertFalse($resource->isFresh(0)); + } + + /** + * @dataProvider getPatterns + */ + public function testGetContent($pattern) + { + $resource = new DirectoryResource(__DIR__, $pattern); + $content = $resource->getContent(); + + $this->assertInternalType('string', $content); + } + + public function getPatterns() + { + return array( + array(null), + array('/\.php$/'), + array('/\.foo$/'), + ); + } + + /** + * @dataProvider getPatternsAndEmpty + */ + public function testIteration($pattern, $empty) + { + $resource = new DirectoryResource(__DIR__, $pattern); + + $count = 0; + foreach ($resource as $r) { + ++$count; + $this->assertInstanceOf('Assetic\\Factory\\Resource\\ResourceInterface', $r); + } + + if ($empty) { + $this->assertEmpty($count); + } else { + $this->assertNotEmpty($count); + } + } + + public function getPatternsAndEmpty() + { + return array( + array(null, false), + array('/\.php$/', false), + array('/\.foo$/', true), + ); + } + + public function testRecursiveIteration() + { + $resource = new DirectoryResource(realpath(__DIR__.'/..'), '/^'.preg_quote(basename(__FILE__)).'$/'); + + $count = 0; + foreach ($resource as $r) { + ++$count; + } + + $this->assertEquals(1, $count); + } + + /** + * @dataProvider getPaths + */ + public function testTrailingSlash($path) + { + $resource = new DirectoryResource($path); + $this->assertStringEndsWith(DIRECTORY_SEPARATOR, (string) $resource, 'path ends with a slash'); + } + + public function getPaths() + { + return array( + array(__DIR__), + array(__DIR__.DIRECTORY_SEPARATOR), + ); + } + + public function testInvalidDirectory() + { + $resource = new DirectoryResource(__DIR__.'foo'); + $this->assertEquals(0, iterator_count($resource), 'works for non-existent directory'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/FileResourceTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/FileResourceTest.php new file mode 100644 index 0000000..4864c80 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/FileResourceTest.php @@ -0,0 +1,42 @@ +assertTrue($resource->isFresh(time() + 5)); + $this->assertFalse($resource->isFresh(0)); + } + + public function testGetContent() + { + $resource = new FileResource(__FILE__); + $this->assertEquals(file_get_contents(__FILE__), $resource->getContent()); + } + + public function testIsFreshOnInvalidPath() + { + $resource = new FileResource(__FILE__.'foo'); + $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the file does not exist'); + } + + public function testGetContentOnInvalidPath() + { + $resource = new FileResource(__FILE__.'foo'); + $this->assertSame('', $resource->getContent(), '->getContent() returns an empty string when path is invalid'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir1/file1.txt b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir1/file1.txt new file mode 100644 index 0000000..e69de29 diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir1/file2.txt b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir1/file2.txt new file mode 100644 index 0000000..e69de29 diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir2/file1.txt b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir2/file1.txt new file mode 100644 index 0000000..e69de29 diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir2/file3.txt b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir2/file3.txt new file mode 100644 index 0000000..e69de29 diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Worker/EnsureFilterWorkerTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Worker/EnsureFilterWorkerTest.php new file mode 100644 index 0000000..bdcffe5 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Worker/EnsureFilterWorkerTest.php @@ -0,0 +1,47 @@ +getMock('Assetic\\Filter\\FilterInterface'); + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $asset->expects($this->once()) + ->method('getTargetPath') + ->will($this->returnValue('css/main.css')); + $asset->expects($this->once()) + ->method('ensureFilter') + ->with($filter); + + $worker = new EnsureFilterWorker('/\.css$/', $filter); + $worker->process($asset); + } + + public function testNonMatch() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $asset->expects($this->once()) + ->method('getTargetPath') + ->will($this->returnValue('js/all.js')); + $asset->expects($this->never())->method('ensureFilter'); + + $worker = new EnsureFilterWorker('/\.css$/', $filter); + $worker->process($asset); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/BaseImageFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/BaseImageFilterTest.php new file mode 100644 index 0000000..eb26c19 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/BaseImageFilterTest.php @@ -0,0 +1,24 @@ +file($data) : $finfo->buffer($data); + + self::assertEquals($expected, $actual, $message); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CallablesFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CallablesFilterTest.php new file mode 100644 index 0000000..252f2d1 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CallablesFilterTest.php @@ -0,0 +1,39 @@ +assertInstanceOf('Assetic\\Filter\\FilterInterface', $filter, 'CallablesFilter implements FilterInterface'); + } + + public function testLoader() + { + $nb = 0; + $filter = new CallablesFilter(function($asset) use(&$nb) { $nb++; }); + $filter->filterLoad($this->getMock('Assetic\\Asset\\AssetInterface')); + $this->assertEquals(1, $nb, '->filterLoad() calls the loader callable'); + } + + public function testDumper() + { + $nb = 0; + $filter = new CallablesFilter(null, function($asset) use(&$nb) { $nb++; }); + $filter->filterDump($this->getMock('Assetic\\Asset\\AssetInterface')); + $this->assertEquals(1, $nb, '->filterDump() calls the loader callable'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CoffeeScriptFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CoffeeScriptFilterTest.php new file mode 100644 index 0000000..5c46cef --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CoffeeScriptFilterTest.php @@ -0,0 +1,73 @@ +markTestSkipped('There is no COFFEE_BIN or NODE_BIN environment variable.'); + } + + $this->filter = new CoffeeScriptFilter($_SERVER['COFFEE_BIN'], $_SERVER['NODE_BIN']); + } + + public function testFilterLoad() + { + $expected = << x * x'); + $asset->load(); + + $this->filter->filterLoad($asset); + + $this->assertEquals($expected, $asset->getContent()); + } + + public function testBare() + { + $expected = << x * x'); + $asset->load(); + + $this->filter->setBare(true); + $this->filter->filterLoad($asset); + + $this->assertEquals($expected, $asset->getContent()); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CompassFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CompassFilterTest.php new file mode 100644 index 0000000..4231e8a --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CompassFilterTest.php @@ -0,0 +1,66 @@ + + * @group integration + */ +class CompassFilterTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!isset($_SERVER['COMPASS_BIN'])) { + $this->markTestSkipped('There is no COMPASS_BIN environment variable.'); + } + } + + public function testFilterLoadWithScss() + { + $asset = new FileAsset(__DIR__.'/fixtures/compass/stylesheet.scss'); + $asset->load(); + + $filter = new CompassFilter($_SERVER['COMPASS_BIN']); + $filter->filterLoad($asset); + + $this->assertContains('.test-class', $asset->getContent()); + $this->assertContains('font-size: 2em;', $asset->getContent()); + } + + public function testFilterLoadWithSass() + { + $asset = new FileAsset(__DIR__.'/fixtures/compass/stylesheet.sass'); + $asset->load(); + + $filter = new CompassFilter($_SERVER['COMPASS_BIN']); + $filter->filterLoad($asset); + + $this->assertContains('.test-class', $asset->getContent()); + $this->assertContains('font-size: 2em;', $asset->getContent()); + } + + public function testCompassMixin() + { + $asset = new FileAsset(__DIR__.'/fixtures/compass/compass.sass'); + $asset->load(); + + $filter = new CompassFilter($_SERVER['COMPASS_BIN']); + $filter->filterLoad($asset); + + $this->assertContains('text-decoration', $asset->getContent()); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssEmbedFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssEmbedFilterTest.php new file mode 100644 index 0000000..579abf2 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssEmbedFilterTest.php @@ -0,0 +1,54 @@ +markTestSkipped('There is no CSSEMBED_JAR environment variable.'); + } + } + + public function testCssEmbedDataUri() + { + $data = base64_encode(file_get_contents(__DIR__.'/fixtures/home.png')); + + $asset = new FileAsset(__DIR__ . '/fixtures/cssembed/test.css'); + $asset->load(); + + $filter = new CssEmbedFilter($_SERVER['CSSEMBED_JAR']); + $filter->filterDump($asset); + + $this->assertContains('url(data:image/png;base64,'.$data, $asset->getContent()); + } + + public function testCssEmbedMhtml() + { + $asset = new FileAsset(__DIR__ . '/fixtures/cssembed/test.css'); + $asset->load(); + + $filter = new CssEmbedFilter($_SERVER['CSSEMBED_JAR']); + $filter->setMhtml(true); + $filter->setMhtmlRoot('/test'); + $filter->filterDump($asset); + + $this->assertContains('url(mhtml:/test/!', $asset->getContent()); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssImportFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssImportFilterTest.php new file mode 100644 index 0000000..ecde8e1 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssImportFilterTest.php @@ -0,0 +1,67 @@ +setTargetPath('foo/bar.css'); + $asset->ensureFilter($filter1); + $asset->ensureFilter($filter2); + + $expected = <<assertEquals($expected, $asset->dump(), '->filterLoad() inlines CSS imports'); + } + + /** + * The order of these two filters is only interchangeable because one acts on + * load and the other on dump. We need a more scalable solution. + */ + public function getFilters() + { + return array( + array(new CssImportFilter(), new CssRewriteFilter()), + array(new CssRewriteFilter(), new CssImportFilter()), + ); + } + + public function testNonCssImport() + { + $asset = new FileAsset(__DIR__.'/fixtures/cssimport/noncssimport.css', array(), __DIR__.'/fixtures/cssimport', 'noncssimport.css'); + $asset->load(); + + $filter = new CssImportFilter(); + $filter->filterLoad($asset); + + $this->assertEquals(file_get_contents(__DIR__.'/fixtures/cssimport/noncssimport.css'), $asset->getContent(), '->filterLoad() skips non css'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssMinFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssMinFilterTest.php new file mode 100644 index 0000000..abba852 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssMinFilterTest.php @@ -0,0 +1,40 @@ +markTestSkipped('CssMin is not installed.'); + } + } + + public function testRelativeSourceUrlImportImports() + { + $asset = new FileAsset(__DIR__.'/fixtures/cssmin/main.css'); + $asset->load(); + + $filter = new CssMinFilter(__DIR__.'/fixtures/cssmin'); + $filter->setFilter('ImportImports', true); + $filter->filterDump($asset); + + $this->assertEquals('body{color:white}body{background:black}', $asset->getContent()); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssRewriteFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssRewriteFilterTest.php new file mode 100644 index 0000000..4c497bf --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssRewriteFilterTest.php @@ -0,0 +1,124 @@ +setTargetPath($targetPath); + $asset->load(); + + $filter = new CssRewriteFilter(); + $filter->filterLoad($asset); + $filter->filterDump($asset); + + $this->assertEquals(sprintf($format, $expectedUrl), $asset->getContent(), '->filterDump() rewrites relative urls'); + } + + public function provideUrls() + { + return array( + // url variants + array('body { background: url(%s); }', 'css/body.css', 'css/build/main.css', '../images/bg.gif', '../../images/bg.gif'), + array('body { background: url("%s"); }', 'css/body.css', 'css/build/main.css', '../images/bg.gif', '../../images/bg.gif'), + array('body { background: url(\'%s\'); }', 'css/body.css', 'css/build/main.css', '../images/bg.gif', '../../images/bg.gif'), + + //url with data: + array('body { background: url(\'%s\'); }', 'css/body.css', 'css/build/main.css', 'data:image/png;base64,abcdef=', 'data:image/png;base64,abcdef='), + array('body { background: url(\'%s\'); }', 'css/body.css', 'css/build/main.css', '../images/bg-data:.gif', '../../images/bg-data:.gif'), + + // @import variants + array('@import "%s";', 'css/imports.css', 'css/build/main.css', 'import.css', '../import.css'), + array('@import url(%s);', 'css/imports.css', 'css/build/main.css', 'import.css', '../import.css'), + array('@import url("%s");', 'css/imports.css', 'css/build/main.css', 'import.css', '../import.css'), + array('@import url(\'%s\');', 'css/imports.css', 'css/build/main.css', 'import.css', '../import.css'), + + // path diffs + array('body { background: url(%s); }', 'css/body/bg.css', 'css/build/main.css', '../../images/bg.gif', '../../images/bg.gif'), + array('body { background: url(%s); }', 'css/body.css', 'main.css', '../images/bg.gif', 'css/../images/bg.gif'), // fixme + array('body { background: url(%s); }', 'body.css', 'css/main.css', 'images/bg.gif', '../images/bg.gif'), + array('body { background: url(%s); }', 'source/css/body.css', 'output/build/main.css', '../images/bg.gif', '../../source/images/bg.gif'), + array('body { background: url(%s); }', 'css/body.css', 'css/build/main.css', '//example.com/images/bg.gif', '//example.com/images/bg.gif'), + + // url diffs + array('body { background: url(%s); }', 'css/body.css', 'css/build/main.css', 'http://foo.com/bar.gif', 'http://foo.com/bar.gif'), + array('body { background: url(%s); }', 'css/body.css', 'css/build/main.css', '/images/foo.gif', '/images/foo.gif'), + array('body { background: url(%s); }', 'css/body.css', 'css/build/main.css', 'http://foo.com/images/foo.gif', 'http://foo.com/images/foo.gif'), + ); + } + + /** + * @dataProvider provideMultipleUrls + */ + public function testMultipleUrls($format, $sourcePath, $targetPath, $inputUrl1, $inputUrl2, $expectedUrl1, $expectedUrl2) + { + $asset = new StringAsset(sprintf($format, $inputUrl1, $inputUrl2), array(), null, $sourcePath); + $asset->setTargetPath($targetPath); + $asset->load(); + + $filter = new CssRewriteFilter(); + $filter->filterLoad($asset); + $filter->filterDump($asset); + + $this->assertEquals(sprintf($format, $expectedUrl1, $expectedUrl2), $asset->getContent(), '->filterDump() rewrites relative urls'); + } + + public function provideMultipleUrls() + { + return array( + // multiple url + array('body { background: url(%s); background: url(%s); }', 'css/body.css', 'css/build/main.css', '../images/bg.gif', '../images/bg2.gif', '../../images/bg.gif', '../../images/bg2.gif'), + array("body { background: url(%s);\nbackground: url(%s); }", 'css/body.css', 'css/build/main.css', '../images/bg.gif', '../images/bg2.gif', '../../images/bg.gif', '../../images/bg2.gif'), + + // multiple import + array('@import "%s"; @import "%s";', 'css/imports.css', 'css/build/main.css', 'import.css', 'import2.css', '../import.css', '../import2.css'), + array("@import \"%s\";\n@import \"%s\";", 'css/imports.css', 'css/build/main.css', 'import.css', 'import2.css', '../import.css', '../import2.css'), + + // mixed urls and imports + array('@import "%s"; body { background: url(%s); }', 'css/body.css', 'css/build/main.css', 'import.css', '../images/bg2.gif', '../import.css', '../../images/bg2.gif'), + array("@import \"%s\";\nbody { background: url(%s); }", 'css/body.css', 'css/build/main.css', 'import.css', '../images/bg2.gif', '../import.css', '../../images/bg2.gif'), + ); + } + + public function testNoTargetPath() + { + $content = 'body { background: url(foo.gif); }'; + + $asset = new StringAsset($content); + $asset->load(); + + $filter = new CssRewriteFilter(); + $filter->filterDump($asset); + + $this->assertEquals($content, $asset->getContent(), '->filterDump() urls are not changed without urls'); + } + + public function testExternalSource() + { + $asset = new StringAsset('body { background: url(../images/bg.gif); }', array(), 'http://www.example.com', 'css/main.css'); + $asset->setTargetPath('css/packed/main.css'); + $asset->load(); + + $filter = new CssRewriteFilter(); + $filter->filterDump($asset); + + $this->assertContains('http://www.example.com/css/../images/bg.gif', $asset->getContent(), '->filterDump() rewrites references in external stylesheets'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/FilterCollectionTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/FilterCollectionTest.php new file mode 100644 index 0000000..277c773 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/FilterCollectionTest.php @@ -0,0 +1,59 @@ +assertInstanceOf('Assetic\\Filter\\FilterInterface', $filter, 'FilterCollection implements FilterInterface'); + } + + public function testEnsure() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $filter->expects($this->once())->method('filterLoad'); + + $coll = new FilterCollection(); + $coll->ensure($filter); + $coll->ensure($filter); + $coll->filterLoad($asset); + } + + public function testAll() + { + $filter = new FilterCollection(array( + $this->getMock('Assetic\\Filter\\FilterInterface'), + $this->getMock('Assetic\\Filter\\FilterInterface'), + )); + + $this->assertInternalType('array', $filter->all(), '->all() returns an array'); + } + + public function testEmptyAll() + { + $filter = new FilterCollection(); + $this->assertInternalType('array', $filter->all(), '->all() returns an array'); + } + + public function testCountable() + { + $filters = new FilterCollection(array($this->getMock('Assetic\\Filter\\FilterInterface'))); + + $this->assertEquals(1, count($filters), 'Countable returns the count'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/GoogleClosure/CompilerApiFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/GoogleClosure/CompilerApiFilterTest.php new file mode 100644 index 0000000..a8458d0 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/GoogleClosure/CompilerApiFilterTest.php @@ -0,0 +1,59 @@ +load(); + + $filter = new CompilerApiFilter(); + $filter->setCompilationLevel(CompilerApiFilter::COMPILE_SIMPLE_OPTIMIZATIONS); + $filter->setJsExterns(''); + $filter->setExternsUrl(''); + $filter->setExcludeDefaultExterns(true); + $filter->setFormatting(CompilerApiFilter::FORMAT_PRETTY_PRINT); + $filter->setUseClosureLibrary(false); + $filter->setWarningLevel(CompilerApiFilter::LEVEL_VERBOSE); + + $filter->filterLoad($asset); + $filter->filterDump($asset); + + $this->assertEquals($expected, $asset->getContent()); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/GoogleClosure/CompilerJarFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/GoogleClosure/CompilerJarFilterTest.php new file mode 100644 index 0000000..2edb9c6 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/GoogleClosure/CompilerJarFilterTest.php @@ -0,0 +1,53 @@ +markTestSkipped('There is no CLOSURE_JAR environment variable.'); + } + + $input = <<load(); + + $filter = new CompilerJarFilter($_SERVER['CLOSURE_JAR']); + $filter->filterLoad($asset); + $filter->filterDump($asset); + + $this->assertEquals($expected, $asset->getContent()); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/GssFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/GssFilterTest.php new file mode 100644 index 0000000..2b4c7bc --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/GssFilterTest.php @@ -0,0 +1,45 @@ +markTestSkipped('There is no GSS_JAR environment variable.'); + } + + $input = <<load(); + + $filter = new GssFilter($_SERVER['GSS_JAR']); + $filter->filterLoad($asset); + + $this->assertEquals($expected, $asset->getContent()); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JSMinFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JSMinFilterTest.php new file mode 100644 index 0000000..b0d6c21 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JSMinFilterTest.php @@ -0,0 +1,39 @@ +markTestSkipped('JSMin is not installed.'); + } + } + + public function testRelativeSourceUrlImportImports() + { + $asset = new FileAsset(__DIR__.'/fixtures/jsmin/js.js'); + $asset->load(); + + $filter = new JSMinFilter(); + $filter->filterDump($asset); + + $this->assertEquals('var a="abc";;;var bbb="u";', $asset->getContent()); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JSMinPlusFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JSMinPlusFilterTest.php new file mode 100644 index 0000000..72e769a --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JSMinPlusFilterTest.php @@ -0,0 +1,39 @@ +markTestSkipped('JSMinPlus is not installed.'); + } + } + + public function testRelativeSourceUrlImportImports() + { + $asset = new FileAsset(__DIR__.'/fixtures/jsmin/js.js'); + $asset->load(); + + $filter = new JSMinPlusFilter(); + $filter->filterDump($asset); + + $this->assertEquals('var a="abc",bbb="u"', $asset->getContent()); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JpegoptimFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JpegoptimFilterTest.php new file mode 100644 index 0000000..d0a6761 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JpegoptimFilterTest.php @@ -0,0 +1,45 @@ +markTestSkipped('No jpegoptim configuration.'); + } + + $this->filter = new JpegoptimFilter($_SERVER['JPEGOPTIM_BIN']); + } + + public function testFilter() + { + $asset = new FileAsset(__DIR__.'/fixtures/home.jpg'); + $asset->load(); + + $before = $asset->getContent(); + $this->filter->filterDump($asset); + + $this->assertNotEmpty($asset->getContent(), '->filterLoad() sets content'); + $this->assertNotEquals($before, $asset->getContent(), '->filterDump() changes the content'); + $this->assertMimeType('image/jpeg', $asset->getContent(), '->filterDump() creates JPEG data'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JpegtranFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JpegtranFilterTest.php new file mode 100644 index 0000000..10245f6 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JpegtranFilterTest.php @@ -0,0 +1,45 @@ +markTestSkipped('No jpegtran configuration.'); + } + + $this->filter = new JpegtranFilter($_SERVER['JPEGTRAN_BIN']); + } + + public function testFilter() + { + $asset = new FileAsset(__DIR__.'/fixtures/home.jpg'); + $asset->load(); + + $before = $asset->getContent(); + $this->filter->filterDump($asset); + + $this->assertNotEmpty($asset->getContent(), '->filterLoad() sets content'); + $this->assertNotEquals($before, $asset->getContent(), '->filterDump() changes the content'); + $this->assertMimeType('image/jpeg', $asset->getContent(), '->filterDump() creates JPEG data'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/LessFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/LessFilterTest.php new file mode 100644 index 0000000..ce97a86 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/LessFilterTest.php @@ -0,0 +1,63 @@ +markTestSkipped('No node.js configuration.'); + } + + $this->filter = new LessFilter($_SERVER['NODE_BIN'], array($_SERVER['NODE_PATH'])); + } + + public function testFilterLoad() + { + $asset = new StringAsset('.foo{.bar{width:1+1;}}'); + $asset->load(); + + $this->filter->filterLoad($asset); + + $this->assertEquals(".foo .bar {\n width: 2;\n}\n", $asset->getContent(), '->filterLoad() parses the content'); + } + + public function testImport() + { + $expected = <<load(); + + $this->filter->filterLoad($asset); + + $this->assertEquals($expected, $asset->getContent(), '->filterLoad() sets an include path based on source url'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/LessphpFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/LessphpFilterTest.php new file mode 100644 index 0000000..08a8031 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/LessphpFilterTest.php @@ -0,0 +1,67 @@ +filter = new LessphpFilter(); + } + + public function testFilterLoad() + { + $asset = new StringAsset('.foo{.bar{width:1+ 1;}}'); + $asset->load(); + + $this->filter->filterLoad($asset); + + $this->assertEquals(".foo .bar { width:2; }\n", $asset->getContent(), '->filterLoad() parses the content'); + } + + public function testImport() + { + $expected = <<load(); + + $this->filter->filterLoad($asset); + + $this->assertEquals($expected, $asset->getContent(), '->filterLoad() sets an include path based on source url'); + } + + public function testPresets() + { + $asset = new StringAsset('.foo { color: @bar }'); + $asset->load(); + + $this->filter->setPresets(array( + 'bar' => 'green' + )); + + $this->filter->filterLoad($asset); + + $this->assertEquals(".foo { color:green; }\n", $asset->getContent(), '->setPresets() to pass variables into lessphp filter'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/OptiPngFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/OptiPngFilterTest.php new file mode 100644 index 0000000..c2f72c7 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/OptiPngFilterTest.php @@ -0,0 +1,56 @@ +markTestSkipped('No OptiPNG configuration.'); + } + + $this->filter = new OptiPngFilter($_SERVER['OPTIPNG_BIN']); + } + + /** + * @dataProvider getImages + */ + public function testFilter($image) + { + $asset = new FileAsset($image); + $asset->load(); + + $before = $asset->getContent(); + $this->filter->filterDump($asset); + + $this->assertNotEmpty($asset->getContent(), '->filterDump() sets content'); + $this->assertNotEquals($before, $asset->getContent(), '->filterDump() changes the content'); + $this->assertMimeType('image/png', $asset->getContent(), '->filterDump() creates PNG data'); + } + + public function getImages() + { + return array( + array(__DIR__.'/fixtures/home.gif'), + array(__DIR__.'/fixtures/home.png'), + ); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PackagerFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PackagerFilterTest.php new file mode 100644 index 0000000..7dcdaa0 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PackagerFilterTest.php @@ -0,0 +1,69 @@ +markTestSkipped('Packager is not available.'); + } + } + + public function testPackager() + { + $expected = <<load(); + + $filter = new PackagerFilter(); + $filter->addPackage(__DIR__.'/fixtures/packager/lib'); + $filter->filterLoad($asset); + + $this->assertEquals($expected, $asset->getContent(), '->filterLoad() runs packager'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PackerFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PackerFilterTest.php new file mode 100644 index 0000000..8bad914 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PackerFilterTest.php @@ -0,0 +1,36 @@ +markTestSkipped('JavaScriptPacker is not installed.'); + } + } + + public function testPacker() + { + $asset = new FileAsset(__DIR__.'/fixtures/packer/example.js'); + $asset->load(); + + $filter = new PackerFilter(); + $filter->filterDump($asset); + + $this->assertEquals("var exampleFunction=function(arg1,arg2){alert('exampleFunction called!')}", $asset->getContent()); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PngoutFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PngoutFilterTest.php new file mode 100644 index 0000000..23c0712 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PngoutFilterTest.php @@ -0,0 +1,57 @@ +markTestSkipped('No pngout configuration.'); + } + + $this->filter = new PngoutFilter($_SERVER['PNGOUT_BIN']); + } + + /** + * @dataProvider getImages + */ + public function testFilter($image) + { + $asset = new FileAsset($image); + $asset->load(); + + $before = $asset->getContent(); + $this->filter->filterDump($asset); + + $this->assertNotEmpty($asset->getContent(), '->filterLoad() sets content'); + $this->assertNotEquals($before, $asset->getContent(), '->filterLoad() changes the content'); + $this->assertMimeType('image/png', $asset->getContent(), '->filterLoad() creates PNG data'); + } + + public function getImages() + { + return array( + array(__DIR__.'/fixtures/home.gif'), + array(__DIR__.'/fixtures/home.jpg'), + array(__DIR__.'/fixtures/home.png'), + ); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Sass/SassFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Sass/SassFilterTest.php new file mode 100644 index 0000000..874e591 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Sass/SassFilterTest.php @@ -0,0 +1,70 @@ +markTestSkipped('There is no SASS_BIN environment variable.'); + } + + $this->filter = new SassFilter($_SERVER['SASS_BIN']); + } + + public function testSass() + { + $input = <<load(); + + $this->filter->setStyle(SassFilter::STYLE_COMPACT); + $this->filter->filterLoad($asset); + + $this->assertEquals("body { color: red; }\n", $asset->getContent(), '->filterLoad() parses the sass'); + } + + public function testScssGuess() + { + $input = <<<'EOF' +$red: #F00; + +.foo { + color: $red; +} + +EOF; + + $expected = '.foo { color: red; }'; + + $asset = new StringAsset($input, array(), null, 'foo.scss'); + $asset->load(); + + $this->filter->setStyle(SassFilter::STYLE_COMPACT); + $this->filter->filterLoad($asset); + + $this->assertEquals(".foo { color: red; }\n", $asset->getContent(), '->filterLoad() detects SCSS based on source path extension'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Sass/ScssFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Sass/ScssFilterTest.php new file mode 100644 index 0000000..a08fe0e --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Sass/ScssFilterTest.php @@ -0,0 +1,44 @@ +markTestSkipped('There is no SASS_BIN environment variable.'); + } + + $asset = new FileAsset(__DIR__.'/../fixtures/sass/main.scss'); + $asset->load(); + + $filter = new ScssFilter($_SERVER['SASS_BIN']); + $filter->setStyle(ScssFilter::STYLE_COMPACT); + $filter->filterLoad($asset); + + $expected = <<assertEquals($expected, $asset->getContent(), '->filterLoad() loads imports'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/SprocketsFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/SprocketsFilterTest.php new file mode 100644 index 0000000..8694dc5 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/SprocketsFilterTest.php @@ -0,0 +1,69 @@ +markTestSkipped('There is no sprockets configuration.'); + } + + $this->assetRoot = sys_get_temp_dir().'/assetic_sprockets'; + if (is_dir($this->assetRoot)) { + $this->cleanup(); + } else { + mkdir($this->assetRoot); + } + } + + protected function tearDown() + { + $this->cleanup(); + } + + private function cleanup() + { + $it = new \RecursiveDirectoryIterator($this->assetRoot); + foreach (new \RecursiveIteratorIterator($it) as $path => $file) { + if (is_file($path)) { + unlink($path); + } + } + } + + public function testFilterLoad() + { + $asset = new FileAsset(__DIR__.'/fixtures/sprockets/main.js'); + $asset->load(); + + $filter = new SprocketsFilter($_SERVER['SPROCKETS_LIB'], $_SERVER['RUBY_BIN']); + $filter->addIncludeDir(__DIR__.'/fixtures/sprockets/lib1'); + $filter->addIncludeDir(__DIR__.'/fixtures/sprockets/lib2'); + $filter->setAssetRoot($this->assetRoot); + $filter->filterLoad($asset); + + $this->assertContains('/* header.js */', $asset->getContent()); + $this->assertContains('/* include.js */', $asset->getContent()); + $this->assertContains('/* footer.js */', $asset->getContent()); + $this->assertFileExists($this->assetRoot.'/images/image.gif'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/StylusFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/StylusFilterTest.php new file mode 100644 index 0000000..03fc729 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/StylusFilterTest.php @@ -0,0 +1,53 @@ +markTestSkipped('No node.js configuration.'); + } + + $this->filter = new StylusFilter($_SERVER['NODE_BIN'], array($_SERVER['NODE_PATH'])); + } + + public function testFilterLoad() + { + $asset = new StringAsset("body\n font 12px Helvetica, Arial, sans-serif\n color black"); + $asset->load(); + + $this->filter->filterLoad($asset); + + $this->assertEquals("body {\n font: 12px Helvetica, Arial, sans-serif;\n color: #000;\n}\n", $asset->getContent(), '->filterLoad() parses the content'); + } + + public function testFilterLoadWithCompression() + { + $asset = new StringAsset("body\n font 12px Helvetica, Arial, sans-serif\n color black;"); + $asset->load(); + + $this->filter->setCompress(true); + $this->filter->filterLoad($asset); + + $this->assertEquals("body{font:12px Helvetica,Arial,sans-serif;color:#000}\n", $asset->getContent(), '->filterLoad() parses the content and compress it'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/UglifyJsFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/UglifyJsFilterTest.php new file mode 100644 index 0000000..bc4b242 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/UglifyJsFilterTest.php @@ -0,0 +1,100 @@ +markTestSkipped('There is no uglifyJs configuration.'); + } + + $this->asset = new FileAsset(__DIR__.'/fixtures/uglifyjs/script.js'); + $this->asset->load(); + + if (isset($_SERVER['NODE_BIN'])) { + $this->filter = new UglifyJsFilter($_SERVER['UGLIFYJS_BIN'], $_SERVER['NODE_BIN']); + } else { + $this->filter = new UglifyJsFilter($_SERVER['UGLIFYJS_BIN']); + } + } + + protected function tearDown() + { + $this->asset = null; + $this->filter = null; + } + + public function testUglify() + { + $this->filter->filterDump($this->asset); + + $expected = <<assertSame($expected, $this->asset->getContent()); + } + + public function testUnsafeUglify() + { + $this->filter->setUnsafe(true); + $this->filter->filterDump($this->asset); + + $expected = <<assertSame($expected, $this->asset->getContent()); + } + + public function testBeautifyUglify() + { + $this->filter->setBeautify(true); + $this->filter->filterDump($this->asset); + + $expected = <<assertSame($expected, $this->asset->getContent()); + } + + public function testNoCopyrightUglify() + { + $this->filter->setNoCopyright(true); + $this->filter->filterDump($this->asset); + + $expected = 'function bar(a){return var2.push(a),a}var foo=new Array(1,2,3,4),bar=Array(a,b,c),var1=new Array(5),var2=new Array(a),foo=function(a){return a};'; + $this->assertSame($expected, $this->asset->getContent()); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Yui/BaseCompressorFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Yui/BaseCompressorFilterTest.php new file mode 100644 index 0000000..39491b1 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Yui/BaseCompressorFilterTest.php @@ -0,0 +1,31 @@ +assertInstanceOf('Assetic\\Filter\\FilterInterface', $filter, 'BaseCompressorFilter implements FilterInterface'); + } +} + +class YuiCompressorFilterForTest extends BaseCompressorFilter +{ + public function filterDump(AssetInterface $asset) + { + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Yui/CssCompressorFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Yui/CssCompressorFilterTest.php new file mode 100644 index 0000000..61f9fd8 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Yui/CssCompressorFilterTest.php @@ -0,0 +1,23 @@ +assertInstanceOf('Assetic\\Filter\\FilterInterface', $filter, 'CssCompressorFilter implements FilterInterface'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Yui/JsCompressorFilterTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Yui/JsCompressorFilterTest.php new file mode 100644 index 0000000..c391837 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Yui/JsCompressorFilterTest.php @@ -0,0 +1,62 @@ +assertInstanceOf('Assetic\\Filter\\FilterInterface', $filter, 'JsCompressorFilter implements FilterInterface'); + } + + /** + * @group integration + */ + public function testFilterDump() + { + if (!isset($_SERVER['YUI_COMPRESSOR_JAR'])) { + $this->markTestSkipped('There is no YUI_COMPRESSOR_JAR environment variable.'); + } + + $source = <<load(); + + $filter = new JsCompressorFilter($_SERVER['YUI_COMPRESSOR_JAR']); + $filter->filterDump($asset); + + $this->assertEquals($expected, $asset->getContent(), '->filterDump()'); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/compass.sass b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/compass.sass new file mode 100644 index 0000000..dfc99fb --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/compass.sass @@ -0,0 +1,4 @@ +@import "compass/typography/links/hover-link" + +a + @include hover-link diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/partials/_sass.sass b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/partials/_sass.sass new file mode 100644 index 0000000..8593aab --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/partials/_sass.sass @@ -0,0 +1,4 @@ +@import "compass/utilities" + +@mixin mixin-test($fontSize: 1em) + font-size: $fontSize \ No newline at end of file diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/partials/_scss.scss b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/partials/_scss.scss new file mode 100644 index 0000000..896ba5b --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/partials/_scss.scss @@ -0,0 +1,6 @@ +@import "compass/utilities"; + +@mixin mixin-test($fontSize: 1em) +{ + font-size: $fontSize; +} \ No newline at end of file diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/stylesheet.sass b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/stylesheet.sass new file mode 100644 index 0000000..569d84e --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/stylesheet.sass @@ -0,0 +1,4 @@ +@import "partials/sass" + +.test-class + @include mixin-test(2em) \ No newline at end of file diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/stylesheet.scss b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/stylesheet.scss new file mode 100644 index 0000000..461884c --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/stylesheet.scss @@ -0,0 +1,6 @@ +@import "partials/scss"; + +.test-class +{ + @include mixin-test(2em); +} \ No newline at end of file diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssembed/test.css b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssembed/test.css new file mode 100644 index 0000000..370982c --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssembed/test.css @@ -0,0 +1,4 @@ +.test +{ + background: url(../home.png); +} \ No newline at end of file diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/import.css b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/import.css new file mode 100644 index 0000000..e2c77fe --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/import.css @@ -0,0 +1,2 @@ +/* import.css */ +body { color: red; } \ No newline at end of file diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/main.css b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/main.css new file mode 100644 index 0000000..1a90d49 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/main.css @@ -0,0 +1,4 @@ +/* main.css */ +@import "import.css"; +@import url('more/evenmore/deep1.css'); +body { color: black; } \ No newline at end of file diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more.sass b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more.sass new file mode 100644 index 0000000..1463b16 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more.sass @@ -0,0 +1 @@ +/* more.sass */ \ No newline at end of file diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/bg.gif b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/bg.gif new file mode 100644 index 0000000..e69de29 diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/deep1.css b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/deep1.css new file mode 100644 index 0000000..433b341 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/deep1.css @@ -0,0 +1,2 @@ +/* more/evenmore/deep1.css */ +@import url(deep2.css); \ No newline at end of file diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/deep2.css b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/deep2.css new file mode 100644 index 0000000..645a40e --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/deep2.css @@ -0,0 +1,4 @@ +/* more/evenmore/deep2.css */ +body { + background: url(bg.gif); +} \ No newline at end of file diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/noncssimport.css b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/noncssimport.css new file mode 100644 index 0000000..2cea30f --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/noncssimport.css @@ -0,0 +1,2 @@ +/* noncssimport.css */ +@import "more.sass"; \ No newline at end of file diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssmin/fonts.css b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssmin/fonts.css new file mode 100644 index 0000000..2d135f6 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssmin/fonts.css @@ -0,0 +1,3 @@ +body { + color: white; +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssmin/main.css b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssmin/main.css new file mode 100644 index 0000000..8fbabc8 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssmin/main.css @@ -0,0 +1,5 @@ +@import url("fonts.css"); + +body { + background: black; +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/home.gif b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/home.gif new file mode 100644 index 0000000000000000000000000000000000000000..edda5603d352c0483c577cf208db53cb7ef13471 GIT binary patch literal 61 zcmZ?wbhEHbC5UDGKfoZ!!NA49#mp$kz$D1XEXer(2tzUh z12fQ#NPvZdlaUdL4`vDgJ)(FaTYrk~7(Q*CwD^^RPU!s(ss;rnA{dE zWm7n%vc#{t^UjVq7gtTUzPeu5Bi)x&rzUu6dWpB+d|UL+X^LIIZ{AzM`{!+8Zr}AY cVT#W6n0+f4v7|ftIx;YR|DNig)WpGT%PfAtr%uP&B4N6T+sVqF1Y6Dc{<>}%WQgJKk&;S4S%ti^{?(UXy z`G5C~Oqb5N7GFUtX;;NvEW0Fx^;}V5n3!A`8LR<&whSHs literal 0 HcmV?d00001 diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib1/header.js b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib1/header.js new file mode 100644 index 0000000..c60f8d5 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib1/header.js @@ -0,0 +1,3 @@ +/* header.js */ + +//= provide "assets" diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib2/footer.js b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib2/footer.js new file mode 100644 index 0000000..5ce2b9c --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib2/footer.js @@ -0,0 +1 @@ +/* footer.js */ diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/main.js b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/main.js new file mode 100644 index 0000000..6ea483a --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/main.js @@ -0,0 +1,5 @@ +//= require
    + +//= require "include" + +//= require
    diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/uglifyjs/script.js b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/uglifyjs/script.js new file mode 100644 index 0000000..a7c2233 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/uglifyjs/script.js @@ -0,0 +1,18 @@ +/** + * Copyright + */ + +var foo = new Array(1, 2, 3, 4); +var bar = Array(a, b, c); +var var1 = new Array(5); +var var2 = new Array(a); + +function bar(foo) { + var2.push(foo); + return foo; +} + +// comment +var foo = function (var1) { + return var1; +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/FilterManagerTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/FilterManagerTest.php new file mode 100644 index 0000000..6d54a71 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/FilterManagerTest.php @@ -0,0 +1,58 @@ +fm = new FilterManager(); + } + + public function testInvalidName() + { + $this->setExpectedException('InvalidArgumentException'); + + $this->fm->get('foo'); + } + + public function testGetFilter() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $name = 'foo'; + + $this->fm->set($name, $filter); + + $this->assertSame($filter, $this->fm->get($name), '->set() sets a filter'); + } + + public function testHas() + { + $this->fm->set('foo', $this->getMock('Assetic\\Filter\\FilterInterface')); + $this->assertTrue($this->fm->has('foo'), '->has() returns true if the filter is set'); + } + + public function testHasInvalid() + { + $this->assertFalse($this->fm->has('foo'), '->has() returns false if the filter is not set'); + } + + public function testInvalidAlias() + { + $this->setExpectedException('InvalidArgumentException'); + $this->fm->set('@foo', $this->getMock('Assetic\\Filter\\FilterInterface')); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Fixture/messages.de.js b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Fixture/messages.de.js new file mode 100644 index 0000000..d2c7780 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Fixture/messages.de.js @@ -0,0 +1 @@ +var messages = {"text.greeting": "Hallo %name%!"}; \ No newline at end of file diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Fixture/messages.en.js b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Fixture/messages.en.js new file mode 100644 index 0000000..3eb9da2 --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Fixture/messages.en.js @@ -0,0 +1 @@ +var messages = {"text.greeting": "Hello %name%!"}; \ No newline at end of file diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Fixture/messages.fr.js b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Fixture/messages.fr.js new file mode 100644 index 0000000..8fd4c4d --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Fixture/messages.fr.js @@ -0,0 +1 @@ +var messages = {"text.greet": "All\u00f4 %name%!"}; \ No newline at end of file diff --git a/vendor/kriswallsmith/assetic/tests/Assetic/Test/Util/TraversableStringTest.php b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Util/TraversableStringTest.php new file mode 100644 index 0000000..47bd05a --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/Assetic/Test/Util/TraversableStringTest.php @@ -0,0 +1,35 @@ +assertEquals('foo', (string) $foo); + } + + public function testArray() + { + $foo = new TraversableString('foo', array('foo', 'bar')); + + $values = array(); + foreach ($foo as $value) { + $values[] = $value; + } + + $this->assertEquals(array('foo', 'bar'), $values); + } +} diff --git a/vendor/kriswallsmith/assetic/tests/bootstrap.php b/vendor/kriswallsmith/assetic/tests/bootstrap.php new file mode 100644 index 0000000..767818d --- /dev/null +++ b/vendor/kriswallsmith/assetic/tests/bootstrap.php @@ -0,0 +1,46 @@ +add('Assetic\Test', __DIR__); + +if (isset($_SERVER['TWIG_LIB'])) { + $loader->add('Twig_', $_SERVER['TWIG_LIB']); +} + +if (isset($_SERVER['LESSPHP'])) { + require_once $_SERVER['LESSPHP']; +} + +if (isset($_SERVER['CSSMIN'])) { + require_once $_SERVER['CSSMIN']; +} + +if (isset($_SERVER['JSMIN'])) { + require_once $_SERVER['JSMIN']; +} + +if (isset($_SERVER['JSMINPLUS'])) { + require_once $_SERVER['JSMINPLUS']; +} + +if (isset($_SERVER['PACKAGER'])) { + require_once $_SERVER['PACKAGER']; +} + +if (isset($_SERVER['PACKER'])) { + require_once $_SERVER['PACKER']; +} \ No newline at end of file diff --git a/vendor/monolog/monolog/.travis.yml b/vendor/monolog/monolog/.travis.yml new file mode 100644 index 0000000..eb35049 --- /dev/null +++ b/vendor/monolog/monolog/.travis.yml @@ -0,0 +1,11 @@ +language: php + +php: + - 5.3 + - 5.4 + +before_script: + - curl -s http://getcomposer.org/installer | php + - php composer.phar install --dev + +script: phpunit diff --git a/vendor/monolog/monolog/CHANGELOG.mdown b/vendor/monolog/monolog/CHANGELOG.mdown new file mode 100644 index 0000000..ddaa16e --- /dev/null +++ b/vendor/monolog/monolog/CHANGELOG.mdown @@ -0,0 +1,38 @@ +* 1.1.0 (2012-04-23) + + Changes: + + * Added Monolog\Logger::isHandling() to check if a handler will + handle the given log level + * Added ChromePHPHandler + * Added MongoDBHandler + * Added GelfHandler (for use with Graylog2 servers) + * Added SocketHandler (for use with syslog-ng for example) + * Added NormalizerFormatter + * Added the possibility to change the activation strategy of the FingersCrossedHandler + * Added possibility to show microseconds in logs + * Added `server` and `referer` to WebProcessor output + +* 1.0.2 (2011-10-24) + + Changes: + + * Fixed bug in IE with large response headers and FirePHPHandler + +* 1.0.1 (2011-08-25) + + Changes: + + * Added MemoryPeakUsageProcessor and MemoryUsageProcessor + * Added Monolog\Logger::getName() to get a logger's channel name + +* 1.0.0 (2011-07-06) + + Changes: + + * Added IntrospectionProcessor to get info from where the logger was called + * Fixed WebProcessor in CLI + +* 1.0.0-RC1 (2011-07-01) + + * Initial release diff --git a/vendor/monolog/monolog/LICENSE b/vendor/monolog/monolog/LICENSE new file mode 100644 index 0000000..5df1c39 --- /dev/null +++ b/vendor/monolog/monolog/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) Jordi Boggiano + +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/monolog/monolog/README.mdown b/vendor/monolog/monolog/README.mdown new file mode 100644 index 0000000..786aac1 --- /dev/null +++ b/vendor/monolog/monolog/README.mdown @@ -0,0 +1,172 @@ +Monolog - Logging for PHP 5.3 +============================= + +[![Build Status](https://secure.travis-ci.org/Seldaek/monolog.png)](http://travis-ci.org/Seldaek/monolog) + +Usage +----- + + use Monolog\Logger; + use Monolog\Handler\StreamHandler; + + // create a log channel + $log = new Logger('name'); + $log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING)); + + // add records to the log + $log->addWarning('Foo'); + $log->addError('Bar'); + +Core Concepts +------------- + +Every Logger instance has a channel (name) and a stack of handlers. Whenever +you add a record to the logger, it traverses the handler stack. Each handler +decides whether it handled fully the record, and if so, the propagation of the +record ends there. + +This allow for flexible logging setups, for example having a FileHandler at +the bottom of the stack that will log anything to disk, and on top of that add +a MailHandler that will send emails only when an error message is logged. +Handlers also have a bubbling property which define whether they block the +record or not if they handled it. In this example, setting the MailHandler's +$bubble argument to true means that all records will propagate to the +FileHandler, even the errors that are handled by the MailHandler. + +You can create many Loggers, each defining a channel (e.g.: db, request, +router, ..) and each of them combining various handlers, which can be shared +or not. The channel is reflected in the logs and allows you to easily see or +filter records. + +Each Handler also has a Formatter, a default one with settings that make sense +will be created if you don't set one. The formatters normalize and format +incoming records so that they can be used by the handlers to output useful +information. + +Custom severity levels are not available. Only six levels (debug, info, +warning, error, critical, alert) are present for basic filtering purposes, but +for sorting and other use cases that would require flexibility, you should add +Processors to the Logger that can add extra information (tags, user ip, ..) to +the records before they are handled. + +Log Levels +---------- + +Monolog exposes 6 log levels. Although it is possible to add more by extending +the classes you need, these are generally enough. + +- **DEBUG** (100): Detailed debug information. + +- **INFO** (200): Interesting events. Examples: User logs in, SQL logs. + +- **WARNING** (300): Exceptional occurrences that are not errors. Examples: + Use of deprecated APIs, poor use of an API, undesirable things that are not + necessarily wrong. + +- **ERROR** (400): Runtime errors that do not require immediate action but + should typically be logged and monitored. + +- **CRITICAL** (500): Critical conditions. Example: Application component + unavailable, unexpected exception. + +- **ALERT** (550): Action must be taken immediately. Example: Entire website + down, database unavailable, etc. This should trigger the SMS alerts and wake + you up. + +Docs +==== + +**See the doc/ directory for more detailed documentation. The following is only a list of all parts that come with Monolog.** + +Handlers +-------- + +- _StreamHandler_: Logs records into any php stream, use this for log files. +- _RotatingFileHandler_: Logs records to a file and creates one logfile per day. + It will also delete files older than $maxFiles. You should use + [logrotate](http://linuxcommand.org/man_pages/logrotate8.html) for high profile + setups though, this is just meant as a quick and dirty solution. +- _FirePHPHandler_: Handler for [FirePHP](http://www.firephp.org/), providing + inline `console` messages within [FireBug](http://getfirebug.com/). +- _ChromePHPHandler_: Handler for [ChromePHP](http://www.chromephp.com/), providing + inline `console` messages within Chrome. +- _MongoDBHandler_: Handler to write records in MongoDB via a + [Mongo](http://pecl.php.net/package/mongo) extension connection. +- _NativeMailHandler_: Sends emails using PHP's mail() function. +- _SwiftMailerHandler_: Sends emails using a SwiftMailer instance. +- _SyslogHandler_: Logs records to the syslog. +- _GelfHandler_: Logs records to a [Graylog2](http://www.graylog2.org) server. +- _SocketHandler_: Logs records to [sockets](http://php.net/fsockopen), use this + for UNIX and TCP sockets. See an [example](https://github.com/Seldaek/monolog/blob/master/doc/sockets.md). + +Wrappers / Special Handlers +--------------------------- + +- _FingersCrossedHandler_: A very interesting wrapper. It takes a logger as + parameter and will accumulate log records of all levels until a record + exceeds the defined severity level. At which point it delivers all records, + including those of lower severity, to the handler it wraps. This means that + until an error actually happens you will not see anything in your logs, but + when it happens you will have the full information, including debug and info + records. This provides you with all the information you need, but only when + you need it. +- _NullHandler_: Any record it can handle will be thrown away. This can be used + to put on top of an existing handler stack to disable it temporarily. +- _BufferHandler_: This handler will buffer all the log records it receives + until close() is called at which point it will call handleBatch() on the + handler it wraps with all the log messages at once. This is very useful to + send an email with all records at once for example instead of having one mail + for every log record. +- _GroupHandler_: This handler groups other handlers. Every record received is + sent to all the handlers it is configured with. +- _TestHandler_: Used for testing, it records everything that is sent to it and + has accessors to read out the information. + +Formatters +---------- + +- _LineFormatter_: Formats a log record into a one-line string. +- _NormalizerFormatter_: Normalizes objects/resources down to strings so a record can easily be serialized/encoded. +- _JsonFormatter_: Encodes a log record into json. +- _WildfireFormatter_: Used to format log records into the Wildfire/FirePHP protocol, only useful for the FirePHPHandler. +- _ChromePHPFormatter_: Used to format log records into the ChromePHP format, only useful for the ChromePHPHandler. +- _GelfFormatter_: Used to format log records into Gelf message instances, only useful for the GelfHandler. + +Processors +---------- + +- _IntrospectionProcessor_: Adds the line/file/class/method from which the log call originated. +- _WebProcessor_: Adds the current request URI, request method and client IP to a log record. +- _MemoryUsageProcessor_: Adds the current memory usage to a log record. +- _MemoryPeakUsageProcessor_: Adds the peak memory usage to a log record. + +About +===== + +Requirements +------------ + +- Any flavor of PHP 5.3 should do +- [optional] PHPUnit 3.5+ to execute the test suite (phpunit --version) + +Submitting bugs and feature requests +------------------------------------ + +Bugs and feature request are tracked on [GitHub](https://github.com/Seldaek/monolog/issues) + +Author +------ + +Jordi Boggiano - -
    +See also the list of [contributors](https://github.com/Seldaek/monolog/contributors) which participated in this project. + +License +------- + +Monolog is licensed under the MIT License - see the LICENSE file for details + +Acknowledgements +---------------- + +This library is heavily inspired by Python's [Logbook](http://packages.python.org/Logbook/) +library, although most concepts have been adjusted to fit to the PHP world. diff --git a/vendor/monolog/monolog/composer.json b/vendor/monolog/monolog/composer.json new file mode 100644 index 0000000..c8c28b0 --- /dev/null +++ b/vendor/monolog/monolog/composer.json @@ -0,0 +1,27 @@ +{ + "name": "monolog/monolog", + "description": "Logging for PHP 5.3", + "keywords": ["log","logging"], + "homepage": "http://github.com/Seldaek/monolog", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "mlehner/gelf-php": "1.0.*" + }, + "suggest": { + "mlehner/gelf-php": "Allow sending log messages to a GrayLog2 server" + }, + "autoload": { + "psr-0": {"Monolog": "src/"} + } +} diff --git a/vendor/monolog/monolog/doc/extending.md b/vendor/monolog/monolog/doc/extending.md new file mode 100644 index 0000000..fcd7af2 --- /dev/null +++ b/vendor/monolog/monolog/doc/extending.md @@ -0,0 +1,76 @@ +Extending Monolog +================= + +Monolog is fully extensible, allowing you to adapt your logger to your needs. + +Writing your own handler +------------------------ + +Monolog provides many built-in handlers. But if the one you need does not +exist, you can write it and use it in your logger. The only requirement is +to implement `Monolog\Handler\HandlerInterface`. + +Let's write a PDOHandler to log records to a database. We will extend the +abstract class provided by Monolog to keep things DRY. + +```php +pdo = $pdo; + parent::__construct($level, $bubble); + } + + protected function write(array $record) + { + if (!$this->initialized) { + $this->initialize(); + } + + $this->statement->execute(array( + 'channel' => $record['channel'], + 'level' => $record['level'], + 'message' => $record['formatted'], + 'time' => $record['datetime']->format('U'), + )); + } + + private function initialize() + { + $this->pdo->exec( + 'CREATE TABLE IF NOT EXISTS monolog ' + .'(channel VARCHAR(255), level INTEGER, message LONGTEXT, time INTEGER UNSIGNED)' + ); + $this->statement = $this->pdo->prepare( + 'INSERT INTO monolog (channel, level, message, time) VALUES (:channel, :level, :message, :time)' + ); + + $this->initialized = true; + } +} +``` + +You can now use this handler in your logger: + +```php +pushHandler(new PDOHandler(new PDO('sqlite:logs.sqlite')); + +// You can now use your logger +$logger->addInfo('My logger is now ready'); +``` + +The `Monolog\Handler\AbstractProcessingHandler` class provides most of the +logic needed for the handler, including the use of processors and the formatting +of the record (which is why we use ``$record['formatted']`` instead of ``$record['message']``). diff --git a/vendor/monolog/monolog/doc/sockets.md b/vendor/monolog/monolog/doc/sockets.md new file mode 100644 index 0000000..fad30a9 --- /dev/null +++ b/vendor/monolog/monolog/doc/sockets.md @@ -0,0 +1,37 @@ +Sockets Handler +=============== + +This handler allows you to write your logs to sockets using [fsockopen](http://php.net/fsockopen) +or [pfsockopen](http://php.net/pfsockopen). + +Persistent sockets are mainly useful in web environments where you gain some performance not closing/opening +the connections between requests. + +Basic Example +------------- + +```php +setPersistent(true); + +// Now add the handler +$logger->pushHandler($handler, Logger::DEBUG); + +// You can now use your logger +$logger->addInfo('My logger is now ready'); + +``` + +In this example, using syslog-ng, you should see the log on the log server: + + cweb1 [2012-02-26 00:12:03] my_logger.INFO: My logger is now ready [] [] + diff --git a/vendor/monolog/monolog/doc/usage.md b/vendor/monolog/monolog/doc/usage.md new file mode 100644 index 0000000..a3cfc7f --- /dev/null +++ b/vendor/monolog/monolog/doc/usage.md @@ -0,0 +1,124 @@ +Using Monolog +============= + +Installation +------------ + +Monolog is available on Packagist ([monolog/monolog](http://packagist.org/packages/monolog/monolog)) +and as such installable via [Composer](http://getcomposer.org/). + +If you do not use Composer, you can grab the code from GitHub, and use any +PSR-0 compatible autoloader (e.g. the [Symfony2 ClassLoader component](https://github.com/symfony/ClassLoader)) +to load Monolog classes. + +Configuring a logger +-------------------- + +Here is a basic setup to log to a file and to firephp on the DEBUG level: + +```php +pushHandler(new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG)); +$logger->pushHandler(new FirePHPHandler()); + +// You can now use your logger +$logger->addInfo('My logger is now ready'); +``` + +Let's explain it. The first step is to create the logger instance which will +be used in your code. The argument is a channel name, which is useful when +you use several loggers (see below for more details about it). + +The logger itself does not know how to handle a record. It delegates it to +some handlers. The code above registers two handlers in the stack to allow +handling records in two different ways. + +Note that the FirePHPHandler is called first as it is added on top of the +stack. This allows you to temporarily add a logger with bubbling disabled if +you want to override other configured loggers. + +Adding extra data in the records +-------------------------------- + +Monolog provides two different ways to add extra informations along the simple +textual message. + +### Using the logging context + +The first way is the context, allowing to pass an array of data along the +record: + +```php +addInfo('Adding a new user', array('username' => 'Seldaek')); +``` + +Simple handlers (like the StreamHandler for instance) will simply format +the array to a string but richer handlers can take advantage of the context +(FirePHP is able to display arrays in pretty way for instance). + +### Using processors + +The second way is to add extra data for all records by using a processor. +Processors can be any callable. They will get the record as parameter and +must return it after having eventually changed the `extra` part of it. Let's +write a processor adding some dummy data in the record: + +```php +pushProcessor(function ($record) { + $record['extra']['dummy'] = 'Hello world!'; + + return $record; +}); +``` + +Monolog provides some built-in processors that can be used in your project. +Look at the README file for the list. + +> Tip: processors can also be registered on a specific handler instead of + the logger to apply only for this handler. + +Leveraging channels +------------------- + +Channels are a great way to identify to which part of the application a record +is related. This is useful in big applications (and is leveraged by +MonologBundle in Symfony2). You can then easily grep through log files for +example to filter this or that type of log record. + +Using different loggers with the same handlers allow to identify the logger +that issued the record (through the channel name) by keeping the same handlers +(for instance to use a single log file). + +```php +pushHandler($stream); +$logger->pushHandler($firephp); + +// Create a logger for the security-related stuff with a different channel +$securityLogger = new Logger('security'); +$securityLogger->pushHandler($stream); +$securityLogger->pushHandler($firephp); +``` diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php b/vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php new file mode 100644 index 0000000..44335b5 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.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 Monolog\Formatter; + +use Monolog\Logger; + +/** + * Formats a log message according to the ChromePHP array format + * + * @author Christophe Coevoet + */ +class ChromePHPFormatter implements FormatterInterface +{ + /** + * Translates Monolog log levels to Wildfire levels. + */ + private $logLevels = array( + Logger::DEBUG => 'log', + Logger::INFO => 'info', + Logger::WARNING => 'warn', + Logger::ERROR => 'error', + Logger::CRITICAL => 'error', + Logger::ALERT => 'error', + ); + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + // Retrieve the line and file if set and remove them from the formatted extra + $backtrace = 'unknown'; + if (isset($record['extra']['file']) && isset($record['extra']['line'])) { + $backtrace = $record['extra']['file'].' : '.$record['extra']['line']; + unset($record['extra']['file']); + unset($record['extra']['line']); + } + + $message = array('message' => $record['message']); + if ($record['context']) { + $message['context'] = $record['context']; + } + if ($record['extra']) { + $message['extra'] = $record['extra']; + } + if (count($message) === 1) { + $message = reset($message); + } + + return array( + $record['channel'], + $message, + $backtrace, + $this->logLevels[$record['level']], + ); + } + + public function formatBatch(array $records) + { + $formatted = array(); + + foreach ($records as $record) { + $formatted[] = $this->format($record); + } + + return $formatted; + } +} \ No newline at end of file diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php b/vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php new file mode 100644 index 0000000..77891de --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.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 Monolog\Formatter; + +/** + * Interface for formatters + * + * @author Jordi Boggiano + */ +interface FormatterInterface +{ + /** + * Formats a log record. + * + * @param array $record A record to format + * @return mixed The formatted record + */ + function format(array $record); + + /** + * Formats a set of log records. + * + * @param array $records A set of records to format + * @return mixed The formatted set of records + */ + function formatBatch(array $records); +} diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php b/vendor/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php new file mode 100644 index 0000000..95c17ad --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.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 Monolog\Formatter; + +use Monolog\Logger; +use Gelf\Message; + +/** + * Serializes a log message according to Wildfire's header requirements + * + * @author Matt Lehner + */ +class GelfMessageFormatter extends NormalizerFormatter +{ + /** + * @var string the name of the system for the Gelf log message + */ + protected $systemName; + + /** + * @var string a prefix for 'extra' fields from the Monolog record (optional) + */ + protected $extraPrefix; + + /** + * @var string a prefix for 'context' fields from the Monolog record (optional) + */ + protected $contextPrefix; + + /** + * Translates Monolog log levels to Graylog2 log priorities. + */ + private $logLevels = array( + Logger::DEBUG => LOG_DEBUG, + Logger::INFO => LOG_INFO, + Logger::WARNING => LOG_WARNING, + Logger::ERROR => LOG_ERR, + Logger::CRITICAL => LOG_CRIT, + Logger::ALERT => LOG_ALERT, + ); + + public function __construct($systemName = null, $extraPrefix = null, $contextPrefix = 'ctxt_') + { + parent::__construct('U.u'); + + $this->systemName = $systemName ?: gethostname(); + + $this->extraPrefix = $extraPrefix; + $this->contextPrefix = $contextPrefix; + } + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + $record = parent::format($record); + $message = new Message(); + $message + ->setTimestamp($record['datetime']) + ->setShortMessage((string) $record['message']) + ->setFacility($record['channel']) + ->setHost($this->systemName) + ->setLine(isset($record['extra']['line']) ? $record['extra']['line'] : null) + ->setFile(isset($record['extra']['file']) ? $record['extra']['file'] : null) + ->setLevel($this->logLevels[$record['level']]); + + // Do not duplicate these values in the additional fields + unset($record['extra']['line']); + unset($record['extra']['file']); + + foreach ($record['extra'] as $key => $val) { + $message->setAdditional($this->extraPrefix . $key, is_scalar($val) ? $val : $this->toJson($val)); + } + + foreach ($record['context'] as $key => $val) { + $message->setAdditional($this->contextPrefix . $key, is_scalar($val) ? $val : $this->toJson($val)); + } + + return $message; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php b/vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php new file mode 100644 index 0000000..ab20179 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.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 Monolog\Formatter; + +use Monolog\Logger; + +/** + * Encodes whatever record data is passed to it as json + * + * This can be useful to log to databases or remote APIs + * + * @author Jordi Boggiano + */ +class JsonFormatter implements FormatterInterface +{ + /** + * {@inheritdoc} + */ + public function format(array $record) + { + return json_encode($record); + } + + /** + * {@inheritdoc} + */ + public function formatBatch(array $records) + { + return json_encode($records); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php b/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php new file mode 100644 index 0000000..61d3b8c --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.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 Monolog\Formatter; + +use Monolog\Logger; + +/** + * Formats incoming records into a one-line string + * + * This is especially useful for logging to files + * + * @author Jordi Boggiano + * @author Christophe Coevoet + */ +class LineFormatter extends NormalizerFormatter +{ + const SIMPLE_FORMAT = "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"; + + protected $format; + + /** + * @param string $format The format of the message + * @param string $dateFormat The format of the timestamp: one supported by DateTime::format + */ + public function __construct($format = null, $dateFormat = null) + { + $this->format = $format ?: static::SIMPLE_FORMAT; + parent::__construct($dateFormat); + } + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + $vars = parent::format($record); + + $output = $this->format; + foreach ($vars['extra'] as $var => $val) { + if (false !== strpos($output, '%extra.'.$var.'%')) { + $output = str_replace('%extra.'.$var.'%', $this->convertToString($val), $output); + unset($vars['extra'][$var]); + } + } + foreach ($vars as $var => $val) { + $output = str_replace('%'.$var.'%', $this->convertToString($val), $output); + } + + return $output; + } + + public function formatBatch(array $records) + { + $message = ''; + foreach ($records as $record) { + $message .= $this->format($record); + } + + return $message; + } + + protected function normalize($data) + { + if (is_bool($data) || is_null($data)) { + return var_export($data, true); + } + + return parent::normalize($data); + } + + protected function convertToString($data) + { + if (null === $data || is_scalar($data)) { + return (string) $data; + } + + if (version_compare(PHP_VERSION, '5.4.0', '>=')) { + return json_encode($this->normalize($data), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); + } + + return stripslashes(json_encode($this->normalize($data))); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php b/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php new file mode 100644 index 0000000..09cadb7 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.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 Monolog\Formatter; + +use Monolog\Logger; + +/** + * Normalizes incoming records to remove objects/resources so it's easier to dump to various targets + * + * @author Jordi Boggiano + */ +class NormalizerFormatter implements FormatterInterface +{ + const SIMPLE_DATE = "Y-m-d H:i:s"; + + protected $dateFormat; + + /** + * @param string $dateFormat The format of the timestamp: one supported by DateTime::format + */ + public function __construct($dateFormat = null) + { + $this->dateFormat = $dateFormat ?: static::SIMPLE_DATE; + } + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + return $this->normalize($record); + } + + /** + * {@inheritdoc} + */ + public function formatBatch(array $records) + { + foreach ($records as $key => $record) { + $records[$key] = $this->format($record); + } + + return $records; + } + + protected function normalize($data) + { + if (null === $data || is_scalar($data)) { + return $data; + } + + if (is_array($data) || $data instanceof \Traversable) { + $normalized = array(); + + foreach ($data as $key => $value) { + $normalized[$key] = $this->normalize($value); + } + + return $normalized; + } + + if ($data instanceof \DateTime) { + return $data->format($this->dateFormat); + } + + if (is_resource($data)) { + return '[resource]'; + } + + return sprintf("[object] (%s: %s)", get_class($data), $this->toJson($data)); + } + + protected function toJson($data) + { + if (version_compare(PHP_VERSION, '5.4.0', '>=')) { + return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); + } + + return json_encode($data); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php b/vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php new file mode 100644 index 0000000..4c393a9 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.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 Monolog\Formatter; + +use Monolog\Logger; + +/** + * Serializes a log message according to Wildfire's header requirements + * + * @author Eric Clemmons (@ericclemmons) + * @author Christophe Coevoet + * @author Kirill chEbba Chebunin + */ +class WildfireFormatter implements FormatterInterface +{ + /** + * Translates Monolog log levels to Wildfire levels. + */ + private $logLevels = array( + Logger::DEBUG => 'LOG', + Logger::INFO => 'INFO', + Logger::WARNING => 'WARN', + Logger::ERROR => 'ERROR', + Logger::CRITICAL => 'ERROR', + Logger::ALERT => 'ERROR', + ); + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + // Retrieve the line and file if set and remove them from the formatted extra + $file = $line = ''; + if (isset($record['extra']['file'])) { + $file = $record['extra']['file']; + unset($record['extra']['file']); + } + if (isset($record['extra']['line'])) { + $line = $record['extra']['line']; + unset($record['extra']['line']); + } + + $message = array('message' => $record['message']); + if ($record['context']) { + $message['context'] = $record['context']; + } + if ($record['extra']) { + $message['extra'] = $record['extra']; + } + if (count($message) === 1) { + $message = reset($message); + } + + // Create JSON object describing the appearance of the message in the console + $json = json_encode(array( + array( + 'Type' => $this->logLevels[$record['level']], + 'File' => $file, + 'Line' => $line, + 'Label' => $record['channel'], + ), + $message, + )); + + // The message itself is a serialization of the above JSON object + it's length + return sprintf( + '%s|%s|', + strlen($json), + $json + ); + } + + public function formatBatch(array $records) + { + throw new \BadMethodCallException('Batch formatting does not make sense for the WildfireFormatter'); + } +} \ No newline at end of file diff --git a/vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php new file mode 100644 index 0000000..1349c25 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.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 Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\FormatterInterface; +use Monolog\Formatter\LineFormatter; + +/** + * Base Handler class providing the Handler structure + * + * @author Jordi Boggiano + */ +abstract class AbstractHandler implements HandlerInterface +{ + protected $level = Logger::DEBUG; + protected $bubble = false; + + /** + * @var FormatterInterface + */ + protected $formatter; + protected $processors = array(); + + /** + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($level = Logger::DEBUG, $bubble = true) + { + $this->level = $level; + $this->bubble = $bubble; + } + + /** + * {@inheritdoc} + */ + public function isHandling(array $record) + { + return $record['level'] >= $this->level; + } + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + foreach ($records as $record) { + $this->handle($record); + } + } + + /** + * Closes the handler. + * + * This will be called automatically when the object is destroyed + */ + public function close() + { + } + + /** + * {@inheritdoc} + */ + public function pushProcessor($callback) + { + if (!is_callable($callback)) { + throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), '.var_export($callback, true).' given'); + } + array_unshift($this->processors, $callback); + } + + /** + * {@inheritdoc} + */ + public function popProcessor() + { + if (!$this->processors) { + throw new \LogicException('You tried to pop from an empty processor stack.'); + } + return array_shift($this->processors); + } + + /** + * {@inheritdoc} + */ + public function setFormatter(FormatterInterface $formatter) + { + $this->formatter = $formatter; + } + + /** + * {@inheritdoc} + */ + public function getFormatter() + { + if (!$this->formatter) { + $this->formatter = $this->getDefaultFormatter(); + } + + return $this->formatter; + } + + /** + * Sets minimum logging level at which this handler will be triggered. + * + * @param integer $level + */ + public function setLevel($level) + { + $this->level = $level; + } + + /** + * Gets minimum logging level at which this handler will be triggered. + * + * @return integer + */ + public function getLevel() + { + return $this->level; + } + + /** + * Sets the bubbling behavior. + * + * @param Boolean $bubble True means that bubbling is not permitted. + * False means that this handler allows bubbling. + */ + public function setBubble($bubble) + { + $this->bubble = $bubble; + } + + /** + * Gets the bubbling behavior. + * + * @return Boolean True means that bubbling is not permitted. + * False means that this handler allows bubbling. + */ + public function getBubble() + { + return $this->bubble; + } + + public function __destruct() + { + try { + $this->close(); + } catch(\Exception $e) { + // do nothing + } + } + + /** + * Gets the default formatter. + * + * @return FormatterInterface + */ + protected function getDefaultFormatter() + { + return new LineFormatter(); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php new file mode 100644 index 0000000..9babe03 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.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 Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\FormatterInterface; +use Monolog\Formatter\LineFormatter; + +/** + * Base Handler class providing the Handler structure + * + * Classes extending it should (in most cases) only implement write($record) + * + * @author Jordi Boggiano + * @author Christophe Coevoet + */ +abstract class AbstractProcessingHandler extends AbstractHandler +{ + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if ($record['level'] < $this->level) { + return false; + } + + $record = $this->processRecord($record); + + $record['formatted'] = $this->getFormatter()->format($record); + + $this->write($record); + + return false === $this->bubble; + } + + /** + * Writes the record down to the log of the implementing handler + * + * @param array $record + * @return void + */ + abstract protected function write(array $record); + + /** + * Processes a record. + * + * @param array $record + * @return array + */ + protected function processRecord(array $record) + { + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = call_user_func($processor, $record); + } + } + + return $record; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.php new file mode 100644 index 0000000..7031607 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.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 Monolog\Handler; + +use Monolog\Logger; + +/** + * Buffers all records until closing the handler and then pass them as batch. + * + * This is useful for a MailHandler to send only one mail per request instead of + * sending one per log message. + * + * @author Christophe Coevoet + */ +class BufferHandler extends AbstractHandler +{ + protected $handler; + protected $bufferSize; + protected $buffer = array(); + + /** + * @param HandlerInterface $handler Handler. + * @param integer $bufferSize How many entries should be buffered at most, beyond that the oldest items are removed from the buffer. + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(HandlerInterface $handler, $bufferSize = 0, $level = Logger::DEBUG, $bubble = true) + { + parent::__construct($level, $bubble); + $this->handler = $handler; + $this->bufferSize = $bufferSize; + } + + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if ($record['level'] < $this->level) { + return false; + } + + $this->buffer[] = $record; + if ($this->bufferSize > 0 && count($this->buffer) > $this->bufferSize) { + array_shift($this->buffer); + } + + return false === $this->bubble; + } + + /** + * {@inheritdoc} + */ + public function close() + { + $this->handler->handleBatch($this->buffer); + } +} \ No newline at end of file diff --git a/vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php new file mode 100644 index 0000000..4d7ae8c --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.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 Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\ChromePHPFormatter; + +/** + * Handler sending logs to the ChromePHP extension (http://www.chromephp.com/) + * + * @author Christophe Coevoet + */ +class ChromePHPHandler extends AbstractProcessingHandler +{ + /** + * Version of the extension + */ + const VERSION = '3.0'; + + /** + * Header name + */ + const HEADER_NAME = 'X-ChromePhp-Data'; + + static protected $initialized = false; + + static protected $json = array( + 'version' => self::VERSION, + 'columns' => array('label', 'log', 'backtrace', 'type'), + 'rows' => array(), + ); + + protected $sendHeaders = true; + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + $messages = array(); + + foreach ($records as $record) { + if ($record['level'] < $this->level) { + continue; + } + $messages[] = $this->processRecord($record); + } + + if (!empty($messages)) { + $messages = $this->getFormatter()->formatBatch($messages); + self::$json['rows'] = array_merge(self::$json['rows'], $messages); + $this->send(); + } + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new ChromePHPFormatter(); + } + + /** + * Creates & sends header for a record + * + * @see sendHeader() + * @see send() + * @param array $record + */ + protected function write(array $record) + { + self::$json['rows'][] = $record['formatted']; + + $this->send(); + } + + /** + * Sends the log header + * + * @see sendHeader() + */ + protected function send() + { + if (!self::$initialized) { + $this->sendHeaders = $this->headersAccepted(); + self::$json['request_uri'] = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : ''; + + self::$initialized = true; + } + + $this->sendHeader(self::HEADER_NAME, base64_encode(utf8_encode(json_encode(self::$json)))); + } + + /** + * Send header string to the client + * + * @param string $header + * @param string $content + */ + protected function sendHeader($header, $content) + { + if (!headers_sent() && $this->sendHeaders) { + header(sprintf('%s: %s', $header, $content)); + } + } + + /** + * Verifies if the headers are accepted by the current user agent + * + * @return Boolean + */ + protected function headersAccepted() + { + return !isset($_SERVER['HTTP_USER_AGENT']) + || preg_match('{\bChrome/\d+[\.\d+]*\b}', $_SERVER['HTTP_USER_AGENT']); + } +} \ No newline at end of file diff --git a/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php b/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php new file mode 100644 index 0000000..54b9a8d --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.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 Monolog\Handler\FingersCrossed; + +/** + * Interface for activation strategies for the FingersCrossedHandler. + * + * @author Johannes M. Schmitt + */ +interface ActivationStrategyInterface +{ + /** + * Returns whether the given record activates the handler. + * + * @param array $record + * @return Boolean + */ + function isHandlerActivated(array $record); +} \ No newline at end of file diff --git a/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php b/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php new file mode 100644 index 0000000..2cfe6dd --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.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 Monolog\Handler\FingersCrossed; + +/** + * Error level based activation strategy. + * + * @author Johannes M. Schmitt + */ +class ErrorLevelActivationStrategy implements ActivationStrategyInterface +{ + private $actionLevel; + + public function __construct($actionLevel) + { + $this->actionLevel = $actionLevel; + } + + public function isHandlerActivated(array $record) + { + return $record['level'] >= $this->actionLevel; + } +} \ No newline at end of file diff --git a/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php new file mode 100644 index 0000000..3731fa8 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.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 Monolog\Handler; + +use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy; +use Monolog\Handler\FingersCrossed\ActivationStrategyInterface; +use Monolog\Logger; + +/** + * Buffers all records until a certain level is reached + * + * The advantage of this approach is that you don't get any clutter in your log files. + * Only requests which actually trigger an error (or whatever your actionLevel is) will be + * in the logs, but they will contain all records, not only those above the level threshold. + * + * @author Jordi Boggiano + */ +class FingersCrossedHandler extends AbstractHandler +{ + protected $handler; + protected $activationStrategy; + protected $buffering = true; + protected $bufferSize; + protected $buffer = array(); + protected $stopBuffering; + + /** + * @param callback|HandlerInterface $handler Handler or factory callback($record, $fingersCrossedHandler). + * @param int|ActivationStrategyInterface $activationStrategy Strategy which determines when this handler takes action + * @param int $bufferSize How many entries should be buffered at most, beyond that the oldest items are removed from the buffer. + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param Boolean $stopBuffering Whether the handler should stop buffering after being triggered (default true) + */ + public function __construct($handler, $activationStrategy = null, $bufferSize = 0, $bubble = true, $stopBuffering = true) + { + if (null === $activationStrategy) { + $activationStrategy = new ErrorLevelActivationStrategy(Logger::WARNING); + } + if (!$activationStrategy instanceof ActivationStrategyInterface) { + $activationStrategy = new ErrorLevelActivationStrategy($activationStrategy); + } + + $this->handler = $handler; + $this->activationStrategy = $activationStrategy; + $this->bufferSize = $bufferSize; + $this->bubble = $bubble; + $this->stopBuffering = $stopBuffering; + } + + /** + * {@inheritdoc} + */ + public function isHandling(array $record) + { + return true; + } + + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if ($this->buffering) { + $this->buffer[] = $record; + if ($this->bufferSize > 0 && count($this->buffer) > $this->bufferSize) { + array_shift($this->buffer); + } + if ($this->activationStrategy->isHandlerActivated($record)) { + if ($this->stopBuffering) { + $this->buffering = false; + } + if (!$this->handler instanceof HandlerInterface) { + $this->handler = call_user_func($this->handler, $record, $this); + } + if (!$this->handler instanceof HandlerInterface) { + throw new \RuntimeException("The factory callback should return a HandlerInterface"); + } + $this->handler->handleBatch($this->buffer); + $this->buffer = array(); + } + } else { + $this->handler->handle($record); + } + + return false === $this->bubble; + } + + /** + * Resets the state of the handler. Stops forwarding records to the wrapped handler. + */ + public function reset() + { + $this->buffering = true; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php new file mode 100644 index 0000000..8cc10e9 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php @@ -0,0 +1,161 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\WildfireFormatter; + +/** + * Simple FirePHP Handler (http://www.firephp.org/), which uses the Wildfire protocol. + * + * @author Eric Clemmons (@ericclemmons) + */ +class FirePHPHandler extends AbstractProcessingHandler +{ + /** + * WildFire JSON header message format + */ + const PROTOCOL_URI = 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2'; + + /** + * FirePHP structure for parsing messages & their presentation + */ + const STRUCTURE_URI = 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'; + + /** + * Must reference a "known" plugin, otherwise headers won't display in FirePHP + */ + const PLUGIN_URI = 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3'; + + /** + * Header prefix for Wildfire to recognize & parse headers + */ + const HEADER_PREFIX = 'X-Wf'; + + /** + * Whether or not Wildfire vendor-specific headers have been generated & sent yet + */ + protected static $initialized = false; + + /** + * Shared static message index between potentially multiple handlers + * @var int + */ + protected static $messageIndex = 1; + + protected $sendHeaders = true; + + /** + * Base header creation function used by init headers & record headers + * + * @param array $meta Wildfire Plugin, Protocol & Structure Indexes + * @param string $message Log message + * @return array Complete header string ready for the client as key and message as value + */ + protected function createHeader(array $meta, $message) + { + $header = sprintf('%s-%s', self::HEADER_PREFIX, join('-', $meta)); + + return array($header => $message); + } + + /** + * Creates message header from record + * + * @see createHeader() + * @param array $record + * @return string + */ + protected function createRecordHeader(array $record) + { + // Wildfire is extensible to support multiple protocols & plugins in a single request, + // but we're not taking advantage of that (yet), so we're using "1" for simplicity's sake. + return $this->createHeader( + array(1, 1, 1, self::$messageIndex++), + $record['formatted'] + ); + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new WildfireFormatter(); + } + + /** + * Wildfire initialization headers to enable message parsing + * + * @see createHeader() + * @see sendHeader() + * @return array + */ + protected function getInitHeaders() + { + // Initial payload consists of required headers for Wildfire + return array_merge( + $this->createHeader(array('Protocol', 1), self::PROTOCOL_URI), + $this->createHeader(array(1, 'Structure', 1), self::STRUCTURE_URI), + $this->createHeader(array(1, 'Plugin', 1), self::PLUGIN_URI) + ); + } + + /** + * Send header string to the client + * + * @param string $header + * @param string $content + */ + protected function sendHeader($header, $content) + { + if (!headers_sent() && $this->sendHeaders) { + header(sprintf('%s: %s', $header, $content)); + } + } + + /** + * Creates & sends header for a record, ensuring init headers have been sent prior + * + * @see sendHeader() + * @see sendInitHeaders() + * @param array $record + */ + protected function write(array $record) + { + // WildFire-specific headers must be sent prior to any messages + if (!self::$initialized) { + $this->sendHeaders = $this->headersAccepted(); + + foreach ($this->getInitHeaders() as $header => $content) { + $this->sendHeader($header, $content); + } + + self::$initialized = true; + } + + $header = $this->createRecordHeader($record); + $this->sendHeader(key($header), current($header)); + } + + /** + * Verifies if the headers are accepted by the current user agent + * + * @return Boolean + */ + protected function headersAccepted() + { + return !isset($_SERVER['HTTP_USER_AGENT']) + || preg_match('{\bFirePHP/\d+\.\d+\b}', $_SERVER['HTTP_USER_AGENT']) + || isset($_SERVER['HTTP_X_FIREPHP_VERSION']); + } +} \ No newline at end of file diff --git a/vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.php new file mode 100644 index 0000000..7346029 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.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 Monolog\Handler; + +use Gelf\IMessagePublisher; +use Monolog\Logger; +use Monolog\Handler\AbstractProcessingHandler; +use Monolog\Formatter\GelfMessageFormatter; + +/** + * Handler to send messages to a Graylog2 (http://www.graylog2.org) server + * + * @author Matt Lehner + */ +class GelfHandler extends AbstractProcessingHandler +{ + /** + * @var Gelf\IMessagePublisher the publisher object that sends the message to the server + */ + protected $publisher; + + /** + * @param Gelf\IMessagePublisher $publisher a publisher object + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(IMessagePublisher $publisher, $level = Logger::DEBUG, $bubble = true) + { + parent::__construct($level, $bubble); + + $this->publisher = $publisher; + } + + /** + * {@inheritdoc} + */ + public function close() + { + $this->publisher = null; + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $this->publisher->publish($record['formatted']); + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new GelfMessageFormatter(); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/GroupHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/GroupHandler.php new file mode 100644 index 0000000..c94c52f --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/GroupHandler.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 Monolog\Handler; + +/** + * Forwards records to multiple handlers + * + * @author Lenar Lõhmus + */ +class GroupHandler extends AbstractHandler +{ + protected $handlers; + + /** + * @param array $handlers Array of Handlers. + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(array $handlers, $bubble = true) + { + foreach ($handlers as $handler) { + if (!$handler instanceof HandlerInterface) { + throw new \InvalidArgumentException('The first argument of the GroupHandler must be an array of HandlerInterface instances.'); + } + } + + $this->handlers = $handlers; + $this->bubble = $bubble; + } + + /** + * {@inheritdoc} + */ + public function isHandling(array $record) + { + foreach ($this->handlers as $handler) { + if ($handler->isHandling($record)) { + return true; + } + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + foreach ($this->handlers as $handler) { + $handler->handle($record); + } + + return false === $this->bubble; + } + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + foreach ($this->handlers as $handler) { + $handler->handleBatch($records); + } + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/HandlerInterface.php b/vendor/monolog/monolog/src/Monolog/Handler/HandlerInterface.php new file mode 100644 index 0000000..24f82d7 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/HandlerInterface.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 Monolog\Handler; + +use Monolog\Formatter\FormatterInterface; + +/** + * Interface that all Monolog Handlers must implement + * + * @author Jordi Boggiano + */ +interface HandlerInterface +{ + /** + * Checks whether the given record will be handled by this handler. + * + * This is mostly done for performance reasons, to avoid calling processors for nothing. + * + * @return Boolean + */ + function isHandling(array $record); + + /** + * Handles a record. + * + * The return value of this function controls the bubbling process of the handler stack. + * + * @param array $record The record to handle + * @return Boolean True means that this handler handled the record, and that bubbling is not permitted. + * False means the record was either not processed or that this handler allows bubbling. + */ + function handle(array $record); + + /** + * Handles a set of records at once. + * + * @param array $records The records to handle (an array of record arrays) + */ + function handleBatch(array $records); + + /** + * Adds a processor in the stack. + * + * @param callable $callback + */ + function pushProcessor($callback); + + /** + * Removes the processor on top of the stack and returns it. + * + * @return callable + */ + function popProcessor(); + + /** + * Sets the formatter. + * + * @param FormatterInterface $formatter + */ + function setFormatter(FormatterInterface $formatter); + + /** + * Gets the formatter. + * + * @return FormatterInterface + */ + function getFormatter(); +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/MailHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/MailHandler.php new file mode 100644 index 0000000..94ed841 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/MailHandler.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 Monolog\Handler; + +/** + * Base class for all mail handlers + * + * @author Gyula Sallai + */ +abstract class MailHandler extends AbstractProcessingHandler +{ + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + $messages = array(); + + foreach ($records as $record) { + if ($record['level'] < $this->level) { + continue; + } + $messages[] = $this->processRecord($record); + } + + if (!empty($messages)) { + $this->send((string) $this->getFormatter()->formatBatch($messages), $messages); + } + } + + /** + * Send a mail with the given content + * + * @param string $content + * @param array $records the array of log records that formed this content + */ + abstract protected function send($content, array $records); + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $this->send((string) $record['formatted'], array($record)); + } +} \ No newline at end of file diff --git a/vendor/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php new file mode 100644 index 0000000..210bb19 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/MongoDBHandler.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 Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\NormalizerFormatter; + +/** + * Logs to a MongoDB database. + * + * usage example: + * + * $log = new Logger('application'); + * $mongodb = new MongoDBHandler(new \Mongo("mongodb://localhost:27017"), "logs", "prod"); + * $log->pushHandler($mongodb); + * + * @author Thomas Tourlourat + */ +class MongoDBHandler extends AbstractProcessingHandler +{ + private $mongoCollection; + + public function __construct(\Mongo $mongo, $database, $collection, $level = Logger::DEBUG, $bubble = true) + { + $this->mongoCollection = $mongo->selectCollection($database, $collection); + + parent::__construct($level, $bubble); + } + + protected function write(array $record) + { + $this->mongoCollection->save($record["formatted"]); + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new NormalizerFormatter(); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php new file mode 100644 index 0000000..6933ff6 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.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 Monolog\Handler; + +use Monolog\Logger; + +/** + * NativeMailerHandler uses the mail() function to send the emails + * + * @author Christophe Coevoet + */ +class NativeMailerHandler extends MailHandler +{ + protected $to; + protected $subject; + protected $headers; + + /** + * @param string $to The receiver of the mail + * @param string $subject The subject of the mail + * @param string $from The sender of the mail + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($to, $subject, $from, $level = Logger::ERROR, $bubble = true) + { + parent::__construct($level, $bubble); + $this->to = $to; + $this->subject = $subject; + $this->headers = sprintf("From: %s\r\nContent-type: text/plain; charset=utf-8\r\n", $from); + } + + /** + * {@inheritdoc} + */ + protected function send($content, array $records) + { + mail($this->to, $this->subject, wordwrap($content, 70), $this->headers); + } +} \ No newline at end of file diff --git a/vendor/monolog/monolog/src/Monolog/Handler/NullHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/NullHandler.php new file mode 100644 index 0000000..7caf4a2 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/NullHandler.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 Monolog\Handler; + +use Monolog\Logger; + +/** + * Blackhole + * + * Any record it can handle will be thrown away. This can be used + * to put on top of an existing stack to override it temporarily. + * + * @author Jordi Boggiano + */ +class NullHandler extends AbstractHandler +{ + /** + * @param integer $level The minimum logging level at which this handler will be triggered + */ + public function __construct($level = Logger::DEBUG) + { + parent::__construct($level, false); + } + + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if ($record['level'] < $this->level) { + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php new file mode 100644 index 0000000..ebecd56 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.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 Monolog\Handler; + +use Monolog\Logger; + +/** + * Stores logs to files that are rotated every day and a limited number of files are kept. + * + * This rotation is only intended to be used as a workaround. Using logrotate to + * handle the rotation is strongly encouraged when you can use it. + * + * @author Christophe Coevoet + */ +class RotatingFileHandler extends StreamHandler +{ + protected $filename; + protected $maxFiles; + protected $mustRotate; + + /** + * @param string $filename + * @param integer $maxFiles The maximal amount of files to keep (0 means unlimited) + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($filename, $maxFiles = 0, $level = Logger::DEBUG, $bubble = true) + { + $this->filename = $filename; + $this->maxFiles = (int) $maxFiles; + + $fileInfo = pathinfo($this->filename); + $timedFilename = $fileInfo['dirname'].'/'.$fileInfo['filename'].'-'.date('Y-m-d'); + if (!empty($fileInfo['extension'])) { + $timedFilename .= '.'.$fileInfo['extension']; + } + + // disable rotation upfront if files are unlimited + if (0 === $this->maxFiles) { + $this->mustRotate = false; + } + + parent::__construct($timedFilename, $level, $bubble); + } + + /** + * {@inheritdoc} + */ + public function close() + { + parent::close(); + + if (true === $this->mustRotate) { + $this->rotate(); + } + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + // on the first record written, if the log is new, we should rotate (once per day) + if (null === $this->mustRotate) { + $this->mustRotate = !file_exists($this->url); + } + + parent::write($record); + } + + /** + * Rotates the files. + */ + protected function rotate() + { + $fileInfo = pathinfo($this->filename); + $glob = $fileInfo['dirname'].'/'.$fileInfo['filename'].'-*'; + if (!empty($fileInfo['extension'])) { + $glob .= '.'.$fileInfo['extension']; + } + $iterator = new \GlobIterator($glob); + $count = $iterator->count(); + if ($this->maxFiles >= $count) { + // no files to remove + return; + } + + // Sorting the files by name to remove the older ones + $array = iterator_to_array($iterator); + usort($array, function($a, $b) { + return strcmp($b->getFilename(), $a->getFilename()); + }); + + foreach (array_slice($array, $this->maxFiles) as $file) { + if ($file->isWritable()) { + unlink($file->getRealPath()); + } + } + } +} \ No newline at end of file diff --git a/vendor/monolog/monolog/src/Monolog/Handler/SocketHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/SocketHandler.php new file mode 100644 index 0000000..b44fad7 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/SocketHandler.php @@ -0,0 +1,272 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Stores to any socket - uses fsockopen() or pfsockopen(). + * + * @author Pablo de Leon Belloc + * @see http://php.net/manual/en/function.fsockopen.php + */ +class SocketHandler extends AbstractProcessingHandler +{ + private $connectionString; + private $connectionTimeout; + private $resource; + private $timeout = 0; + private $persistent = false; + private $errno; + private $errstr; + + /** + * @param string $connectionString Socket connection string + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($connectionString, $level = Logger::DEBUG, $bubble = true) + { + parent::__construct($level, $bubble); + $this->connectionString = $connectionString; + $this->connectionTimeout = (float) ini_get('default_socket_timeout'); + } + + /** + * Connect (if necessary) and write to the socket + * + * @param array $record + * + * @throws \UnexpectedValueException + * @throws \RuntimeException + */ + public function write(array $record) + { + $this->connectIfNotConnected(); + $this->writeToSocket((string) $record['formatted']); + } + + /** + * We will not close a PersistentSocket instance so it can be reused in other requests. + */ + public function close() + { + if (!$this->isPersistent()) { + $this->closeSocket(); + } + } + + /** + * Close socket, if open + */ + public function closeSocket() + { + if (is_resource($this->resource)) { + fclose($this->resource); + $this->resource = null; + } + } + + /** + * Set socket connection to nbe persistent. It only has effect before the connection is initiated. + * + * @param type $boolean + */ + public function setPersistent($boolean) + { + $this->persistent = (boolean) $boolean; + } + + /** + * Set connection timeout. Only has effect before we connect. + * + * @param integer $seconds + * + * @see http://php.net/manual/en/function.fsockopen.php + */ + public function setConnectionTimeout($seconds) + { + $this->validateTimeout($seconds); + $this->connectionTimeout = (float) $seconds; + } + + /** + * Set write timeout. Only has effect before we connect. + * + * @param type $seconds + * + * @see http://php.net/manual/en/function.stream-set-timeout.php + */ + public function setTimeout($seconds) + { + $this->validateTimeout($seconds); + $this->timeout = (int) $seconds; + } + + /** + * Get current connection string + * + * @return string + */ + public function getConnectionString() + { + return $this->connectionString; + } + + /** + * Get persistent setting + * + * @return boolean + */ + public function isPersistent() + { + return $this->persistent; + } + + /** + * Get current connection timeout setting + * + * @return float + */ + public function getConnectionTimeout() + { + return $this->connectionTimeout; + } + + /** + * Get current in-transfer timeout + * + * @return float + */ + public function getTimeout() + { + return $this->timeout; + } + + /** + * Check to see if the socket is currently available. + * + * UDP might appear to be connected but might fail when writing. See http://php.net/fsockopen for details. + * + * @return boolean + */ + public function isConnected() + { + return is_resource($this->resource) + && !feof($this->resource); // on TCP - other party can close connection. + } + + /** + * Wrapper to allow mocking + */ + protected function pfsockopen() + { + return @pfsockopen($this->connectionString, -1, $this->errno, $this->errstr, $this->connectionTimeout); + } + + /** + * Wrapper to allow mocking + */ + protected function fsockopen() + { + return @fsockopen($this->connectionString, -1, $this->errno, $this->errstr, $this->connectionTimeout); + } + + /** + * Wrapper to allow mocking + */ + protected function streamSetTimeout() + { + return stream_set_timeout($this->resource, $this->timeout); + } + + /** + * Wrapper to allow mocking + */ + protected function fwrite($data) + { + return @fwrite($this->resource, $data); + } + + /** + * Wrapper to allow mocking + */ + protected function streamGetMetadata() + { + return stream_get_meta_data($this->resource); + } + + private function validateTimeout($value) + { + $ok = filter_var($value, FILTER_VALIDATE_INT, array('options' => array( + 'min_range' => 0, + ))); + if ($ok === false) { + throw new \InvalidArgumentException("Timeout must be 0 or a positive integer (got $value)"); + } + } + + private function connectIfNotConnected() + { + if ($this->isConnected()) { + return; + } + $this->connect(); + } + + private function connect() + { + $this->createSocketResource(); + $this->setSocketTimeout(); + } + + private function createSocketResource() + { + if ($this->isPersistent()) { + $resource = $this->pfsockopen(); + } else { + $resource = $this->fsockopen(); + } + if (!$resource) { + throw new \UnexpectedValueException("Failed connecting to $this->connectionString ($this->errno: $this->errstr)"); + } + $this->resource = $resource; + } + + private function setSocketTimeout() + { + if (!$this->streamSetTimeout()) { + throw new \UnexpectedValueException("Failed setting timeout with stream_set_timeout()"); + } + } + + private function writeToSocket($data) + { + $length = strlen($data); + $sent = 0; + while ($this->isConnected() && $sent < $length) { + $chunk = $this->fwrite(substr($data, $sent)); + if ($chunk === false) { + throw new \RuntimeException("Could not write to socket"); + } + $sent += $chunk; + $socketInfo = $this->streamGetMetadata(); + if ($socketInfo['timed_out']) { + throw new \RuntimeException("Write timed-out"); + } + } + if (!$this->isConnected() && $sent < $length) { + throw new \RuntimeException("End-of-file reached, probably we got disconnected (sent $sent of $length)"); + } + } + +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php new file mode 100644 index 0000000..5593054 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.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 Monolog\Handler; + +use Monolog\Logger; + +/** + * Stores to any stream resource + * + * Can be used to store into php://stderr, remote and local files, etc. + * + * @author Jordi Boggiano + */ +class StreamHandler extends AbstractProcessingHandler +{ + protected $stream; + protected $url; + + /** + * @param string $stream + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($stream, $level = Logger::DEBUG, $bubble = true) + { + parent::__construct($level, $bubble); + if (is_resource($stream)) { + $this->stream = $stream; + } else { + $this->url = $stream; + } + } + + /** + * {@inheritdoc} + */ + public function close() + { + if (is_resource($this->stream)) { + fclose($this->stream); + } + $this->stream = null; + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + if (null === $this->stream) { + if (!$this->url) { + throw new \LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().'); + } + $this->stream = @fopen($this->url, 'a'); + if (!is_resource($this->stream)) { + $this->stream = null; + throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened; it may be invalid or not writable.', $this->url)); + } + } + fwrite($this->stream, (string) $record['formatted']); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.php new file mode 100644 index 0000000..addc4c4 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.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 Monolog\Handler; + +use Monolog\Logger; + +/** + * SwiftMailerHandler uses Swift_Mailer to send the emails + * + * @author Gyula Sallai + */ +class SwiftMailerHandler extends MailHandler +{ + protected $mailer; + protected $message; + + /** + * @param \Swift_Mailer $mailer The mailer to use + * @param callback|\Swift_Message $message An example message for real messages, only the body will be replaced + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(\Swift_Mailer $mailer, $message, $level = Logger::ERROR, $bubble = true) + { + parent::__construct($level, $bubble); + $this->mailer = $mailer; + if (!$message instanceof \Swift_Message && is_callable($message)) { + $message = call_user_func($message); + } + if (!$message instanceof \Swift_Message) { + throw new \InvalidArgumentException('You must provide either a Swift_Message instance or a callback returning it'); + } + $this->message = $message; + } + + /** + * {@inheritdoc} + */ + protected function send($content, array $records) + { + $message = clone $this->message; + $message->setBody($content); + + $this->mailer->send($message); + } +} \ No newline at end of file diff --git a/vendor/monolog/monolog/src/Monolog/Handler/SyslogHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/SyslogHandler.php new file mode 100644 index 0000000..444a592 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/SyslogHandler.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 Monolog\Handler; + +use Monolog\Logger; + +/** + * Logs to syslog service. + * + * usage example: + * + * $log = new Logger('application'); + * $syslog = new SyslogHandler('myfacility', 'local6'); + * $formatter = new LineFormatter("%channel%.%level_name%: %message% %extra%"); + * $syslog->setFormatter($formatter); + * $log->pushHandler($syslog); + * + * @author Sven Paulus + */ +class SyslogHandler extends AbstractProcessingHandler +{ + /** + * Translates Monolog log levels to syslog log priorities. + */ + private $logLevels = array( + Logger::DEBUG => LOG_DEBUG, + Logger::INFO => LOG_INFO, + Logger::WARNING => LOG_WARNING, + Logger::ERROR => LOG_ERR, + Logger::CRITICAL => LOG_CRIT, + Logger::ALERT => LOG_ALERT, + ); + + /** + * List of valid log facility names. + */ + private $facilities = array( + 'auth' => LOG_AUTH, + 'authpriv' => LOG_AUTHPRIV, + 'cron' => LOG_CRON, + 'daemon' => LOG_DAEMON, + 'kern' => LOG_KERN, + 'lpr' => LOG_LPR, + 'mail' => LOG_MAIL, + 'news' => LOG_NEWS, + 'syslog' => LOG_SYSLOG, + 'user' => LOG_USER, + 'uucp' => LOG_UUCP, + ); + + /** + * @param string $ident + * @param mixed $facility + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($ident, $facility = LOG_USER, $level = Logger::DEBUG, $bubble = true) + { + parent::__construct($level, $bubble); + + if (!defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->facilities['local0'] = LOG_LOCAL0; + $this->facilities['local1'] = LOG_LOCAL1; + $this->facilities['local2'] = LOG_LOCAL2; + $this->facilities['local3'] = LOG_LOCAL3; + $this->facilities['local4'] = LOG_LOCAL4; + $this->facilities['local5'] = LOG_LOCAL5; + $this->facilities['local6'] = LOG_LOCAL6; + $this->facilities['local7'] = LOG_LOCAL7; + } + + // convert textual description of facility to syslog constant + if (array_key_exists(strtolower($facility), $this->facilities)) { + $facility = $this->facilities[strtolower($facility)]; + } else if (!in_array($facility, array_values($this->facilities), true)) { + throw new \UnexpectedValueException('Unknown facility value "'.$facility.'" given'); + } + + if (!openlog($ident, LOG_PID, $facility)) { + throw new \LogicException('Can\'t open syslog for ident "'.$ident.'" and facility "'.$facility.'"'); + } + } + + /** + * {@inheritdoc} + */ + public function close() + { + closelog(); + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + syslog($this->logLevels[$record['level']], (string) $record['formatted']); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/TestHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/TestHandler.php new file mode 100644 index 0000000..8f47855 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/TestHandler.php @@ -0,0 +1,120 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Used for testing purposes. + * + * It records all records and gives you access to them for verification. + * + * @author Jordi Boggiano + */ +class TestHandler extends AbstractProcessingHandler +{ + protected $records = array(); + protected $recordsByLevel = array(); + + public function getRecords() + { + return $this->records; + } + + public function hasAlert($record) + { + return $this->hasRecord($record, Logger::ALERT); + } + + public function hasCritical($record) + { + return $this->hasRecord($record, Logger::CRITICAL); + } + + public function hasError($record) + { + return $this->hasRecord($record, Logger::ERROR); + } + + public function hasWarning($record) + { + return $this->hasRecord($record, Logger::WARNING); + } + + public function hasInfo($record) + { + return $this->hasRecord($record, Logger::INFO); + } + + public function hasDebug($record) + { + return $this->hasRecord($record, Logger::DEBUG); + } + + public function hasAlertRecords() + { + return isset($this->recordsByLevel[Logger::ALERT]); + } + + public function hasCriticalRecords() + { + return isset($this->recordsByLevel[Logger::CRITICAL]); + } + + public function hasErrorRecords() + { + return isset($this->recordsByLevel[Logger::ERROR]); + } + + public function hasWarningRecords() + { + return isset($this->recordsByLevel[Logger::WARNING]); + } + + public function hasInfoRecords() + { + return isset($this->recordsByLevel[Logger::INFO]); + } + + public function hasDebugRecords() + { + return isset($this->recordsByLevel[Logger::DEBUG]); + } + + protected function hasRecord($record, $level) + { + if (!isset($this->recordsByLevel[$level])) { + return false; + } + + if (is_array($record)) { + $record = $record['message']; + } + + foreach ($this->recordsByLevel[$level] as $rec) { + if ($rec['message'] === $record) { + return true; + } + } + + return false; + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $this->recordsByLevel[$record['level']][] = $record; + $this->records[] = $record; + } +} \ No newline at end of file diff --git a/vendor/monolog/monolog/src/Monolog/Logger.php b/vendor/monolog/monolog/src/Monolog/Logger.php new file mode 100644 index 0000000..91a6ca4 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Logger.php @@ -0,0 +1,421 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog; + +use Monolog\Handler\HandlerInterface; +use Monolog\Handler\StreamHandler; + +/** + * Monolog log channel + * + * It contains a stack of Handlers and a stack of Processors, + * and uses them to store records that are added to it. + * + * @author Jordi Boggiano + */ +class Logger +{ + /** + * Detailed debug information + */ + const DEBUG = 100; + + /** + * Interesting events + * + * Examples: User logs in, SQL logs. + */ + const INFO = 200; + + /** + * Exceptional occurrences that are not errors + * + * Examples: Use of deprecated APIs, poor use of an API, + * undesirable things that are not necessarily wrong. + */ + const WARNING = 300; + + /** + * Runtime errors + */ + const ERROR = 400; + + /** + * Critical conditions + * + * Example: Application component unavailable, unexpected exception. + */ + const CRITICAL = 500; + + /** + * Action must be taken immediately + * + * Example: Entire website down, database unavailable, etc. + * This should trigger the SMS alerts and wake you up. + */ + const ALERT = 550; + + protected static $levels = array( + 100 => 'DEBUG', + 200 => 'INFO', + 300 => 'WARNING', + 400 => 'ERROR', + 500 => 'CRITICAL', + 550 => 'ALERT', + ); + + protected $name; + + /** + * The handler stack + * + * @var array of Monolog\Handler\HandlerInterface + */ + protected $handlers = array(); + + protected $processors = array(); + + /** + * @param string $name The logging channel + */ + public function __construct($name) + { + $this->name = $name; + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Pushes a handler on to the stack. + * + * @param HandlerInterface $handler + */ + public function pushHandler(HandlerInterface $handler) + { + array_unshift($this->handlers, $handler); + } + + /** + * Pops a handler from the stack + * + * @return HandlerInterface + */ + public function popHandler() + { + if (!$this->handlers) { + throw new \LogicException('You tried to pop from an empty handler stack.'); + } + return array_shift($this->handlers); + } + + /** + * Adds a processor on to the stack. + * + * @param callable $callback + */ + public function pushProcessor($callback) + { + if (!is_callable($callback)) { + throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), '.var_export($callback, true).' given'); + } + array_unshift($this->processors, $callback); + } + + /** + * Removes the processor on top of the stack and returns it. + * + * @return callable + */ + public function popProcessor() + { + if (!$this->processors) { + throw new \LogicException('You tried to pop from an empty processor stack.'); + } + return array_shift($this->processors); + } + + /** + * Adds a log record. + * + * @param integer $level The logging level + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addRecord($level, $message, array $context = array()) + { + if (!$this->handlers) { + $this->pushHandler(new StreamHandler('php://stderr', self::DEBUG)); + } + $record = array( + 'message' => (string) $message, + 'context' => $context, + 'level' => $level, + 'level_name' => self::getLevelName($level), + 'channel' => $this->name, + 'datetime' => \DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true))), + 'extra' => array(), + ); + // check if any message will handle this message + $handlerKey = null; + foreach ($this->handlers as $key => $handler) { + if ($handler->isHandling($record)) { + $handlerKey = $key; + break; + } + } + // none found + if (null === $handlerKey) { + return false; + } + // found at least one, process message and dispatch it + foreach ($this->processors as $processor) { + $record = call_user_func($processor, $record); + } + while (isset($this->handlers[$handlerKey]) && + false === $this->handlers[$handlerKey]->handle($record)) { + $handlerKey++; + } + + return true; + } + + /** + * Adds a log record at the DEBUG level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addDebug($message, array $context = array()) + { + return $this->addRecord(self::DEBUG, $message, $context); + } + + /** + * Adds a log record at the INFO level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addInfo($message, array $context = array()) + { + return $this->addRecord(self::INFO, $message, $context); + } + + /** + * Adds a log record at the WARNING level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addWarning($message, array $context = array()) + { + return $this->addRecord(self::WARNING, $message, $context); + } + + /** + * Adds a log record at the ERROR level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addError($message, array $context = array()) + { + return $this->addRecord(self::ERROR, $message, $context); + } + + /** + * Adds a log record at the CRITICAL level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addCritical($message, array $context = array()) + { + return $this->addRecord(self::CRITICAL, $message, $context); + } + + /** + * Adds a log record at the ALERT level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addAlert($message, array $context = array()) + { + return $this->addRecord(self::ALERT, $message, $context); + } + + /** + * Gets the name of the logging level. + * + * @param integer $level + * @return string + */ + public static function getLevelName($level) + { + return self::$levels[$level]; + } + + /** + * Checks whether the Logger has a handler that listens on the given level + * + * @param integer $level + * @return Boolean + */ + public function isHandling($level) + { + $record = array( + 'message' => '', + 'context' => array(), + 'level' => $level, + 'level_name' => self::getLevelName($level), + 'channel' => $this->name, + 'datetime' => new \DateTime(), + 'extra' => array(), + ); + + foreach ($this->handlers as $key => $handler) { + if ($handler->isHandling($record)) { + return true; + } + } + + return false; + } + + // ZF Logger Compat + + /** + * Adds a log record at the DEBUG level. + * + * This method allows to have an easy ZF compatibility. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function debug($message, array $context = array()) + { + return $this->addRecord(self::DEBUG, $message, $context); + } + + /** + * Adds a log record at the INFO level. + * + * This method allows to have an easy ZF compatibility. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function info($message, array $context = array()) + { + return $this->addRecord(self::INFO, $message, $context); + } + + /** + * Adds a log record at the INFO level. + * + * This method allows to have an easy ZF compatibility. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function notice($message, array $context = array()) + { + return $this->addRecord(self::INFO, $message, $context); + } + + /** + * Adds a log record at the WARNING level. + * + * This method allows to have an easy ZF compatibility. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function warn($message, array $context = array()) + { + return $this->addRecord(self::WARNING, $message, $context); + } + + /** + * Adds a log record at the ERROR level. + * + * This method allows to have an easy ZF compatibility. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function err($message, array $context = array()) + { + return $this->addRecord(self::ERROR, $message, $context); + } + + /** + * Adds a log record at the CRITICAL level. + * + * This method allows to have an easy ZF compatibility. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function crit($message, array $context = array()) + { + return $this->addRecord(self::CRITICAL, $message, $context); + } + + /** + * Adds a log record at the ALERT level. + * + * This method allows to have an easy ZF compatibility. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function alert($message, array $context = array()) + { + return $this->addRecord(self::ALERT, $message, $context); + } + + /** + * Adds a log record at the ALERT level. + * + * This method allows to have an easy ZF compatibility. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function emerg($message, array $context = array()) + { + return $this->addRecord(self::ALERT, $message, $context); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php b/vendor/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php new file mode 100644 index 0000000..f03e347 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.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 Monolog\Processor; + +/** + * Injects line/file:class/function where the log message came from + * + * Warning: This only works if the handler processes the logs directly. + * If you put the processor on a handler that is behind a FingersCrossedHandler + * for example, the processor will only be called once the trigger level is reached, + * and all the log records will have the same file/line/.. data from the call that + * triggered the FingersCrossedHandler. + * + * @author Jordi Boggiano + */ +class IntrospectionProcessor +{ + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + $trace = debug_backtrace(); + + // skip first since it's always the current method + array_shift($trace); + // the call_user_func call is also skipped + array_shift($trace); + + $i = 0; + while (isset($trace[$i]['class']) && false !== strpos($trace[$i]['class'], 'Monolog\\')) { + $i++; + } + + // we should have the call source now + $record['extra'] = array_merge( + $record['extra'], + array( + 'file' => isset($trace[$i-1]['file']) ? $trace[$i-1]['file'] : null, + 'line' => isset($trace[$i-1]['line']) ? $trace[$i-1]['line'] : null, + 'class' => isset($trace[$i]['class']) ? $trace[$i]['class'] : null, + 'function' => isset($trace[$i]['function']) ? $trace[$i]['function'] : null, + ) + ); + + return $record; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php b/vendor/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php new file mode 100644 index 0000000..77e0324 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.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 Monolog\Processor; + +/** + * Injects memory_get_peak_usage in all records + * + * @see Monolog\Processor\MemoryProcessor::__construct() for options + * @author Rob Jensen + */ +class MemoryPeakUsageProcessor extends MemoryProcessor +{ + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + $bytes = memory_get_peak_usage($this->realUsage); + $formatted = self::formatBytes($bytes); + + $record['extra'] = array_merge( + $record['extra'], + array( + 'memory_peak_usage' => $formatted, + ) + ); + + return $record; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php b/vendor/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php new file mode 100644 index 0000000..7a41238 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Processor/MemoryProcessor.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 Monolog\Processor; + +/** + * Some methods that are common for all memory processors + * + * @author Rob Jensen + */ +abstract class MemoryProcessor +{ + protected $realUsage; + + /** + * @param boolean $realUsage + */ + public function __construct($realUsage = true) + { + $this->realUsage = (boolean) $realUsage; + } + + /** + * Formats bytes into a human readable string + * + * @param int $bytes + * @return string + */ + protected static function formatBytes($bytes) + { + $bytes = (int) $bytes; + + if ($bytes > 1024*1024) { + return round($bytes/1024/1024, 2).' MB'; + } elseif ($bytes > 1024) { + return round($bytes/1024, 2).' KB'; + } + + return $bytes . ' B'; + } + +} diff --git a/vendor/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php b/vendor/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php new file mode 100644 index 0000000..0867459 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.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 Monolog\Processor; + +/** + * Injects memory_get_usage in all records + * + * @see Monolog\Processor\MemoryProcessor::__construct() for options + * @author Rob Jensen + */ +class MemoryUsageProcessor extends MemoryProcessor +{ + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + $bytes = memory_get_usage($this->realUsage); + $formatted = self::formatBytes($bytes); + + $record['extra'] = array_merge( + $record['extra'], + array( + 'memory_usage' => $formatted, + ) + ); + + return $record; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.php b/vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.php new file mode 100644 index 0000000..61000a0 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.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 Monolog\Processor; + +/** + * Injects url/method and remote IP of the current web request in all records + * + * @author Jordi Boggiano + */ +class WebProcessor +{ + protected $serverData; + + /** + * @param mixed $serverData array or object w/ ArrayAccess that provides access to the $_SERVER data + */ + public function __construct($serverData = null) + { + if (null === $serverData) { + $this->serverData =& $_SERVER; + } elseif (is_array($serverData) || $serverData instanceof \ArrayAccess) { + $this->serverData = $serverData; + } else { + throw new \UnexpectedValueException('$serverData must be an array or object implementing ArrayAccess.'); + } + } + + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + // skip processing if for some reason request data + // is not present (CLI or wonky SAPIs) + if (!isset($this->serverData['REQUEST_URI'])) { + return $record; + } + + if (!isset($this->serverData['HTTP_REFERER'])) { + $this->serverData['HTTP_REFERER'] = null; + } + + $record['extra'] = array_merge( + $record['extra'], + array( + 'url' => $this->serverData['REQUEST_URI'], + 'ip' => $this->serverData['REMOTE_ADDR'], + 'http_method' => $this->serverData['REQUEST_METHOD'], + 'server' => $this->serverData['SERVER_NAME'], + 'referrer' => $this->serverData['HTTP_REFERER'], + ) + ); + + return $record; + } +} diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Composer/ScriptHandler.php b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Composer/ScriptHandler.php new file mode 100644 index 0000000..f18bddc --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Composer/ScriptHandler.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 Sensio\Bundle\DistributionBundle\Composer; + +use Symfony\Component\ClassLoader\ClassCollectionLoader; +use Symfony\Component\Process\Process; +use Symfony\Component\Process\PhpExecutableFinder; + +/** + * @author Jordi Boggiano + */ +class ScriptHandler +{ + public static function buildBootstrap($event) + { + $options = self::getOptions($event); + $appDir = $options['symfony-app-dir']; + + if (!is_dir($appDir)) { + echo 'The symfony-app-dir ('.$appDir.') specified in composer.json was not found in '.getcwd().', can not build bootstrap file.'.PHP_EOL; + + return; + } + + static::executeBuildBootstrap($appDir); + } + + public static function clearCache($event) + { + $options = self::getOptions($event); + $appDir = $options['symfony-app-dir']; + + if (!is_dir($appDir)) { + echo 'The symfony-app-dir ('.$appDir.') specified in composer.json was not found in '.getcwd().', can not clear the cache.'.PHP_EOL; + + return; + } + + static::executeCommand($event, $appDir, 'cache:clear --no-warmup'); + } + + public static function installAssets($event) + { + $options = self::getOptions($event); + $appDir = $options['symfony-app-dir']; + $webDir = $options['symfony-web-dir']; + + $symlink = ''; + if ($options['symfony-assets-install'] == 'symlink') { + $symlink = '--symlink '; + } elseif ($options['symfony-assets-install'] == 'relative') { + $symlink = '--symlink --relative '; + } + + if (!is_dir($webDir)) { + echo 'The symfony-web-dir ('.$webDir.') specified in composer.json was not found in '.getcwd().', can not install assets.'.PHP_EOL; + + return; + } + + static::executeCommand($event, $appDir, 'assets:install '.$symlink.escapeshellarg($webDir)); + } + + public static function doBuildBootstrap($appDir) + { + $file = $appDir.'/bootstrap.php.cache'; + if (file_exists($file)) { + unlink($file); + } + + ClassCollectionLoader::load(array( + 'Symfony\\Component\\DependencyInjection\\ContainerAwareInterface', + // Cannot be included because annotations will parse the big compiled class file + //'Symfony\\Component\\DependencyInjection\\ContainerAware', + 'Symfony\\Component\\DependencyInjection\\ContainerInterface', + 'Symfony\\Component\\DependencyInjection\\Container', + 'Symfony\\Component\\HttpKernel\\HttpKernelInterface', + 'Symfony\\Component\\HttpKernel\\KernelInterface', + 'Symfony\\Component\\HttpKernel\\Kernel', + 'Symfony\\Component\\ClassLoader\\ClassCollectionLoader', + 'Symfony\\Component\\ClassLoader\\ApcClassLoader', + 'Symfony\\Component\\HttpKernel\\Bundle\\BundleInterface', + 'Symfony\\Component\\HttpKernel\\Bundle\\Bundle', + 'Symfony\\Component\\Config\\ConfigCache', + // cannot be included as commands are discovered based on the path to this class via Reflection + //'Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle', + ), dirname($file), basename($file, '.php.cache'), false, false, '.php.cache'); + + file_put_contents($file, sprintf("find()); + $console = escapeshellarg($appDir.'/console'); + if ($event->getIO()->isDecorated()) { + $console.= ' --ansi'; + } + + $process = new Process($php.' '.$console.' '.$cmd); + $process->run(function ($type, $buffer) { echo $buffer; }); + } + + protected static function executeBuildBootstrap($appDir) + { + $phpFinder = new PhpExecutableFinder; + $php = escapeshellarg($phpFinder->find()); + $cmd = escapeshellarg(__DIR__.'/../Resources/bin/build_bootstrap.php'); + $appDir = escapeshellarg($appDir); + + $process = new Process($php.' '.$cmd.' '.$appDir); + $process->run(function ($type, $buffer) { echo $buffer; }); + } + + protected static function getOptions($event) + { + $options = array_merge(array( + 'symfony-app-dir' => 'app', + 'symfony-web-dir' => 'web', + 'symfony-assets-install' => 'hard' + ), $event->getComposer()->getPackage()->getExtra()); + + $options['symfony-assets-install'] = getenv('SYMFONY_ASSETS_INSTALL') ?: $options['symfony-assets-install']; + + return $options; + } +} diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Configurator.php b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Configurator.php new file mode 100644 index 0000000..8138398 --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Configurator.php @@ -0,0 +1,186 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sensio\Bundle\DistributionBundle\Configurator; + +use Sensio\Bundle\DistributionBundle\Configurator\Step\StepInterface; +use Symfony\Component\Yaml\Yaml; + +/** + * Configurator. + * + * @author Marc Weistroff + */ +class Configurator +{ + protected $filename; + protected $steps; + protected $parameters; + + public function __construct($kernelDir) + { + $this->kernelDir = $kernelDir; + $this->filename = $kernelDir.'/config/parameters.yml'; + + $this->steps = array(); + $this->parameters = $this->read(); + } + + public function isFileWritable() + { + return is_writable($this->filename); + } + + public function clean() + { + if (file_exists($this->getCacheFilename())) { + @unlink($this->getCacheFilename()); + } + } + + /** + * @param StepInterface $step + */ + public function addStep(StepInterface $step) + { + $this->steps[] = $step; + } + + /** + * @param integer $index + * + * @return StepInterface + */ + public function getStep($index) + { + if (isset($this->steps[$index])) { + return $this->steps[$index]; + } + } + + /** + * @return array + */ + public function getSteps() + { + return $this->steps; + } + + /** + * @return array + */ + public function getParameters() + { + return $this->parameters; + } + + /** + * @return integer + */ + public function getStepCount() + { + return count($this->steps); + } + + /** + * @param array $parameters + */ + public function mergeParameters($parameters) + { + $this->parameters = array_merge($this->parameters, $parameters); + } + + /** + * @return array + */ + public function getRequirements() + { + $majors = array(); + foreach ($this->steps as $step) { + foreach ($step->checkRequirements() as $major) { + $majors[] = $major; + } + } + + return $majors; + } + + /** + * @return array + */ + public function getOptionalSettings() + { + $minors = array(); + foreach ($this->steps as $step) { + foreach ($step->checkOptionalSettings() as $minor) { + $minors[] = $minor; + } + } + + return $minors; + } + + /** + * Renders parameters as a string. + * + * @return string + */ + public function render() + { + return Yaml::dump(array('parameters' => $this->parameters)); + } + + /** + * Writes parameters to parameters.yml or temporary in the cache directory. + * + * @return boolean + */ + public function write() + { + $filename = $this->isFileWritable() ? $this->filename : $this->getCacheFilename(); + + return file_put_contents($filename, $this->render()); + } + + /** + * Reads parameters from file. + * + * @return array + */ + protected function read() + { + $filename = $this->filename; + if (!$this->isFileWritable() && file_exists($this->getCacheFilename())) { + $filename = $this->getCacheFilename(); + } + + $ret = Yaml::parse($filename); + if (false === $ret || array() === $ret) { + throw new \InvalidArgumentException(sprintf('The %s file is not valid.', $filename)); + } + + if (isset($ret['parameters']) && is_array($ret['parameters'])) { + return $ret['parameters']; + } else { + return array(); + } + } + + /** + * getCacheFilename + * + * @return string + */ + protected function getCacheFilename() + { + return $this->kernelDir.'/cache/parameters.yml'; + } +} diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Form/DoctrineStepType.php b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Form/DoctrineStepType.php new file mode 100644 index 0000000..fa315c5 --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Form/DoctrineStepType.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 Sensio\Bundle\DistributionBundle\Configurator\Form; + +use Sensio\Bundle\DistributionBundle\Configurator\Step\DoctrineStep; +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\FormBuilderInterface; + +/** + * Doctrine Form Type. + * + * @author Fabien Potencier + */ +class DoctrineStepType extends AbstractType +{ + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder + ->add('driver', 'choice', array('choices' => DoctrineStep::getDrivers())) + ->add('name', 'text') + ->add('host', 'text') + ->add('port', 'text', array('required' => false)) + ->add('user', 'text') + ->add('password', 'repeated', array( + 'required' => false, + 'type' => 'password', + 'first_name' => 'password', + 'second_name' => 'password_again', + 'invalid_message' => 'The password fields must match.', + )) + ; + } + + public function getName() + { + return 'distributionbundle_doctrine_step'; + } +} diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Form/SecretStepType.php b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Form/SecretStepType.php new file mode 100644 index 0000000..c62ebd1 --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Form/SecretStepType.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 Sensio\Bundle\DistributionBundle\Configurator\Form; + +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\FormBuilderInterface; + +/** + * Secret Form Type. + * + * @author Marc Weistroff + */ +class SecretStepType extends AbstractType +{ + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder->add('secret', 'text'); + } + + public function getName() + { + return 'distributionbundle_secret_step'; + } +} diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Step/DoctrineStep.php b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Step/DoctrineStep.php new file mode 100644 index 0000000..ba2163e --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Step/DoctrineStep.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 Sensio\Bundle\DistributionBundle\Configurator\Step; + +use Sensio\Bundle\DistributionBundle\Configurator\Form\DoctrineStepType; +use Symfony\Component\Validator\Constraints as Assert; + +/** + * Doctrine Step. + * + * @author Fabien Potencier + */ +class DoctrineStep implements StepInterface +{ + /** + * @Assert\Choice(callback="getDriverKeys") + */ + public $driver; + + /** + * @Assert\NotBlank + */ + public $host; + + /** + * @Assert\Min(0) + */ + public $port; + + /** + * @Assert\NotBlank + */ + public $name; + + /** + * @Assert\NotBlank + */ + public $user; + + public $password; + + public function __construct(array $parameters) + { + foreach ($parameters as $key => $value) { + if (0 === strpos($key, 'database_')) { + $parameters[substr($key, 9)] = $value; + $key = substr($key, 9); + $this->$key = $value; + } + } + } + + /** + * @see StepInterface + */ + public function getFormType() + { + return new DoctrineStepType(); + } + + /** + * @see StepInterface + */ + public function checkRequirements() + { + $messages = array(); + + if (!class_exists('\PDO')) { + $messages[] = 'PDO extension is mandatory.'; + } else { + $drivers = \PDO::getAvailableDrivers(); + if (0 == count($drivers)) { + $messages[] = 'Please install PDO drivers.'; + } + } + + return $messages; + } + + /** + * @see StepInterface + */ + public function checkOptionalSettings() + { + return array(); + } + + /** + * @see StepInterface + */ + public function update(StepInterface $data) + { + $parameters = array(); + + foreach ($data as $key => $value) { + $parameters['database_'.$key] = $value; + } + + return $parameters; + } + + /** + * @see StepInterface + */ + public function getTemplate() + { + return 'SensioDistributionBundle:Configurator/Step:doctrine.html.twig'; + } + + /** + * @return array + */ + static public function getDriverKeys() + { + return array_keys(static::getDrivers()); + } + + /** + * @return array + */ + static public function getDrivers() + { + return array( + 'pdo_mysql' => 'MySQL (PDO)', + 'pdo_sqlite' => 'SQLite (PDO)', + 'pdo_pgsql' => 'PosgreSQL (PDO)', + 'oci8' => 'Oracle (native)', + 'ibm_db2' => 'IBM DB2 (native)', + 'pdo_oci' => 'Oracle (PDO)', + 'pdo_ibm' => 'IBM DB2 (PDO)', + 'pdo_sqlsrv' => 'SQLServer (PDO)', + ); + } +} diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Step/SecretStep.php b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Step/SecretStep.php new file mode 100644 index 0000000..d2333ba --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Step/SecretStep.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 Sensio\Bundle\DistributionBundle\Configurator\Step; + +use Sensio\Bundle\DistributionBundle\Configurator\Form\SecretStepType; +use Symfony\Component\Validator\Constraints as Assert; + +/** + * Secret Step. + * + * @author Fabien Potencier + */ +class SecretStep implements StepInterface +{ + /** + * @Assert\NotBlank + */ + public $secret; + + public function __construct(array $parameters) + { + if (array_key_exists('secret', $parameters)){ + $this->secret = $parameters['secret']; + + if ('ThisTokenIsNotSoSecretChangeIt' == $this->secret) { + $this->secret = $this->generateRandomSecret(); + } + } else { + $this->secret = $this->generateRandomSecret(); + } + + } + + private function generateRandomSecret() + { + return hash('sha1', uniqid(mt_rand())); + } + + /** + * @see StepInterface + */ + public function getFormType() + { + return new SecretStepType(); + } + + /** + * @see StepInterface + */ + public function checkRequirements() + { + return array(); + } + + /** + * checkOptionalSettings + */ + public function checkOptionalSettings() + { + return array(); + } + + /** + * @see StepInterface + */ + public function update(StepInterface $data) + { + return array('secret' => $data->secret); + } + + /** + * @see StepInterface + */ + public function getTemplate() + { + return 'SensioDistributionBundle:Configurator/Step:secret.html.twig'; + } +} diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Step/StepInterface.php b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Step/StepInterface.php new file mode 100644 index 0000000..94767ee --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Configurator/Step/StepInterface.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 Sensio\Bundle\DistributionBundle\Configurator\Step; + +use Symfony\Component\Form\Type\FormTypeInterface; + +/** + * StepInterface. + * + * @author Marc Weistroff + */ +interface StepInterface +{ + /** + * __construct + * + * @param array $parameters + */ + function __construct(array $parameters); + + /** + * Returns the form used for configuration. + * + * @return FormTypeInterface + */ + function getFormType(); + + /** + * Checks for requirements. + * + * @return array + */ + function checkRequirements(); + + /** + * Checks for optional setting it could be nice to have. + * + * @return array + */ + function checkOptionalSettings(); + + /** + * Returns the template to be renderer for this step. + * + * @return string + */ + function getTemplate(); + + /** + * Updates form data parameters. + * + * @param array $parameters + * @return array + */ + function update(StepInterface $data); +} diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Controller/ConfiguratorController.php b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Controller/ConfiguratorController.php new file mode 100644 index 0000000..07214cf --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Controller/ConfiguratorController.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 Sensio\Bundle\DistributionBundle\Controller; + +use Symfony\Component\DependencyInjection\ContainerAware; +use Symfony\Component\HttpFoundation\RedirectResponse; + +/** + * ConfiguratorController. + * + * @author Fabien Potencier + */ +class ConfiguratorController extends ContainerAware +{ + /** + * @return Response A Response instance + */ + public function stepAction($index = 0) + { + $configurator = $this->container->get('sensio.distribution.webconfigurator'); + + $step = $configurator->getStep($index); + $form = $this->container->get('form.factory')->create($step->getFormType(), $step); + + $request = $this->container->get('request'); + if ('POST' === $request->getMethod()) { + $form->bindRequest($request); + if ($form->isValid()) { + $configurator->mergeParameters($step->update($form->getData())); + $configurator->write(); + + $index++; + + if ($index < $configurator->getStepCount()) { + return new RedirectResponse($this->container->get('router')->generate('_configurator_step', array('index' => $index))); + } + + return new RedirectResponse($this->container->get('router')->generate('_configurator_final')); + } + } + + return $this->container->get('templating')->renderResponse($step->getTemplate(), array( + 'form' => $form->createView(), + 'index' => $index, + 'count' => $configurator->getStepCount(), + 'version' => $this->getVersion(), + )); + } + + public function checkAction() + { + $configurator = $this->container->get('sensio.distribution.webconfigurator'); + + // Trying to get as much requirements as possible + $majors = $configurator->getRequirements(); + $minors = $configurator->getOptionalSettings(); + + $url = $this->container->get('router')->generate('_configurator_step', array('index' => 0)); + + if (empty($majors) && empty($minors)) { + return new RedirectResponse($url); + } + + return $this->container->get('templating')->renderResponse('SensioDistributionBundle::Configurator/check.html.twig', array( + 'majors' => $majors, + 'minors' => $minors, + 'url' => $url, + 'version' => $this->getVersion(), + )); + } + + public function finalAction() + { + $configurator = $this->container->get('sensio.distribution.webconfigurator'); + $configurator->clean(); + + try { + $welcomeUrl = $this->container->get('router')->generate('_welcome'); + } catch (\Exception $e) { + $welcomeUrl = null; + } + + return $this->container->get('templating')->renderResponse('SensioDistributionBundle::Configurator/final.html.twig', array( + 'welcome_url' => $welcomeUrl, + 'parameters' => $configurator->render(), + 'yml_path' => $this->container->getParameter('kernel.root_dir').'/config/parameters.yml', + 'is_writable' => $configurator->isFileWritable(), + 'version' => $this->getVersion(), + )); + } + + public function getVersion() + { + $kernel = $this->container->get('kernel'); + + return $kernel::VERSION; + } +} diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/DependencyInjection/SensioDistributionExtension.php b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/DependencyInjection/SensioDistributionExtension.php new file mode 100644 index 0000000..4363d57 --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/DependencyInjection/SensioDistributionExtension.php @@ -0,0 +1,33 @@ + + */ +class SensioDistributionExtension extends Extension +{ + public function load(array $configs, ContainerBuilder $container) + { + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + + $loader->load('webconfigurator.xml'); + } + + public function getNamespace() + { + return 'http://symfony.com/schema/dic/symfony/sensiodistribution'; + } + + public function getAlias() + { + return 'sensio_distribution'; + } +} diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/LICENSE b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/LICENSE new file mode 100644 index 0000000..c6aa7e3 --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010,2011 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/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/bin/build.sh b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/bin/build.sh new file mode 100755 index 0000000..ad9ee9b --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/bin/build.sh @@ -0,0 +1,102 @@ +#!/bin/sh + +# This file is part of the Symfony Standard Edition. +# +# (c) Fabien Potencier +# +# For the full copyright and license information, please view the LICENSE +# file that was distributed with this source code. + +DIR=`php -r "echo realpath(dirname(\\$_SERVER['argv'][0]));"` +cd $DIR +VERSION=`grep ' VERSION ' vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php | sed -E "s/.*'(.+)'.*/\1/g"` + +if [ ! -d "$DIR/build" ]; then + mkdir -p $DIR/build +fi + +# Without vendors +rm -rf /tmp/Symfony +mkdir /tmp/Symfony +cp -r app /tmp/Symfony/ +cp -r src /tmp/Symfony/ +cp -r web /tmp/Symfony/ +cp README.md /tmp/Symfony/ +cp LICENSE /tmp/Symfony/ +cp composer.json /tmp/Symfony/ +cp composer.lock /tmp/Symfony/ +cd /tmp/Symfony +sudo rm -rf app/cache/* app/logs/* .git* +chmod 777 app/cache app/logs + +# DS_Store cleanup +find . -name .DS_Store | xargs rm -rf - + +cd .. +# avoid the creation of ._* files +export COPY_EXTENDED_ATTRIBUTES_DISABLE=true +export COPYFILE_DISABLE=true +tar zcpf $DIR/build/Symfony_Standard_$VERSION.tgz Symfony +sudo rm -f $DIR/build/Symfony_Standard_$VERSION.zip +zip -rq $DIR/build/Symfony_Standard_$VERSION.zip Symfony + +# With vendors +cd $DIR +rm -rf /tmp/vendor +mkdir /tmp/vendor +TARGET=/tmp/vendor + +if [ ! -d "$DIR/vendor" ]; then + echo "The master vendor directory does not exist" + exit +fi + +cp -r $DIR/vendor/* $TARGET/ + +# Doctrine ORM +cd $TARGET/doctrine/orm && rm -rf UPGRADE* build* bin tests tools lib/vendor + +# Doctrine DBAL +cd $TARGET/doctrine/dbal && rm -rf bin build* tests lib/vendor + +# Doctrine Common +cd $TARGET/doctrine/common && rm -rf build* tests lib/vendor + +# Swiftmailer +cd $TARGET/swiftmailer/swiftmailer && rm -rf CHANGES README* build* docs notes test-suite tests create_pear_package.php package* + +# Symfony +cd $TARGET/symfony/symfony && rm -rf README.md phpunit.xml* tests *.sh vendor + +# Twig +cd $TARGET/twig/twig && rm -rf AUTHORS CHANGELOG README.markdown bin doc package.xml.tpl phpunit.xml* test + +# Twig Extensions +cd $TARGET/twig/extensions && rm -rf README doc phpunit.xml* test + +# Monolog +cd $TARGET/monolog/monolog && rm -rf README.markdown phpunit.xml* tests + +# Sensio +cd $TARGET/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/ && rm -rf phpunit.xml* Tests CHANGELOG* +cd $TARGET/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/ && rm -rf phpunit.xml* Tests CHANGELOG* +cd $TARGET/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/ && rm -rf phpunit.xml* Tests CHANGELOG* + +# JMS +cd $TARGET/jms/metadata && rm -rf README.rst phpunit.xml* tests +cd $TARGET/jms/cg && rm -rf README.rst phpunit.xml* tests +cd $TARGET/jms/aop-bundle/JMS/AopBundle && rm -rf phpunit.xml* Tests +cd $TARGET/jms/di-extra-bundle/JMS/DiExtraBundle && rm -rf phpunit.xml* Tests +cd $TARGET/jms/security-extra-bundle/JMS/SecurityExtraBundle/ && rm -rf phpunit.xml* Tests + +# cleanup +find $TARGET -name .git | xargs rm -rf - +find $TARGET -name .gitignore | xargs rm -rf - +find $TARGET -name .gitmodules | xargs rm -rf - +find $TARGET -name .svn | xargs rm -rf - + +cd /tmp/ +mv /tmp/vendor /tmp/Symfony/ +tar zcpf $DIR/build/Symfony_Standard_Vendors_$VERSION.tgz Symfony +sudo rm -f $DIR/build/Symfony_Standard_Vendors_$VERSION.zip +zip -rq $DIR/build/Symfony_Standard_Vendors_$VERSION.zip Symfony diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/bin/build_bootstrap.php b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/bin/build_bootstrap.php new file mode 100755 index 0000000..4ac315b --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/bin/build_bootstrap.php @@ -0,0 +1,26 @@ +#!/usr/bin/env php + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +$argv = $_SERVER['argv']; + +// allow the base path to be passed as the first argument, or default +if (isset($argv[1])) { + $appDir = $argv[1]; +} else { + if (!$appDir = realpath(__DIR__.'/../../../../../../../app')) { + exit('Looks like you don\'t have a standard layout.'); + } +} + +require_once $appDir.'/autoload.php'; + +\Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::doBuildBootstrap($appDir); diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/config/routing/webconfigurator.xml b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/config/routing/webconfigurator.xml new file mode 100644 index 0000000..6dae8b5 --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/config/routing/webconfigurator.xml @@ -0,0 +1,18 @@ + + + + + + SensioDistributionBundle:Configurator:check + + + + SensioDistributionBundle:Configurator:step + + + + SensioDistributionBundle:Configurator:final + + diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/config/webconfigurator.xml b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/config/webconfigurator.xml new file mode 100644 index 0000000..fcf3e64 --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/config/webconfigurator.xml @@ -0,0 +1,17 @@ + + + + + + Sensio\Bundle\DistributionBundle\Configurator\Configurator + + + + + %kernel.root_dir% + + + + diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/css/configure.css b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/css/configure.css new file mode 100644 index 0000000..359bba1 --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/css/configure.css @@ -0,0 +1,153 @@ +@import url("install.css"); + +h1 { + margin-top: 10px; + font-size: 26px; +} + +#symfony-wrapper { + padding-top: 0; +} + +#symfony-search { + position: absolute; + top: 50px; + right: 30px; +} + +#symfony-search-field { + width: 190px; +} + +#symfony-search label { + display: block; + float: left; + width: 20px; + height: 25px; + background: url(../images/search.png) no-repeat left 5px; +} + +#symfony-search label span { + display: none; +} + +input[type=text] { + border: 1px solid #DADADA; + background: white url(../images/field-background.gif) repeat-x left top; + padding: 5px 6px; + color: #565656; + font-family: "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif; + font-size: 12px; +} + + +.symfony-button-grey, .symfony-button-green { + font-size: 0.85em; + font-weight: bold; + cursor: pointer; + display: inline-block; + outline: none; + text-align: center; + text-transform: uppercase; + padding: 3px 10px; + text-shadow: 0 1px 1px rgba(0,0,0,.3); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.symfony-button-grey { + color: #868686; + font-weight: normal; + padding: 5px 10px; + border: solid 1px #d7d7d7; + background: #ffffff; + background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#d7d7d7)); + background: -moz-linear-gradient(top, #ffffff, #d7d7d7); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#d7d7d7'); +} + +.symfony-button-green { + padding: 5px 12px; + color: white; + border: solid 1px #a7da39; + background: #a7da39; + background: -webkit-gradient(linear, left top, left bottom, from(#a7da39), to(#6a9211)); + background: -moz-linear-gradient(top, #a7da39, #6a9211); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#a7da39', endColorstr='#6a9211'); +} + +.symfony-block-steps span { + display: inline-block; + padding: 2px 3px; + font-size: 11px; + line-height: 15px; + color: #868686; + font-weight: bold; + text-transform: uppercase; +} + +.symfony-block-steps span.selected { + background-color: #aacd4e; + color: #FFFFFF; +} + + +.symfony-form-row { + padding-bottom: 40px; +} + +.symfony-form-column { + width: 430px; + float: left; +} + +.symfony-form-footer { + padding-top: 20px; + clear: both; +} + +.symfony-form-field { + height: 20px; +} + +.symfony-form-row label { + display: block; + padding-bottom: 8px; +} + +.symfony-form-field input[type=text], +.symfony-form-field input[type=password], +.symfony-form-field textarea, +.symfony-form-field select { + font-size: 13px; + color: #565656; + width: 200px; +} + +.symfony-form-field input[type=text], +.symfony-form-field input[type=password], +.symfony-form-field textarea { + border: 1px solid #dadada; + background: #FFFFFF url(../images/background-textfield.gif) repeat-x left top; + width: 194px; + padding: 5px 6px; +} + +.symfony-form-errors ul { + padding: 0; +} + +.symfony-form-errors li { + background: url(../images/notification.gif) no-repeat left 6px; + font-size: 11px; + line-height: 16px; + color: #759e1a; + padding: 10px 25px; +} + +.symfony-configuration { + margin: 10px 0; + width: 100%; + height: 240px; +} diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/css/install.css b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/css/install.css new file mode 100644 index 0000000..7edb396 --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/css/install.css @@ -0,0 +1,137 @@ +/* +Copyright (c) 2010, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.com/yui/license.html +version: 2.8.2r1 + +Reset +*/ + +html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var,optgroup{font-style:inherit;font-weight:inherit;}del,ins{text-decoration:none;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:baseline;}sub{vertical-align:baseline;}legend{color:#000;}input,button,textarea,select,optgroup,option{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;}input,button,textarea,select{*font-size:100%;} + +html, body { + background-color: #EFEFEF; +} + +body { + font-size: 14px; + font-family: "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif; + color: #313131; +} + +a { + color: #08C; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +strong { + font-weight: bold; +} + +em { + font-style: italic; +} + +h1, h2, h3 { + font-family: Georgia, "Times New Roman", Times, serif; + color: #404040; +} + +h1 { + font-size: 45px; + padding-bottom: 30px; +} + +h2 { + font-weight: bold; + color: #FFFFFF; + /* Font is reset to sans-serif (like body) */ + font-family: "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif; + margin-bottom: 10px; + background-color: #aacd4e; + padding: 2px 4px; + display: inline-block; + text-transform: uppercase; + +} + +p { + line-height: 20px; + padding-bottom: 20px; +} + +ul a { + background: url(../images/blue-arrow.png) no-repeat right 6px; + padding-right: 10px; +} + +ul, ol { + padding-left: 20px; +} + +li { + padding-bottom: 18px; +} + +ol li { + list-style-type: decimal; +} + +ul li { + list-style-type: none; +} + +#symfony-header { + position: relative; + padding: 30px 30px 20px 30px; +} + +#symfony-wrapper { + width: 970px; + margin: 0 auto; + padding-top: 50px; +} + +#symfony-content { + background-color: white; + border: 1px solid #DFDFDF; + padding: 50px; + -moz-border-radius: 16px; + -webkit-border-radius: 16px; + border-radius: 16px; + margin-bottom: 5px; +} + + +.symfony-blocks-install { + overflow: hidden; +} + +.symfony-blocks-install .symfony-block-logo { + float: left; + width: 358px; +} + +.symfony-blocks-install .symfony-block-content { + float: left; + width: 510px; +} + +.symfony-install-continue { + font-size: 0.95em; + padding-left: 0; +} + +.symfony-install-continue li { + padding-bottom: 10px; +} + +.version { + text-align: right; + font-size: 10px; + margin-right: 20px; +} diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/images/background-textfield.gif b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/images/background-textfield.gif new file mode 100644 index 0000000000000000000000000000000000000000..7c0efc1087c3cedd2a95deaef7322d4770170ff3 GIT binary patch literal 63 zcmZ?wbhEHbWMp7vSj52a_3PL7@8AFZ`}fzcU$0)hVt@g~pDbXe4u}M)WngCUU{vO0 Gum%7TE)u5z literal 0 HcmV?d00001 diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/images/blue-arrow.png b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/images/blue-arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..fa82d4b4fff6414062efb2a02049cfeb9e8e7cb1 GIT binary patch literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c!3HD^Kbl$tDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9Md6+I= zhqi>4PnzMOuO)K~*(RkoSoCn7)R^#~T4CSujwM;<0=t>E&QEnQ(&y3G(9U?$#xX^m ckwt=G)hqGzY5M*n+r|-FL<1!X8KKK0Y+4-K|Ip_DgLX_ZFS}O27 zD6VZ4Vy_V55P%DwO+Snf_;2^FO_X=lLt9ZPzz)z@c~ldI{Q@#slCUp96W9qfs%tQ*oXL6(4`+eocJ>~>XTi!Tx6`NE0#k>{2Oo} ztK9}W2EBZ;)|i=(L{i>6UU}sHFa>93DOU?()OGNh>)?K^U==8P)fsB(g!Z`H)Oe2K zAL8V3c}P=UQK;p237iK()-qO$m3q1_)5Uf>)l?g3abZDzzr3uhc^8WX1k|b(vZuwUYd`2nOcXxJ?f6`A^uQ+Js>k0*)1Z4Ms zn^LJ1IeVQ{e)veSS*BUf_2AsdWHfQT>0~mg)MIP0(fZmtg+pPwU~40@=~Q74tpCV* z?ho@%#bU9aI76NxIeHwFNF*?aMWwIcY>?`WCUqU3p`BrU7P-H#KQlGy-*EQ!{qC?| zBHyTwqR}XwX|T}E>o*E#8G_CNzUOjq9hiOEpwp*$E~o3w^mcAenG2uk(7mCIUZ>~% zB=me1mhaCn;Cq#;BX2o}t+|y3?+$Lc6{R^^&pjZF^ literal 0 HcmV?d00001 diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/images/logo-big.gif b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/images/logo-big.gif new file mode 100644 index 0000000000000000000000000000000000000000..721f12ab02990589a95fff62345c84113fdd724a GIT binary patch literal 4060 zcmV<24g99On!ZT*x1;yu(DTG zS)`+-n3tKcv9gPbjB#*s*x1>=y}wsgSc{2_etdtvzQ1vAa-^iC|Ns9mE;9fB{{R30 z000000000000000A^8LW000^QEC2ui0LTFD06+!*peBxFX`X1Rt}Gk83n9<)@&;|L z?|kq7KvCh4DH@N+q;kn@I**4!a7wNEB7&!O%k6rZ0-SYBP7%N8w0g}wl;67tdrn6i z7zK=e&+iW!248M)Zv}OSh)4nueR}{;jge_mggyz0m~;}6d=r^#36(4kpH344oT-fi z3|beej#~l%01~B23!)~Ew@0tAyl9Jj5E6{AdJS3(sT93N0J<6j&qo%>eadRr*xh{r z!PQE-;o=zv-i@|T+}#!Chz_Czbpo)|O%kZyP3air@Yv)Mwct>INcgrixR+%KGjE;( z9vUc(R4D-zDtIfvAP^UO-quN^BTt$Mk0aOr>_dh! zT;u_Qx=Ofe`20iwPc$VGfNnw{1riOFpF|^p*a%NEM_{f1r^JBX5wVN>CZYB*3C=|n zpFp0WwF)F+O3;ILVy2M?I;It zFhGS%MDZL^!=(_;Z6{=vB0+Vr2-%D}6i^#`GzNiy16fIAfCI+mm}3Mzu0@9d^9iX7 z7DgH=K$1%45L}Z~I-#79>s6V^Lw!I{WCkE{^5qgG4K}5gY*3KO01zf&RVrgXaiv)a zB?W*54CKiG1pu_k1(&G|rPYhl2>Qtcu)MQ{0UGh4jWyjw#6(b>h;&PN(vVmRpsEX@yjLn{-ujscXY zTOf)|D@(kIjWfe8VNzIiC`*k0p^U-;fuB^R18uZPlxfnL;1=Nx1m!9LrB|a48zwO6 zCL!Zq3L;|dDi&;!hbpkf+a6@h<=PFiitM{ezwu@eWRxY4woL<}?g2pq7I2%e01Gqx z!>S3dQLM%>4PkMU0yr=)$S9|*^2#i??DESdq@{&^Fl$gR5*yYm-4XxlOd-!c@4zut zCu`8scPC_tsR#jMTwSyN9pT`IK%-EOXer!yjtNTiOhUUkkA}pY#3j~4yGt`@_6X-0 zf%I{&WmuqV`B6=s2^G@JA&w)=t-^ukAu$}aWV0YM6e+MNwGm-27k3KG>0N@~Bkm0L8J8mi z6f)4G8!&-CrUZ;r@Lnb;=no`nA(61?*y*N#y-%PqjZV0uDvIc@c^rb0 zjrfuh-O+?krb2|86vZI9fXYbV>Rzg_Boc6`E$Km$lXY;V9++6mqcDMt*r-z}rGW@8 z>H#TQXjCfNs2Le%FJzezz%L?EfCH|=j7^XxGISZQH!TAE`dVA(O%F=c$<;w2{} z*fH0|1)XD&r!A!ipuO;rO2Xs=6RTuSrqJ^f2B1KmC@|0>Ad?g9Y$x~nlBGEmvk{7F z0wx{xy-oiArISrir>U0U%m_LXT!EYsJh|XaJrqL;#@HV|wPerp%~WclL`DI=MZSLO z%qbfz1=g$=fSU$Y5&p9t2}X2OCwNq;D_C9tod;EE1Yo6FxyvuB3Ks+}qcP`u-vfU`;PYzf%MzW zkm~^d5ztEj8~_^gi9iuVaex>Kkbtb*MlFsdfnqbjy$HlH1Di8JyAUfjqL_d=K8=~Y zAQw6fSPliA^XQb`mW0!-S3ecv9<^$^f&l=8Mbt{02B?*)`pB(rCo+QM{)@N%(#;62 z3r`CGx74wjKrLsrn?p??#>J}52;8$Ue=+>wB5b&7C14JH9XGn}(D-jXHi6REb_5CU zU`q78Q34dp;1S4}J|6Ddk1L1c+!~MtH=|jUNkC!~D3h;7@LzMC;Is?x*UUw@kcRi> zTow061?b~K;kG=UAOkowHM&6nQhb7XH5q1l4nSp@!kl%P^NRy8#4X0S*8_Lvs_@yhd6u2v`6}Pq~2Ke!2`h+VmJrcIq*x)~GZo8J}CN0jZLY zsY8bA+GwCO%dm=V zHT-#H-0n6TzOAuqi~A7To>7a>-HU1)2B_>lf&>^KXigNM0u+GtP=$o(a~mL_su%!I zw~%hX0Px%Zz$7bHb5RU{^9lPd%q#;KhAH|2mD7shP8^E0I!RMcdxh}%p)0XN%=UO2*L3Cn(30NHi1)x|Oe1i-v?N}7+Hb=G; z$wnqVloK}}3$dwy^)!sU0eqsx1RAhWFD23Id$5=QeE8C8q_-0Nt_HwaE;U{C;o(Kt zXd@`EVNOh(4sU-0JlMXbo9b`nNDybIOrZ+QXQC$^7b`MI>4jC+QJ;-Sx&c#>cTAWZ z2=LH6AE15&A0oaJ`r-tvg<+EQ-ohrS_`DNJiVSq}@}SQ!^c#qe29Y9g`AG0SA2J%! zhz-0NMlJ(9#7{u?rK12B(374TVD$=se-65kz9wA7c_)nARq%IG=CE=9J`j1&@PCbP zeoB`PuryYsg(d~(1F?q)XIFY%fPi|yeJ=5PJHU0BP=UO+DDM|bm7sxZfP1hoaW%Ir z9iw$XV1i4)K7OKd*f2}}(03^zc0n+KTHs0w*dZN+4X#%NDA)-4w-y|j9R{HaoCkC@ z*aSh?dd!oAIpBOS#}cG+e0#tIE++}hLx4RHcUK4tBO`q6w*(l70bmC%d$$AkHz2C8 zhDp$cdO&+faD&Vvbz{J6XwY!Imjuw)MO>H;w zrIH;JaXw>g@%9DD236pgmP){oFN2nD*>Y4VJYYGO3gDGcb(h^{JGmwTyB1UgP?vIL zYtPt*rzTsmI7SOVn13lE39yVQ@c_v4n7R;Z41j4JHSJU zo|&4extgrmny&epuo;`OIh(Xuo3?qIxS2fUm1(6(0Eh`PBN8X5S(R-voEr0vjwvK( z(poa`n@SQez6Djvq>pO<+FCbcphWVj5tD|H%UAH43=_ zH*Uj3CWB7x!H+RW0-{(VD1ZdKSS#v<1fiz^YH=BoSru>wq9-~a5b7Nnvy5d%0-lq8 z+twq_mHrcQ>UIlvqUf&>OSId&!jQ}QCz@~A6tSS7Gt zDT1J8dIV}_V{FEze6urC#%BLQXClyLz*S`bnfjnWa3fwbWUFcfh4W;A3aS}~tE4)r z`+=%H24cUet3YN1snQb4p%%$WWq@h|_2L$a#ih2|sfJo(ZFZ=|iG zV|3PEP)Y(7WtLc4W#3h*C*ZBLkr+84b)=yH1P}q6!6R0xS1T2I0lT8YdIAKiunkie zwIu=wKmedYHuOrYDgYrxGgEol0$CAr9h<0*5vpz$bJ6w@va_;9@G%91TLA!8OP~PQ z#RCa6XqiO|gSi4r3jnxgHFo7c3BW#C@QOLJ)f=p~0_+o=Ex?-(07;R@rMkeOxw!(V za~9!Xsb||RdRYZ=MxC=+QO3ywRXY?cX_=h^050^lKcGR|bGEy%1aSES1u(QV;J2}f O01+?)X4L~B0028L!THSq literal 0 HcmV?d00001 diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/images/logo-small.gif b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/images/logo-small.gif new file mode 100644 index 0000000000000000000000000000000000000000..703cf45fc78e6d31d4a9af460252b536b1c9854e GIT binary patch literal 1698 zcmV;T23`3_Nk%w1VYUE10K^&q%gfAUVr4x$Kl1YON=QuQ<>lDe*q4@=v9Pj!eSesj znO9X=ad2|Jy}yf!jHIKbv9Yp#e1F*3*>P`jS5;V~q@}*Tzl({C|Ns9mE;9fB{{R30 z000000000000000A^8LW000^QEC2ui0JZ==06+!*peBxFX^z0-1i_MJ3+p_pEh_&5dM^QH^o`2q?YC;|Y#eo6?SBFL~IkO9*W zUWrg(6a+6t1e9~gkzoUD0u)q?cL8IkHxMNMW_YDz4U&xn4G;-%fMrJwrreB*aD?3_ z1wa){Fo|t|jsdNTB$!ozNI7K6ROJ$p6pPVgF9`4wMB>|mt0D|wjG70m21m-KH6S4q zhKOfKG;JyM!j7010!F!0IkQPpts|OdaKxZQty_Z;XW06P@mIDOfgM&{!i#`0fD`e3 zQEdyS&0Nj2C9?Kr8lnz-R4p>0a~KE_K`S#&yS5Dk42ZH}fWWNn-@r{EpxZBi&EUv6 z8aN0#2?2n~qoYCA9N}^4*n51eZlv`Vo}$7KN0+^P4l3M z2>3zos9Q+@lo%19fEJ&v_eMl=Ver}i6~3L26fm|Wb=^(lB>@IXO1OprcmzanA$V+L zb^~<*z@))9>6GxyTD2hYPk$N-mINXQ^p_PtcqCwBVHzYQp9trqhK*03$jI3zp=`EL z4gk;<4l+DyFhEu)P)UL+z8NDzFH^jr%?TK>h?fa6iXfN(BusNv6&G%ik!z~7xy6*t zIl-j}Y9eFPWF!!y%L|M_g5H-VU{nL2eF8edifzfKN)iT20F<12yZv3FsjK z;Rr5efTm$DL^*<=i7qz6og;{q#A5}anraE7fn!1!py{+pbtXdbOp509;L?wY*qD(5 z06@@Q5uSu`O>_G}VTmEZ{vb*JgE&xUL1w2rpe-Fev@4h-90G~<(Y|8JzQl6785e#5UFuM(io2~!?FPxpW2UiiX#KE~* z@e34008|A3Hij{FaHUIu9SUF;&k<9N3>-uiQxHZ4U%WA%01CV85UvN?MKf#F{QQ#6 zwS{a20W27sMHohcl(Pv9{JSJU??&s;yP0%mi5&wxi^V4(W-tK+3tD074XPv%P67Jn zgWlPu)oR5^7&M*1$rz+WHy1@*`e+rU;lOHbgVTm}65KMKgaFOHA#`1H_0h5o&rIGb zE)5zmMj3GkP)KY67-azeT>((?w-JLB@U8#{nAQ0qC1>EkRbD)Is|#A0lK2~y79sN} zNG@y24sdXt_r~;iTHpx_=E*BaSP{$|$EWviZgdX{vBSluA zfC7ZqxHo|4cW)@0O6rG$hWUwSS3w4Z5G8{2&1zKz6h<&!@COo>P*Ep(L223&B{pG- z2y^&^Ds~qJqs^mjH~7XN@K6{!CC`PjdZDVeRKRC^iZLxrq7p~2JUof2D@uqT9E_kv z39)c17fSdz2oVk(|*9gP26mT@rLI(4sh?6#MCjsXOoCcz2gl2{9QVN>M zDBh=%)a0N50dPS1QV22^6&KcVi9jlXAybu*3hZqF zu;Jn-Qqr8K6@)kfNWj!GMXb&_vW`!zqp1P`D-sM~lX-ZeEsNm?6HFs{LTHX2-e5P0 zkjo5$5s}2!XM@Adqk=r!%(|SQh-ZjzVV3BW)ka{=J|u_>4l{-2o)9YhVN4aQ+W{Xl zVi%ZY#c|acCDCl7u_MR{1AEbx1k!1WaqiPJ^IWEzLb9vsZ1bQIlEVaoGL-Z@6r#YP s-o}b>F^nP~2bk%~rANzE00$7X3b6#@NZAEF2Ha}_46x5i%M$_sJDrx#NB{r; literal 0 HcmV?d00001 diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/images/notification.gif b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/public/webconfigurator/images/notification.gif new file mode 100644 index 0000000000000000000000000000000000000000..017fac8d8c940c37f18bb67713483c38c360b5b4 GIT binary patch literal 206 zcmZ?wbhEHb6lM@-I3mFC>htAm&sXicS+Vwf$f4T}FF##eeJ)_#`LM%xnvUFQdHwn7 z=1Ym2F2%3E5b^*2|5a!GfFuJcK=CIFBLjl~gAPa&$W8`UZv_@cj?Z&6cBwRQux9G8 z2PodpRD7_<;KPplXB}Bib?_zgtn@LQy<9!y))K9?7uH;hJd@OTzulnvMkXtR^R)|2 Sj+sgf4-aGuh%6Fdum%7^qDo`{ literal 0 HcmV?d00001 diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/Step/doctrine.html.twig b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/Step/doctrine.html.twig new file mode 100644 index 0000000..444d592 --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/Step/doctrine.html.twig @@ -0,0 +1,31 @@ +{% extends "SensioDistributionBundle::Configurator/layout.html.twig" %} + +{% block title %}Symfony - Configure database{% endblock %} + +{% block content %} + {% form_theme form "SensioDistributionBundle::Configurator/form.html.twig" %} + {% include "SensioDistributionBundle::Configurator/steps.html.twig" with { "index": index, "count": count } %} + +

    Configure your Database

    +

    If your website needs a database connection, please configure it here.

    + + {{ form_errors(form) }} +
    +
    + {{ form_row(form.driver) }} + {{ form_row(form.host) }} + {{ form_row(form.name) }} +
    +
    + {{ form_row(form.user) }} + {{ form_row(form.password) }} +
    + + {{ form_rest(form) }} + + + +{% endblock %} diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/Step/secret.html.twig b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/Step/secret.html.twig new file mode 100644 index 0000000..4718e7d --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/Step/secret.html.twig @@ -0,0 +1,44 @@ +{% extends "SensioDistributionBundle::Configurator/layout.html.twig" %} + +{% block title %}Symfony - Configure global Secret{% endblock %} + +{% block content %} + {% form_theme form "SensioDistributionBundle::Configurator/form.html.twig" %} + {% include "SensioDistributionBundle::Configurator/steps.html.twig" with { "index": index, "count": count } %} + +

    Global Secret

    +

    Configure the global secret for your website (the secret is used for the CSRF protection among other things):

    + + {{ form_errors(form) }} +
    +
    + {{ form_label(form.secret) }} +
    + {{ form_widget(form.secret) }} + Generate +
    + {{ form_errors(form.secret) }} +
    +
    +
    + + {{ form_rest(form) }} + + + + + + +{% endblock %} diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/check.html.twig b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/check.html.twig new file mode 100644 index 0000000..52a0648 --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/check.html.twig @@ -0,0 +1,43 @@ +{% extends "SensioDistributionBundle::Configurator/layout.html.twig" %} + +{% block content %} + {% if majors|length %} +

    Major Problems that need to be fixed now

    +

    + We have detected {{ majors|length }} major problems. + You must fix them before continuing: +

    +
      + {% for message in majors %} +
    1. {{ message }}
    2. + {% endfor %} +
    + {% endif %} + + {% if minors|length %} +

    Some Recommandations

    + +

    + {% if majors|length %} + Additionally, we + {% else %} + We + {% endif %} + have detected some minor problems that we recommend you to fix to have a better Symfony + experience: + +

      + {% for message in minors %} +
    1. {{ message }}
    2. + {% endfor %} +
    +

    + + {% endif %} + + {% if not majors|length %} + + {% endif %} +{% endblock %} diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/final.html.twig b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/final.html.twig new file mode 100644 index 0000000..f4a0237 --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/final.html.twig @@ -0,0 +1,28 @@ +{% extends "SensioDistributionBundle::Configurator/layout.html.twig" %} + +{% block content_class %}config_done{% endblock %} +{% block content %} +

    Well done!

    + {% if is_writable %} +

    Your distribution is configured!

    + {% else %} +

    Your distribution is almost configured but...

    + {% endif %} +

    + + {% if is_writable %} + Your parameters.yml file has been overwritten with these parameters (in {{ yml_path }}): + {% else %} + Your parameters.yml file is not writeable! Here are the parameters you can copy and paste in {{ yml_path }}: + {% endif %} + +

    + + + + {% if welcome_url %} + + {% endif %} +{% endblock %} diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/form.html.twig b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/form.html.twig new file mode 100644 index 0000000..ad7f8e6 --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/form.html.twig @@ -0,0 +1,31 @@ +{% extends "form_div_layout.html.twig" %} + +{% block field_rows %} +
    + {{ form_errors(form) }} +
    + {% for child in form.children %} + {{ form_row(child) }} + {% endfor %} +{% endblock field_rows %} + +{% block field_row %} +
    + {{ form_label(form) }} +
    + {{ form_widget(form) }} +
    + {{ form_errors(form) }} +
    +
    +
    +{% endblock %} + +{% block field_label %} + +{% endblock %} diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/layout.html.twig b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/layout.html.twig new file mode 100644 index 0000000..3238fc3 --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/layout.html.twig @@ -0,0 +1,20 @@ + + + + + + {% block title %}Web Configurator Bundle{% endblock %} + + + +
    +
    + Symfony logo +
    +
    + {% block content %}{% endblock %} +
    +
    Symfony Standard Edition v.{{ version }}
    +
    + + diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/steps.html.twig b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/steps.html.twig new file mode 100644 index 0000000..c228827 --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/views/Configurator/steps.html.twig @@ -0,0 +1,14 @@ +
    + {% for i in 1..count %} + + {% if i == index + 1 %} + Step {{ i }} + {% else %} + Step {{ i }} + {% endif %} + + {% if i != count %} + > + {% endif %} + {% endfor %} +
    diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/SensioDistributionBundle.php b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/SensioDistributionBundle.php new file mode 100644 index 0000000..88a2913 --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/SensioDistributionBundle.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 Sensio\Bundle\DistributionBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; +use Sensio\Bundle\DistributionBundle\Configurator\Step\DoctrineStep; +use Sensio\Bundle\DistributionBundle\Configurator\Step\SecretStep; + +/** + * SensioDistributionBundle. + * + * @author Fabien Potencier + * @author Marc Weistroff + */ +class SensioDistributionBundle extends Bundle +{ + public function boot() + { + $configurator = $this->container->get('sensio.distribution.webconfigurator'); + $configurator->addStep(new DoctrineStep($configurator->getParameters())); + $configurator->addStep(new SecretStep($configurator->getParameters())); + } +} diff --git a/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/composer.json b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/composer.json new file mode 100644 index 0000000..1a60e63 --- /dev/null +++ b/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/composer.json @@ -0,0 +1,20 @@ +{ + "name": "sensio/distribution-bundle", + "description": "The base bundle for the Symfony Distributions", + "keywords": ["distribution","configuration"], + "type": "symfony-bundle", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "require": { + "symfony/framework-bundle": "2.1.*" + }, + "autoload": { + "psr-0": { "Sensio\\Bundle\\DistributionBundle": "" } + }, + "target-dir": "Sensio/Bundle/DistributionBundle" +} diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/.travis.yml b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/.travis.yml new file mode 100644 index 0000000..96f6fb3 --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/.travis.yml @@ -0,0 +1,9 @@ +language: php + +php: + - 5.3 + - 5.4 + +before_script: + - wget http://getcomposer.org/composer.phar + - php composer.phar install diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/Cache.php b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/Cache.php new file mode 100644 index 0000000..959174c --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/Cache.php @@ -0,0 +1,171 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * The Cache class handles the @Cache annotation parts. + * + * @author Fabien Potencier + * @Annotation + */ +class Cache extends ConfigurationAnnotation +{ + /** + * The expiration date as a valid date for the strtotime() function. + * + * @var string + */ + protected $expires; + + /** + * The number of seconds that the response is considered fresh by a private + * cache like a web browser. + * + * @var integer + */ + protected $maxage; + + /** + * The number of seconds that the response is considered fresh by a public + * cache like a reverse proxy cache. + * + * @var integer + */ + protected $smaxage; + + /** + * Whether or not the response is public or not. + * + * @var integer + */ + protected $public; + + /** + * Additional "Vary:"-headers + * + * @var array + */ + protected $vary = array(); + + /** + * Returns the expiration date for the Expires header field. + * + * @return string + */ + public function getExpires() + { + return $this->expires; + } + + /** + * Sets the expiration date for the Expires header field. + * + * @param string $expires A valid php date + */ + public function setExpires($expires) + { + $this->expires = $expires; + } + + /** + * Sets the number of seconds for the max-age cache-control header field. + * + * @param integer $maxage A number of seconds + */ + public function setMaxAge($maxage) + { + $this->maxage = $maxage; + } + + /** + * Returns the number of seconds the response is considered fresh by a + * private cache. + * + * @return integer + */ + public function getMaxAge() + { + return $this->maxage; + } + + /** + * Sets the number of seconds for the s-maxage cache-control header field. + * + * @param integer $smaxage A number of seconds + */ + public function setSMaxAge($smaxage) + { + $this->smaxage = $smaxage; + } + + /** + * Returns the number of seconds the response is considered fresh by a + * public cache. + * + * @return integer + */ + public function getSMaxAge() + { + return $this->smaxage; + } + + /** + * Returns whether or not a response is public. + * + * @return Boolean + */ + public function isPublic() + { + return (Boolean) $this->public; + } + + /** + * Sets a response public. + * + * @param Boolean $public A boolean value + */ + public function setPublic($public) + { + $this->public = (Boolean) $public; + } + + /** + * Returns the custom "Vary"-headers + * + * @return array + */ + public function getVary() + { + return $this->vary; + } + + /** + * Add additional "Vary:"-headers + * + * @param array $vary + */ + public function setVary($vary) + { + $this->vary = $vary; + } + + /** + * Returns the annotation alias name. + * + * @return string + * @see ConfigurationInterface + */ + public function getAliasName() + { + return 'cache'; + } +} diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/ConfigurationAnnotation.php b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/ConfigurationAnnotation.php new file mode 100644 index 0000000..678de1a --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/ConfigurationAnnotation.php @@ -0,0 +1,22 @@ + + */ +abstract class ConfigurationAnnotation implements ConfigurationInterface +{ + public function __construct(array $values) + { + foreach ($values as $k => $v) { + if (!method_exists($this, $name = 'set'.$k)) { + throw new \RuntimeException(sprintf('Unknown key "%s" for annotation "@%s".', $k, get_class($this))); + } + + $this->$name($v); + } + } +} diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/ConfigurationInterface.php b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/ConfigurationInterface.php new file mode 100644 index 0000000..a30df65 --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/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. + */ + +/** + * ConfigurationInterface. + * + * @author Fabien Potencier + */ +interface ConfigurationInterface +{ + /** + * Returns the alias name for an annotated configuration. + * + * @return string + */ + function getAliasName(); +} diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/Method.php b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/Method.php new file mode 100644 index 0000000..2edad3b --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/Method.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * The Method class handles the @Method annotation parts. + * + * @author Fabien Potencier + * @Annotation + */ +class Method extends ConfigurationAnnotation +{ + /** + * An array of restricted HTTP methods. + * + * @var array + */ + protected $methods = array(); + + /** + * Returns the array of HTTP methods. + * + * @return array + */ + public function getMethods() + { + return $this->methods; + } + + /** + * Sets the HTTP methods. + * + * @param array|string $methods An HTTP method or an array of HTTP methods + */ + public function setMethods($methods) + { + $this->methods = is_array($methods) ? $methods : array($methods); + } + + /** + * Sets the HTTP methods. + * + * @param array|string $methods An HTTP method or an array of HTTP methods + */ + public function setValue($methods) + { + $this->setMethods($methods); + } + + /** + * Returns the annotation alias name. + * + * @return string + * @see ConfigurationInterface + */ + public function getAliasName() + { + return 'method'; + } +} diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/ParamConverter.php b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/ParamConverter.php new file mode 100644 index 0000000..89afc2e --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/ParamConverter.php @@ -0,0 +1,152 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * The ParamConverter class handles the @ParamConverter annotation parts. + * + * @ParamConverter("post", class="BlogBundle:Post") + * + * @author Fabien Potencier + * @Annotation + */ +class ParamConverter extends ConfigurationAnnotation +{ + /** + * The parameter name. + * + * @var string + */ + protected $name; + + /** + * The parameter class. + * + * @var string + */ + protected $class; + + /** + * An array of options. + * + * @var array + */ + protected $options = array(); + + /** + * Whether or not the parameter is optional. + * + * @var Boolean + */ + protected $optional = false; + + /** + * Returns the parameter name. + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Sets the parameter name. + * + * @param string $name The parameter name + */ + public function setValue($name) + { + $this->setName($name); + } + + /** + * Sets the parameter name. + * + * @param string $name The parameter name + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * Returns the parameter class name. + * + * @return string $name + */ + public function getClass() + { + return $this->class; + } + + /** + * Sets the parameter class name. + * + * @param string $class The parameter class name + */ + public function setClass($class) + { + $this->class = $class; + } + + /** + * Returns an array of options. + * + * @return array + */ + public function getOptions() + { + return $this->options; + } + + /** + * Sets an array of options. + * + * @param array $options An array of options + */ + public function setOptions($options) + { + $this->options = $options; + } + + /** + * Sets whether or not the parameter is optional. + * + * @param Boolean $optional Wether the parameter is optional + */ + public function setIsOptional($optional) + { + $this->optional = (Boolean) $optional; + } + + /** + * Returns whether or not the parameter is optional. + * + * @return Boolean + */ + public function isOptional() + { + return $this->optional; + } + + /** + * Returns the annotation alias name. + * + * @return string + * @see ConfigurationInterface + */ + public function getAliasName() + { + return 'converters'; + } +} diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/Route.php b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/Route.php new file mode 100644 index 0000000..efdaf76 --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/Route.php @@ -0,0 +1,33 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * @author Kris Wallsmith + * @Annotation + */ +class Route extends BaseRoute +{ + protected $service; + + public function setService($service) + { + $this->service = $service; + } + + public function getService() + { + return $this->service; + } +} diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/Template.php b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/Template.php new file mode 100644 index 0000000..bd87e17 --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Configuration/Template.php @@ -0,0 +1,148 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * The Template class handles the @Template annotation parts. + * + * @author Fabien Potencier + * @Annotation + */ +class Template extends ConfigurationAnnotation +{ + /** + * The template reference. + * + * @var TemplateReference + */ + protected $template; + + /** + * The template engine used when a specific template isnt specified + * + * @var string + */ + protected $engine = 'twig'; + + /** + * The associative array of template variables. + * + * @var array + */ + protected $vars = array(); + + /** + * Should the template be streamed? + * + * @var Boolean + */ + protected $streamable = false; + + /** + * Returns the array of templates variables. + * + * @return array + */ + public function getVars() + { + return $this->vars; + } + + /** + * @param Boolean $streamable + */ + public function setIsStreamable($streamable) + { + $this->streamable = $streamable; + } + + /** + * @return Boolean + */ + public function isStreamable() + { + return (Boolean) $this->streamable; + } + + /** + * Sets the template variables + * + * @param array $vars The template variables + */ + public function setVars($vars) + { + $this->vars = $vars; + } + + /** + * Returns the engine used when guessing template names + * + * @return string + */ + public function getEngine() + { + return $this->engine; + } + + /** + * Sets the engine used when guessing template names + * + * @param string + */ + public function setEngine($engine) + { + $this->engine = $engine; + } + + /** + * Sets the template logic name. + * + * @param string $template The template logic name + */ + public function setValue($template) + { + $this->setTemplate($template); + } + + /** + * Returns the template reference. + * + * @return TemplateReference + */ + public function getTemplate() + { + return $this->template; + } + + /** + * Sets the template reference. + * + * @param TemplateReference|string $template The template reference + */ + public function setTemplate($template) + { + $this->template = $template; + } + + /** + * Returns the annotation alias name. + * + * @return string + * @see ConfigurationInterface + */ + public function getAliasName() + { + return 'template'; + } +} diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/DependencyInjection/Compiler/AddParamConverterPass.php b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/DependencyInjection/Compiler/AddParamConverterPass.php new file mode 100644 index 0000000..b739e0b --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/DependencyInjection/Compiler/AddParamConverterPass.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 Sensio\Bundle\FrameworkExtraBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Adds tagged request.param_converter services to converter.manager service + * + * @author Fabien Potencier + */ +class AddParamConverterPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (false === $container->hasDefinition('sensio_framework_extra.converter.manager')) { + return; + } + + $definition = $container->getDefinition('sensio_framework_extra.converter.manager'); + foreach ($container->findTaggedServiceIds('request.param_converter') as $id => $attributes) { + $definition->addMethodCall('add', array(new Reference($id), isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0)); + } + } +} diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/DependencyInjection/Configuration.php b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/DependencyInjection/Configuration.php new file mode 100644 index 0000000..4c1b2d1 --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/DependencyInjection/Configuration.php @@ -0,0 +1,55 @@ + + */ +class Configuration +{ + /** + * Generates the configuration tree. + * + * @return Symfony\Component\Config\Definition\NodeInterface + */ + public function getConfigTree() + { + $treeBuilder = new TreeBuilder(); + $rootNode = $treeBuilder->root('sensio_framework_extra', 'array'); + + $rootNode + ->children() + ->arrayNode('router') + ->addDefaultsIfNotSet() + ->children() + ->booleanNode('annotations')->defaultTrue()->end() + ->end() + ->end() + ->arrayNode('request') + ->addDefaultsIfNotSet() + ->children() + ->booleanNode('converters')->defaultTrue()->end() + ->end() + ->end() + ->arrayNode('view') + ->addDefaultsIfNotSet() + ->children() + ->booleanNode('annotations')->defaultTrue()->end() + ->end() + ->end() + ->arrayNode('cache') + ->addDefaultsIfNotSet() + ->children() + ->booleanNode('annotations')->defaultTrue()->end() + ->end() + ->end() + ->end() + ; + + return $treeBuilder->buildTree(); + } +} diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/DependencyInjection/SensioFrameworkExtraExtension.php b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/DependencyInjection/SensioFrameworkExtraExtension.php new file mode 100644 index 0000000..7bee12d --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/DependencyInjection/SensioFrameworkExtraExtension.php @@ -0,0 +1,81 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * SensioFrameworkExtraExtension. + * + * @author Fabien Potencier + */ +class SensioFrameworkExtraExtension extends Extension +{ + public function load(array $configs, ContainerBuilder $container) + { + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + + $processor = new Processor(); + $configuration = new Configuration(); + + $config = $processor->process($configuration->getConfigTree(), $configs); + + $loader->load('services.xml'); + + $annotationsToLoad = array(); + + if ($config['router']['annotations']) { + $annotationsToLoad[] = 'routing.xml'; + } + + if ($config['request']['converters']) { + $annotationsToLoad[] = 'converters.xml'; + } + + if ($config['view']['annotations']) { + $annotationsToLoad[] = 'view.xml'; + } + + if ($config['cache']['annotations']) { + $annotationsToLoad[] = 'cache.xml'; + } + + if ($annotationsToLoad) { + // must be first + $loader->load('annotations.xml'); + + foreach ($annotationsToLoad as $config) { + $loader->load($config); + } + } + } + + /** + * Returns the base path for the XSD files. + * + * @return string The XSD base path + */ + public function getXsdValidationBasePath() + { + return __DIR__.'/../Resources/config/schema'; + } + + public function getNamespace() + { + return 'http://symfony.com/schema/dic/symfony_extra'; + } +} diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/EventListener/CacheListener.php b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/EventListener/CacheListener.php new file mode 100644 index 0000000..3dd6e87 --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/EventListener/CacheListener.php @@ -0,0 +1,65 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * The CacheListener class has the responsability to modify the + * Response object when a controller uses the @Cache annotation. + * + * @author Fabien Potencier + */ +class CacheListener +{ + /** + * Modifies the response to apply HTTP expiration header fields. + * + * @param FilterResponseEvent $event The notified event + */ + public function onKernelResponse(FilterResponseEvent $event) + { + if (!$configuration = $event->getRequest()->attributes->get('_cache')) { + return; + } + + $response = $event->getResponse(); + + if (!$response->isSuccessful()) { + return; + } + + if (null !== $configuration->getSMaxAge()) { + $response->setSharedMaxAge($configuration->getSMaxAge()); + } + + if (null !== $configuration->getMaxAge()) { + $response->setMaxAge($configuration->getMaxAge()); + } + + if (null !== $configuration->getExpires()) { + $date = \DateTime::createFromFormat('U', strtotime($configuration->getExpires()), new \DateTimeZone('UTC')); + $response->setExpires($date); + } + + if (null !== $configuration->getVary()) { + $response->setVary($configuration->getVary()); + } + + if ($configuration->isPublic()) { + $response->setPublic(); + } + + $event->setResponse($response); + } +} diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/EventListener/ControllerListener.php b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/EventListener/ControllerListener.php new file mode 100644 index 0000000..33f5d62 --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/EventListener/ControllerListener.php @@ -0,0 +1,64 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * The ControllerListener class parses annotation blocks located in + * controller classes. + * + * @author Fabien Potencier + */ +class ControllerListener +{ + /** + * @var \Doctrine\Common\Annotations\Reader + */ + protected $reader; + + /** + * Constructor. + * + * @param Reader $reader An Reader instance + */ + public function __construct(Reader $reader) + { + $this->reader = $reader; + } + + /** + * Modifies the Request object to apply configuration information found in + * controllers annotations like the template to render or HTTP caching + * configuration. + * + * @param FilterControllerEvent $event A FilterControllerEvent instance + */ + public function onKernelController(FilterControllerEvent $event) + { + if (!is_array($controller = $event->getController())) { + return; + } + + $object = new \ReflectionObject($controller[0]); + $method = $object->getMethod($controller[1]); + + $request = $event->getRequest(); + foreach (array_merge($this->reader->getClassAnnotations($object), $this->reader->getMethodAnnotations($method)) as $configuration) { + if ($configuration instanceof ConfigurationInterface) { + $request->attributes->set('_'.$configuration->getAliasName(), $configuration); + } + } + } +} diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/EventListener/ParamConverterListener.php b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/EventListener/ParamConverterListener.php new file mode 100644 index 0000000..b6df11e --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/EventListener/ParamConverterListener.php @@ -0,0 +1,85 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * The ParamConverterListener handles the @ParamConverter annotation. + * + * @author Fabien Potencier + */ +class ParamConverterListener +{ + /** + * @var Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterManager + */ + protected $manager; + + /** + * Constructor. + * + * @param ParamConverterManager $manager A ParamConverterManager instance + */ + public function __construct(ParamConverterManager $manager) + { + $this->manager = $manager; + } + + /** + * Modifies the ParamConverterManager instance. + * + * @param FilterControllerEvent $event A FilterControllerEvent instance + */ + public function onKernelController(FilterControllerEvent $event) + { + $controller = $event->getController(); + $request = $event->getRequest(); + $configurations = array(); + + if ($configuration = $request->attributes->get('_converters')) { + foreach (is_array($configuration) ? $configuration : array($configuration) as $configuration) { + $configurations[$configuration->getName()] = $configuration; + } + } + + if (is_array($controller)) { + $r = new \ReflectionMethod($controller[0], $controller[1]); + } else { + $r = new \ReflectionFunction($controller); + } + + // automatically apply conversion for non-configured objects + foreach ($r->getParameters() as $param) { + if (!$param->getClass()) { + continue; + } + + $name = $param->getName(); + + if (!isset($configurations[$name])) { + $configuration = new ParamConverter(array()); + $configuration->setName($name); + $configuration->setClass($param->getClass()->getName()); + + $configurations[$name] = $configuration; + } + + $configurations[$name]->setIsOptional($param->isOptional()); + } + + $this->manager->apply($request, $configurations); + } +} diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/EventListener/TemplateListener.php b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/EventListener/TemplateListener.php new file mode 100644 index 0000000..c8e2aa1 --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/EventListener/TemplateListener.php @@ -0,0 +1,126 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * The TemplateListener class handles the @Template annotation. + * + * @author Fabien Potencier + */ +class TemplateListener +{ + /** + * @var Symfony\Component\DependencyInjection\ContainerInterface + */ + protected $container; + + /** + * Constructor. + * + * @param ContainerInterface $container The service container instance + */ + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + /** + * Guesses the template name to render and its variables and adds them to + * the request object. + * + * @param FilterControllerEvent $event A FilterControllerEvent instance + */ + public function onKernelController(FilterControllerEvent $event) + { + if (!is_array($controller = $event->getController())) { + return; + } + + $request = $event->getRequest(); + + if (!$configuration = $request->attributes->get('_template')) { + return; + } + + if (!$configuration->getTemplate()) { + $guesser = $this->container->get('sensio_framework_extra.view.guesser'); + $configuration->setTemplate($guesser->guessTemplateName($controller, $request, $configuration->getEngine())); + } + + $request->attributes->set('_template', $configuration->getTemplate()); + $request->attributes->set('_template_vars', $configuration->getVars()); + $request->attributes->set('_template_streamable', $configuration->isStreamable()); + + // all controller method arguments + if (!$configuration->getVars()) { + $r = new \ReflectionObject($controller[0]); + + $vars = array(); + foreach ($r->getMethod($controller[1])->getParameters() as $param) { + $vars[] = $param->getName(); + } + + $request->attributes->set('_template_default_vars', $vars); + } + } + + /** + * Renders the template and initializes a new response object with the + * rendered template content. + * + * @param GetResponseForControllerResultEvent $event A GetResponseForControllerResultEvent instance + */ + public function onKernelView(GetResponseForControllerResultEvent $event) + { + $request = $event->getRequest(); + $parameters = $event->getControllerResult(); + $templating = $this->container->get('templating'); + + if (null === $parameters) { + if (!$vars = $request->attributes->get('_template_vars')) { + if (!$vars = $request->attributes->get('_template_default_vars')) { + return; + } + } + + $parameters = array(); + foreach ($vars as $var) { + $parameters[$var] = $request->attributes->get($var); + } + } + + if (!is_array($parameters)) { + return $parameters; + } + + if (!$template = $request->attributes->get('_template')) { + return $parameters; + } + + if (!$request->attributes->get('_template_streamable')) { + $event->setResponse($templating->renderResponse($template, $parameters)); + } else { + $callback = function () use ($templating, $template, $parameters) { + return $templating->stream($template, $parameters); + }; + + + $event->setResponse(new StreamedResponse($callback)); + } + } +} diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/LICENSE b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/LICENSE new file mode 100644 index 0000000..c6aa7e3 --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010,2011 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/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/README.md b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/README.md new file mode 100644 index 0000000..00918ae --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/README.md @@ -0,0 +1,6 @@ +SensioFrameworkExtraBundle +========================== + +This bundle provides a way to configure your controllers with annotations. + +Read about it on its [official homepage](http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/index.html). diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Request/ParamConverter/DoctrineParamConverter.php b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Request/ParamConverter/DoctrineParamConverter.php new file mode 100644 index 0000000..321f223 --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Request/ParamConverter/DoctrineParamConverter.php @@ -0,0 +1,108 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * DoctrineParamConverter. + * + * @author Fabien Potencier + */ +class DoctrineParamConverter implements ParamConverterInterface +{ + /** + * @var ManagerRegistry + */ + protected $registry; + + public function __construct(ManagerRegistry $registry = null) + { + $this->registry = $registry; + } + + public function apply(Request $request, ConfigurationInterface $configuration) + { + $class = $configuration->getClass(); + $options = $this->getOptions($configuration); + + // find by identifier? + if (false === $object = $this->find($class, $request, $options)) { + // find by criteria + if (false === $object = $this->findOneBy($class, $request, $options)) { + throw new \LogicException('Unable to guess how to get a Doctrine instance from the request information.'); + } + } + + if (null === $object && false === $configuration->isOptional()) { + throw new NotFoundHttpException(sprintf('%s object not found.', $class)); + } + + $request->attributes->set($configuration->getName(), $object); + + return true; + } + + protected function find($class, Request $request, $options) + { + if (!$request->attributes->has('id')) { + return false; + } + + return $this->registry->getRepository($class, $options['entity_manager'])->find($request->attributes->get('id')); + } + + protected function findOneBy($class, Request $request, $options) + { + $criteria = array(); + $metadata = $this->registry->getManager($options['entity_manager'])->getClassMetadata($class); + foreach ($request->attributes->all() as $key => $value) { + if ($metadata->hasField($key)) { + $criteria[$key] = $value; + } + } + + if (!$criteria) { + return false; + } + + return $this->registry->getRepository($class, $options['entity_manager'])->findOneBy($criteria); + } + + public function supports(ConfigurationInterface $configuration) + { + if (null === $this->registry) { + return false; + } + + if (null === $configuration->getClass()) { + return false; + } + + $options = $this->getOptions($configuration); + + // Doctrine Entity? + return ! $this->registry->getManager($options['entity_manager']) + ->getMetadataFactory() + ->isTransient($configuration->getClass()); + } + + protected function getOptions(ConfigurationInterface $configuration) + { + return array_replace(array( + 'entity_manager' => null, + ), $configuration->getOptions()); + } +} diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Request/ParamConverter/ParamConverterInterface.php b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Request/ParamConverter/ParamConverterInterface.php new file mode 100644 index 0000000..d5e0390 --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Request/ParamConverter/ParamConverterInterface.php @@ -0,0 +1,27 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * + * + * @author Fabien Potencier + */ +interface ParamConverterInterface +{ + function apply(Request $request, ConfigurationInterface $configuration); + + function supports(ConfigurationInterface $configuration); +} diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Request/ParamConverter/ParamConverterManager.php b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Request/ParamConverter/ParamConverterManager.php new file mode 100644 index 0000000..85e7c22 --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Request/ParamConverter/ParamConverterManager.php @@ -0,0 +1,92 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * Managers converters. + * + * @author Fabien Potencier + * @author Henrik Bjornskov + */ +class ParamConverterManager +{ + /** + * @var array + */ + protected $converters = array(); + + /** + * Applies all converters to the passed configurations and stops when a + * converter is applied it will move on to the next configuration and so on. + * + * @param Request $request + * @param array|object $configurations + */ + public function apply(Request $request, $configurations) + { + if (is_object($configurations)) { + $configurations = array($configurations); + } + + foreach ($configurations as $configuration) { + // If the value is already an instance of the class we are trying to convert it into + // we should continue as no convertion is required + $value = $request->attributes->get($configuration->getName()); + $className = $configuration->getClass(); + if (is_object($value) && $value instanceof $className) { + continue; + } + + foreach ($this->all() as $converter) { + if ($converter->supports($configuration)) { + if ($converter->apply($request, $configuration)) { + continue 2; + } + } + } + } + } + + /** + * Adds a parameter converter. + * + * @param ParamConverterInterface $converter A ParamConverterInterface instance + * @param integer $priority The priority (between -10 and 10) + */ + public function add(ParamConverterInterface $converter, $priority = 0) + { + if (!isset($this->converters[$priority])) { + $this->converters[$priority] = array(); + } + + $this->converters[$priority][] = $converter; + } + + /** + * Returns all registered param converters. + * + * @return array An array of param converters + */ + public function all() + { + krsort($this->converters); + + $converters = array(); + foreach ($this->converters as $all) { + $converters = array_merge($converters, $all); + } + + return $converters; + } +} diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/annotations.xml b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/annotations.xml new file mode 100644 index 0000000..7d2a7eb --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/annotations.xml @@ -0,0 +1,17 @@ + + + + + + Sensio\Bundle\FrameworkExtraBundle\EventListener\ControllerListener + + + + + + + + + diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/cache.xml b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/cache.xml new file mode 100644 index 0000000..4ebc930 --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/cache.xml @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/converters.xml b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/converters.xml new file mode 100644 index 0000000..8f7170e --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/converters.xml @@ -0,0 +1,26 @@ + + + + + + Sensio\Bundle\FrameworkExtraBundle\EventListener\ParamConverterListener + Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterManager + Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\DoctrineParamConverter + + + + + + + + + + + + + + + + diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/routing.xml b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/routing.xml new file mode 100644 index 0000000..b3b58cd --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/routing.xml @@ -0,0 +1,31 @@ + + + + + + Symfony\Component\Routing\Loader\AnnotationDirectoryLoader + Symfony\Component\Routing\Loader\AnnotationFileLoader + Sensio\Bundle\FrameworkExtraBundle\Routing\AnnotatedRouteControllerLoader + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/services.xml b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/services.xml new file mode 100644 index 0000000..6c76e61 --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/services.xml @@ -0,0 +1,17 @@ + + + + + + Sensio\Bundle\FrameworkExtraBundle\Templating\TemplateGuesser + + + + + + + + + diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/view.xml b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/view.xml new file mode 100644 index 0000000..e182902 --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/config/view.xml @@ -0,0 +1,18 @@ + + + + + + Sensio\Bundle\FrameworkExtraBundle\EventListener\TemplateListener + + + + + + + + + + diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/doc/annotations/cache.rst b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/doc/annotations/cache.rst new file mode 100644 index 0000000..a05d9f6 --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/doc/annotations/cache.rst @@ -0,0 +1,60 @@ +@Cache +====== + +Usage +----- + +The ``@Cache`` annotation makes it easy to define HTTP caching:: + + use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache; + + /** + * @Cache(expires="tomorrow") + */ + public function indexAction() + { + } + +You can also use the annotation on a class to define caching for all methods:: + + /** + * @Cache(expires="tomorrow") + */ + class BlogController extends Controller + { + } + +When there is a conflict between the class configuration and the method +configuration, the latter overrides the former:: + + /** + * @Cache(expires="tomorrow") + */ + class BlogController extends Controller + { + /** + * @Cache(expires="+2 days") + */ + public function indexAction() + { + } + } + +Attributes +---------- + +Here is a list of accepted attributes and their HTTP header equivalent: + +============================== =============== +Annotation Response Method +============================== =============== +``@Cache(expires="tomorrow")`` ``$response->setExpires()`` +``@Cache(smaxage="15")`` ``$response->setSharedMaxAge()`` +``@Cache(maxage="15")`` ``$response->setMaxAge()`` +``@Cache(vary=["Cookie"])`` ``$response->setVary()`` +============================== =============== + +.. note:: + + The ``expires`` attribute takes any valid date understood by the PHP + ``strtotime()`` function. diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/doc/annotations/converters.rst b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/doc/annotations/converters.rst new file mode 100644 index 0000000..1245afb --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/doc/annotations/converters.rst @@ -0,0 +1,101 @@ +@ParamConverter +=============== + +Usage +----- + +The ``@ParamConverter`` annotation calls *converters* to convert request +parameters to objects. These objects are stored as request attributes and so +they can be injected as controller method arguments:: + + use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; + use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; + + /** + * @Route("/blog/{id}") + * @ParamConverter("post", class="SensioBlogBundle:Post") + */ + public function showAction(Post $post) + { + } + +Several things happens under the hood: + +* The converter tries to get a ``SensioBlogBundle:Post`` object from the + request attributes (request attributes comes from route placeholders -- here + ``id``); + +* If no ``Post`` object is found, a ``404`` Response is generated; + +* If a ``Post`` object is found, a new ``post`` request attribute is defined + (accessible via ``$request->attributes->get('post')``); + +* As for any other request attribute, it is automatically injected in the + controller when present in the method signature. + +If you use type hinting as in the example above, you can even omit the +``@ParamConverter`` annotation altogether:: + + // automatic with method signature + public function showAction(Post $post) + { + } + +Built-in Converters +------------------- + +The bundle has only one built-in converter, the Doctrine one. + +Doctrine Converter +~~~~~~~~~~~~~~~~~~ + +By default, the Doctrine converter uses the *default* entity manager. This can +be configured with the ``entity_manager`` option:: + + use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; + use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; + + /** + * @Route("/blog/{id}") + * @ParamConverter("post", class="SensioBlogBundle:Post", options={"entity_manager" = "foo"}) + */ + public function showAction(Post $post) + { + } + +Creating a Converter +-------------------- + +All converters must implement the +:class:`Sensio\\Bundle\\FrameworkExtraBundle\\Request\\ParamConverter\\ParamConverterInterface`:: + + namespace Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter; + + use Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationInterface; + use Symfony\Component\HttpFoundation\Request; + + interface ParamConverterInterface + { + function apply(Request $request, ConfigurationInterface $configuration); + + function supports(ConfigurationInterface $configuration); + } + +The ``supports()`` method must return ``true`` when it is able to convert the +given configuration (a ``ParamConverter`` instance). + +The ``ParamConverter`` instance has three information about the annotation: + +* ``name``: The attribute name; +* ``class``: The attribute class name (can be any string representing a class + name); +* ``options``: An array of options + +The ``apply()`` method is called whenever a configuration is supported. Based +on the request attributes, it should set an attribute named +``$configuration->getName()``, which stores an object of class +``$configuration->getClass()``. + +.. tip:: + + Use the ``DoctrineParamConverter`` class as a template for your own converters. diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/doc/annotations/routing.rst b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/doc/annotations/routing.rst new file mode 100644 index 0000000..f993691 --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/doc/annotations/routing.rst @@ -0,0 +1,166 @@ +@Route and @Method +================== + +Usage +----- + +The @Route annotation maps a route pattern with a controller:: + + use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; + + class PostController extends Controller + { + /** + * @Route("/") + */ + public function indexAction() + { + // ... + } + } + +The ``index`` action of the ``Post`` controller is now mapped to the ``/`` +URL. This is equivalent to the following YAML configuration: + +.. code-block:: yaml + + blog_home: + pattern: / + defaults: { _controller: SensioBlogBundle:Post:index } + +Like any route pattern, you can define placeholders, requirements, and default +values:: + + /** + * @Route("/{id}", requirements={"id" = "\d+"}, defaults={"foo" = "bar"}) + */ + public function showAction($id) + { + } + +You can also match more than one URL by defining additional ``@Route`` +annotations:: + + /** + * @Route("/", defaults={"id" = 1}) + * @Route("/{id}") + */ + public function showAction($id) + { + } + +Activation +---------- + +The routes need to be imported to be active as any other routing resources +(note the ``annotation`` type): + +.. code-block:: yaml + + # app/config/routing.yml + + # import routes from a controller class + post: + resource: "@SensioBlogBundle/Controller/PostController.php" + type: annotation + +You can also import a whole directory: + +.. code-block:: yaml + + # import routes from a controller directory + blog: + resource: "@SensioBlogBundle/Controller" + type: annotation + +As for any other resource, you can "mount" the routes under a given prefix: + +.. code-block:: yaml + + post: + resource: "@SensioBlogBundle/Controller/PostController.php" + prefix: /blog + type: annotation + +Route Name +---------- + +A route defined with the ``@Route`` annotation is given a default name composed +of the bundle name, the controller name and the action name. That would be +``sensio_blog_post_index`` for the above example; + +The ``name`` attribute can be used to override this default route name:: + + /** + * @Route("/", name="blog_home") + */ + public function indexAction() + { + // ... + } + +Route Prefix +------------ + +A ``@Route`` annotation on a controller class defines a prefix for all action +routes:: + + /** + * @Route("/blog") + */ + class PostController extends Controller + { + /** + * @Route("/{id}") + */ + public function showAction($id) + { + } + } + +The ``show`` action is now mapped to the ``/blog/{id}`` pattern. + +Route Method +------------ + +There is a shortcut ``@Method`` annotation to specify the HTTP method allowed +for the route. To use it, import the ``Method`` annotation namespace:: + + use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; + use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; + + /** + * @Route("/blog") + */ + class PostController extends Controller + { + /** + * @Route("/edit/{id}") + * @Method({"GET", "POST"}) + */ + public function editAction($id) + { + } + } + +The ``edit`` action is now mapped to the ``/blog/edit/{id}`` pattern if the HTTP +method used is either GET or POST. + +The ``@Method`` annotation is only considered when an action is annotated with +``@Route``. + +Controller as Service +--------------------- + +The ``@Route`` annotation on a controller class can also be used to assign the +controller class to a service so that the controller resolver will instantiate +the controller by fetching it from the DI container instead of calling ``new +PostController()`` itself:: + + /** + * @Route(service="my_post_controller_service") + */ + class PostController extends Controller + { + // ... + } diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/doc/annotations/view.rst b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/doc/annotations/view.rst new file mode 100644 index 0000000..d96f94a --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/doc/annotations/view.rst @@ -0,0 +1,74 @@ +@Template +========= + +Usage +----- + +The ``@Template`` annotation associates a controller with a template name:: + + use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; + + /** + * @Template("SensioBlogBundle:Post:show.html.twig") + */ + public function showAction($id) + { + // get the Post + $post = ...; + + return array('post' => $post); + } + +When using the ``@Template`` annotation, the controller should return an +array of parameters to pass to the view instead of a ``Response`` object. + +.. tip:: + If the action returns a ``Response`` object, the ``@Template`` + annotation is simply ignored. + +If the template is named after the controller and action names, which is the +case for the above example, you can even omit the annotation value:: + + /** + * @Template + */ + public function showAction($id) + { + // get the Post + $post = ...; + + return array('post' => $post); + } + +And if the only parameters to pass to the template are method arguments, you +can use the ``vars`` attribute instead of returning an array. This is very +useful in combination with the ``@ParamConverter`` :doc:`annotation +`:: + + /** + * @ParamConverter("post", class="SensioBlogBundle:Post") + * @Template("SensioBlogBundle:Post:show.html.twig", vars={"post"}) + */ + public function showAction(Post $post) + { + } + +which, thanks to conventions, is equivalent to the following configuration:: + + /** + * @Template(vars={"post"}) + */ + public function showAction(Post $post) + { + } + +You can make it even more concise as all method arguments are automatically +passed to the template if the method returns ``null`` and no ``vars`` +attribute is defined:: + + /** + * @Template + */ + public function showAction(Post $post) + { + } diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/doc/index.rst b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/doc/index.rst new file mode 100644 index 0000000..fcf7a30 --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Resources/doc/index.rst @@ -0,0 +1,145 @@ +SensioFrameworkExtraBundle +========================== + +The default Symfony2 ``FrameworkBundle`` implements a basic but robust and +flexible MVC framework. `SensioFrameworkExtraBundle`_ extends it to add sweet +conventions and annotations. It allows for more concise controllers. + +Installation +------------ + +`Download`_ the bundle and put it under the ``Sensio\Bundle\`` namespace. +Then, like for any other bundle, include it in your Kernel class:: + + public function registerBundles() + { + $bundles = array( + ... + + new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(), + ); + + ... + } + +Configuration +------------- + +All features provided by the bundle are enabled by default when the bundle is +registered in your Kernel class. + +The default configuration is as follow: + +.. configuration-block:: + + .. code-block:: yaml + + sensio_framework_extra: + router: { annotations: true } + request: { converters: true } + view: { annotations: true } + cache: { annotations: true } + + .. code-block:: xml + + + + + + + + + + .. code-block:: php + + // load the profiler + $container->loadFromExtension('sensio_framework_extra', array( + 'router' => array('annotations' => true), + 'request' => array('converters' => true), + 'view' => array('annotations' => true), + 'cache' => array('annotations' => true), + )); + +You can disable some annotations and conventions by defining one or more +settings to false. + +Annotations for Controllers +--------------------------- + +Annotations are a great way to easily configure your controllers, from the +routes to the cache configuration. + +Even if annotations are not a native feature of PHP, it still has several +advantages over the classic Symfony2 configuration methods: + +* Code and configuration are in the same place (the controller class); +* Simple to learn and to use; +* Concise to write; +* Makes your Controller thin (as its sole responsibility is to get data from + the Model). + +.. tip:: + + If you use view classes, annotations are a great way to avoid creating + view classes for simple and common use cases. + +The following annotations are defined by the bundle: + +.. toctree:: + :maxdepth: 1 + + annotations/routing + annotations/converters + annotations/view + annotations/cache + +This example shows all the available annotations in action:: + + use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; + use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache; + use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; + use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; + use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; + + /** + * @Route("/blog") + * @Cache(expires="tomorrow") + */ + class AnnotController extends Controller + { + /** + * @Route("/") + * @Template + */ + public function indexAction() + { + $posts = ...; + + return array('posts' => $posts); + } + + /** + * @Route("/{id}") + * @Method("GET") + * @ParamConverter("post", class="SensioBlogBundle:Post") + * @Template("SensioBlogBundle:Annot:post.html.twig", vars={"post"}) + * @Cache(smaxage="15") + */ + public function showAction(Post $post) + { + } + } + +As the ``showAction`` method follows some conventions, you can omit some +annotations:: + + /** + * @Route("/{id}") + * @Cache(smaxage="15") + */ + public function showAction(Post $post) + { + } + +.. _`SensioFrameworkExtraBundle`: https://github.com/sensio/SensioFrameworkExtraBundle +.. _`Download`: http://github.com/sensio/SensioFrameworkExtraBundle diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Routing/AnnotatedRouteControllerLoader.php b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Routing/AnnotatedRouteControllerLoader.php new file mode 100644 index 0000000..1c19900 --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Routing/AnnotatedRouteControllerLoader.php @@ -0,0 +1,75 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * AnnotatedRouteControllerLoader is an implementation of AnnotationClassLoader + * that sets the '_controller' default based on the class and method names. + * + * It also parse the @Method annotation. + * + * @author Fabien Potencier + */ +class AnnotatedRouteControllerLoader extends AnnotationClassLoader +{ + /** + * Configures the _controller default parameter and eventually the _method + * requirement of a given Route instance. + * + * @param Route $route A Route instance + * @param ReflectionClass $class A ReflectionClass instance + * @param ReflectionMethod $method A ReflectionClass method + */ + protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, $annot) + { + // controller + $classAnnot = $this->reader->getClassAnnotation($class, $this->routeAnnotationClass); + if ($classAnnot && $service = $classAnnot->getService()) { + $route->setDefault('_controller', $service.':'.$method->getName()); + } else { + $route->setDefault('_controller', $class->getName().'::'.$method->getName()); + } + + // requirements (@Method) + foreach ($this->reader->getMethodAnnotations($method) as $configuration) { + if ($configuration instanceof Method) { + $route->setRequirement('_method', implode('|', $configuration->getMethods())); + } + } + } + + /** + * Makes the default route name more sane by removing common keywords. + * + * @param ReflectionClass $class A ReflectionClass instance + * @param ReflectionMethod $method A ReflectionMethod instance + * @return string + */ + protected function getDefaultRouteName(\ReflectionClass $class, \ReflectionMethod $method) + { + $routeName = parent::getDefaultRouteName($class, $method); + + return preg_replace(array( + '/(bundle|controller)_/', + '/action(_\d+)?$/', + '/__/' + ), array( + '_', + '\\1', + '_' + ), $routeName); + } +} diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/SensioFrameworkExtraBundle.php b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/SensioFrameworkExtraBundle.php new file mode 100644 index 0000000..2574a09 --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/SensioFrameworkExtraBundle.php @@ -0,0 +1,31 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * SensioFrameworkExtraBundle. + * + * @author Fabien Potencier + */ +class SensioFrameworkExtraBundle extends Bundle +{ + public function build(ContainerBuilder $container) + { + parent::build($container); + + $container->addCompilerPass(new AddParamConverterPass()); + } +} diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Templating/TemplateGuesser.php b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Templating/TemplateGuesser.php new file mode 100644 index 0000000..e2e2616 --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/Templating/TemplateGuesser.php @@ -0,0 +1,98 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * The TemplateGuesser class handles the guessing of template name based on controller + * + * @author Fabien Potencier + */ +class TemplateGuesser +{ + /** + * @var Symfony\Component\HttpKernel\KernelInterface + */ + protected $kernel; + + /** + * Constructor. + * + * @param KernelInterface $kernel A KernelInterface instance + */ + public function __construct(KernelInterface $kernel) + { + $this->kernel = $kernel; + } + + /** + * Guesses and returns the template name to render based on the controller + * and action names. + * + * @param array $controller An array storing the controller object and action method + * @param Request $request A Request instance + * @param string $engine + * @return TemplateReference template reference + * @throws \InvalidArgumentException + */ + public function guessTemplateName($controller, Request $request, $engine = 'twig') + { + $className = get_class($controller[0]); + + // When JMSSecurityExtraBundle is used it generates Controller classes as MyAccountController__CG__ + if (class_exists('CG\\Core\\ClassUtils')) { + $className = ClassUtils::getUserClass($className); + } + + if (!preg_match('/Controller\\\(.+)Controller$/', $className, $matchController)) { + throw new \InvalidArgumentException(sprintf('The "%s" class does not look like a controller class (it must be in a "Controller" sub-namespace and the class name must end with "Controller")', get_class($controller[0]))); + + } + if (!preg_match('/^(.+)Action$/', $controller[1], $matchAction)) { + throw new \InvalidArgumentException(sprintf('The "%s" method does not look like an action method (it does not end with Action)', $controller[1])); + } + + $bundle = $this->getBundleForClass($className); + + return new TemplateReference($bundle->getName(), $matchController[1], $matchAction[1], $request->getRequestFormat(), $engine); + } + + /** + * Returns the Bundle instance in which the given class name is located. + * + * @param string $class A fully qualified controller class name + * @param Bundle $bundle A Bundle instance + * @throws \InvalidArgumentException + */ + protected function getBundleForClass($class) + { + $reflectionClass = new \ReflectionClass($class); + $bundles = $this->kernel->getBundles(); + + do { + $namespace = $reflectionClass->getNamespaceName(); + foreach ($bundles as $bundle) { + if (0 === strpos($namespace, $bundle->getNamespace())) { + return $bundle; + } + } + $reflectionClass = $reflectionClass->getParentClass(); + } while ($reflectionClass); + + throw new \InvalidArgumentException(sprintf('The "%s" class does not belong to a registered bundle.', $class)); + } +} diff --git a/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/composer.json b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/composer.json new file mode 100644 index 0000000..793388d --- /dev/null +++ b/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/composer.json @@ -0,0 +1,26 @@ +{ + "name": "sensio/framework-extra-bundle", + "description": "This bundle provides a way to configure your controllers with annotations", + "keywords": ["annotations","controllers"], + "type": "symfony-bundle", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "require": { + "symfony/framework-bundle": "2.1.*", + "doctrine/common": ">=2.1,<2.4-dev" + }, + "autoload": { + "psr-0": { "Sensio\\Bundle\\FrameworkExtraBundle": "" } + }, + "target-dir": "Sensio/Bundle/FrameworkExtraBundle", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + } +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/.travis.yml b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/.travis.yml new file mode 100644 index 0000000..96f6fb3 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/.travis.yml @@ -0,0 +1,9 @@ +language: php + +php: + - 5.3 + - 5.4 + +before_script: + - wget http://getcomposer.org/composer.phar + - php composer.phar install diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/GenerateBundleCommand.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/GenerateBundleCommand.php new file mode 100644 index 0000000..9aa79ee --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/GenerateBundleCommand.php @@ -0,0 +1,316 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sensio\Bundle\GeneratorBundle\Command; + +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Output\Output; +use Symfony\Component\HttpKernel\KernelInterface; +use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; +use Sensio\Bundle\GeneratorBundle\Generator\BundleGenerator; +use Sensio\Bundle\GeneratorBundle\Manipulator\KernelManipulator; +use Sensio\Bundle\GeneratorBundle\Manipulator\RoutingManipulator; +use Sensio\Bundle\GeneratorBundle\Command\Helper\DialogHelper; + +/** + * Generates bundles. + * + * @author Fabien Potencier + */ +class GenerateBundleCommand extends ContainerAwareCommand +{ + private $generator; + + /** + * @see Command + */ + protected function configure() + { + $this + ->setDefinition(array( + new InputOption('namespace', '', InputOption::VALUE_REQUIRED, 'The namespace of the bundle to create'), + new InputOption('dir', '', InputOption::VALUE_REQUIRED, 'The directory where to create the bundle'), + new InputOption('bundle-name', '', InputOption::VALUE_REQUIRED, 'The optional bundle name'), + new InputOption('format', '', InputOption::VALUE_REQUIRED, 'Use the format for configuration files (php, xml, yml, or annotation)', 'annotation'), + new InputOption('structure', '', InputOption::VALUE_NONE, 'Whether to generate the whole directory structure'), + )) + ->setDescription('Generates a bundle') + ->setHelp(<<generate:bundle command helps you generates new bundles. + +By default, the command interacts with the developer to tweak the generation. +Any passed option will be used as a default value for the interaction +(--namespace is the only one needed if you follow the +conventions): + +php app/console generate:bundle --namespace=Acme/BlogBundle + +Note that you can use / instead of \\ for the namespace delimiter to avoid any +problem. + +If you want to disable any user interaction, use --no-interaction but don't forget to pass all needed options: + +php app/console generate:bundle --namespace=Acme/BlogBundle --dir=src [--bundle-name=...] --no-interaction + +Note that the bundle namespace must end with "Bundle". +EOT + ) + ->setName('generate:bundle') + ; + } + + /** + * @see Command + * + * @throws \InvalidArgumentException When namespace doesn't end with Bundle + * @throws \RuntimeException When bundle can't be executed + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $dialog = $this->getDialogHelper(); + + if ($input->isInteractive()) { + if (!$dialog->askConfirmation($output, $dialog->getQuestion('Do you confirm generation', 'yes', '?'), true)) { + $output->writeln('Command aborted'); + + return 1; + } + } + + foreach (array('namespace', 'dir') as $option) { + if (null === $input->getOption($option)) { + throw new \RuntimeException(sprintf('The "%s" option must be provided.', $option)); + } + } + + $namespace = Validators::validateBundleNamespace($input->getOption('namespace')); + if (!$bundle = $input->getOption('bundle-name')) { + $bundle = strtr($namespace, array('\\' => '')); + } + $bundle = Validators::validateBundleName($bundle); + $dir = Validators::validateTargetDir($input->getOption('dir'), $bundle, $namespace); + $format = Validators::validateFormat($input->getOption('format')); + $structure = $input->getOption('structure'); + + $dialog->writeSection($output, 'Bundle generation'); + + if (!$this->getContainer()->get('filesystem')->isAbsolutePath($dir)) { + $dir = getcwd().'/'.$dir; + } + + $generator = $this->getGenerator(); + $generator->generate($namespace, $bundle, $dir, $format, $structure); + + $output->writeln('Generating the bundle code: OK'); + + $errors = array(); + $runner = $dialog->getRunner($output, $errors); + + // check that the namespace is already autoloaded + $runner($this->checkAutoloader($output, $namespace, $bundle, $dir)); + + // register the bundle in the Kernel class + $runner($this->updateKernel($dialog, $input, $output, $this->getContainer()->get('kernel'), $namespace, $bundle)); + + // routing + $runner($this->updateRouting($dialog, $input, $output, $bundle, $format)); + + $dialog->writeGeneratorSummary($output, $errors); + } + + protected function interact(InputInterface $input, OutputInterface $output) + { + $dialog = $this->getDialogHelper(); + $dialog->writeSection($output, 'Welcome to the Symfony2 bundle generator'); + + // namespace + $output->writeln(array( + '', + 'Your application code must be written in bundles. This command helps', + 'you generate them easily.', + '', + 'Each bundle is hosted under a namespace (like Acme/Bundle/BlogBundle).', + 'The namespace should begin with a "vendor" name like your company name, your', + 'project name, or your client name, followed by one or more optional category', + 'sub-namespaces, and it should end with the bundle name itself', + '(which must have Bundle as a suffix).', + '', + 'See http://symfony.com/doc/current/cookbook/bundles/best_practices.html#index-1 for more', + 'details on bundle naming conventions.', + '', + 'Use / instead of \\ for the namespace delimiter to avoid any problem.', + '', + )); + + $namespace = $dialog->askAndValidate($output, $dialog->getQuestion('Bundle namespace', $input->getOption('namespace')), array('Sensio\Bundle\GeneratorBundle\Command\Validators', 'validateBundleNamespace'), false, $input->getOption('namespace')); + $input->setOption('namespace', $namespace); + + // bundle name + $bundle = $input->getOption('bundle-name') ?: strtr($namespace, array('\\Bundle\\' => '', '\\' => '')); + $output->writeln(array( + '', + 'In your code, a bundle is often referenced by its name. It can be the', + 'concatenation of all namespace parts but it\'s really up to you to come', + 'up with a unique name (a good practice is to start with the vendor name).', + 'Based on the namespace, we suggest '.$bundle.'.', + '', + )); + $bundle = $dialog->askAndValidate($output, $dialog->getQuestion('Bundle name', $bundle), array('Sensio\Bundle\GeneratorBundle\Command\Validators', 'validateBundleName'), false, $bundle); + $input->setOption('bundle-name', $bundle); + + // target dir + $dir = $input->getOption('dir') ?: dirname($this->getContainer()->getParameter('kernel.root_dir')).'/src'; + $output->writeln(array( + '', + 'The bundle can be generated anywhere. The suggested default directory uses', + 'the standard conventions.', + '', + )); + $dir = $dialog->askAndValidate($output, $dialog->getQuestion('Target directory', $dir), function ($dir) use ($bundle, $namespace) { return Validators::validateTargetDir($dir, $bundle, $namespace); }, false, $dir); + $input->setOption('dir', $dir); + + // format + $output->writeln(array( + '', + 'Determine the format to use for the generated configuration.', + '', + )); + $format = $dialog->askAndValidate($output, $dialog->getQuestion('Configuration format (yml, xml, php, or annotation)', $input->getOption('format')), array('Sensio\Bundle\GeneratorBundle\Command\Validators', 'validateFormat'), false, $input->getOption('format')); + $input->setOption('format', $format); + + // optional files to generate + $output->writeln(array( + '', + 'To help you get started faster, the command can generate some', + 'code snippets for you.', + '', + )); + + $structure = $input->getOption('structure'); + if (!$structure && $dialog->askConfirmation($output, $dialog->getQuestion('Do you want to generate the whole directory structure', 'no', '?'), false)) { + $structure = true; + } + $input->setOption('structure', $structure); + + // summary + $output->writeln(array( + '', + $this->getHelper('formatter')->formatBlock('Summary before generation', 'bg=blue;fg=white', true), + '', + sprintf("You are going to generate a \"%s\\%s\" bundle\nin \"%s\" using the \"%s\" format.", $namespace, $bundle, $dir, $format), + '', + )); + } + + protected function checkAutoloader(OutputInterface $output, $namespace, $bundle, $dir) + { + $output->write('Checking that the bundle is autoloaded: '); + if (!class_exists($namespace.'\\'.$bundle)) { + return array( + '- Edit the composer.json file and register the bundle', + ' namespace in the "autoload" section:', + '', + ); + } + } + + protected function updateKernel($dialog, InputInterface $input, OutputInterface $output, KernelInterface $kernel, $namespace, $bundle) + { + $auto = true; + if ($input->isInteractive()) { + $auto = $dialog->askConfirmation($output, $dialog->getQuestion('Confirm automatic update of your Kernel', 'yes', '?'), true); + } + + $output->write('Enabling the bundle inside the Kernel: '); + $manip = new KernelManipulator($kernel); + try { + $ret = $auto ? $manip->addBundle($namespace.'\\'.$bundle) : false; + + if (!$ret) { + $reflected = new \ReflectionObject($kernel); + + return array( + sprintf('- Edit %s', $reflected->getFilename()), + ' and add the following bundle in the AppKernel::registerBundles() method:', + '', + sprintf(' new %s(),', $namespace.'\\'.$bundle), + '', + ); + } + } catch (\RuntimeException $e) { + return array( + sprintf('Bundle %s is already defined in AppKernel::registerBundles().', $namespace.'\\'.$bundle), + '', + ); + } + } + + protected function updateRouting($dialog, InputInterface $input, OutputInterface $output, $bundle, $format) + { + $auto = true; + if ($input->isInteractive()) { + $auto = $dialog->askConfirmation($output, $dialog->getQuestion('Confirm automatic update of the Routing', 'yes', '?'), true); + } + + $output->write('Importing the bundle routing resource: '); + $routing = new RoutingManipulator($this->getContainer()->getParameter('kernel.root_dir').'/config/routing.yml'); + try { + $ret = $auto ? $routing->addResource($bundle, $format) : false; + if (!$ret) { + if ('annotation' === $format) { + $help = sprintf(" resource: \"@%s/Controller/\"\n type: annotation\n", $bundle); + } else { + $help = sprintf(" resource: \"@%s/Resources/config/routing.%s\"\n", $bundle, $format); + } + $help .= " prefix: /\n"; + + return array( + '- Import the bundle\'s routing resource in the app main routing file:', + '', + sprintf(' %s:', $bundle), + $help, + '', + ); + } + } catch (\RuntimeException $e) { + return array( + sprintf('Bundle %s is already imported.', $bundle), + '', + ); + } + } + + protected function getGenerator() + { + if (null === $this->generator) { + $this->generator = new BundleGenerator($this->getContainer()->get('filesystem'), __DIR__.'/../Resources/skeleton/bundle'); + } + + return $this->generator; + } + + public function setGenerator(BundleGenerator $generator) + { + $this->generator = $generator; + } + + protected function getDialogHelper() + { + $dialog = $this->getHelperSet()->get('dialog'); + if (!$dialog || get_class($dialog) !== 'Sensio\Bundle\GeneratorBundle\Command\Helper\DialogHelper') { + $this->getHelperSet()->set($dialog = new DialogHelper()); + } + + return $dialog; + } +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/GenerateDoctrineCommand.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/GenerateDoctrineCommand.php new file mode 100644 index 0000000..6c784f5 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/GenerateDoctrineCommand.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 Sensio\Bundle\GeneratorBundle\Command; + +use Doctrine\Bundle\DoctrineBundle\Mapping\MetadataFactory; +use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; + +abstract class GenerateDoctrineCommand extends ContainerAwareCommand +{ + public function isEnabled() + { + return class_exists('Doctrine\\Bundle\\DoctrineBundle\\DoctrineBundle'); + } + + protected function parseShortcutNotation($shortcut) + { + $entity = str_replace('/', '\\', $shortcut); + + if (false === $pos = strpos($entity, ':')) { + throw new \InvalidArgumentException(sprintf('The entity name must contain a : ("%s" given, expecting something like AcmeBlogBundle:Blog/Post)', $entity)); + } + + return array(substr($entity, 0, $pos), substr($entity, $pos + 1)); + } + + protected function getEntityMetadata($entity) + { + $factory = new MetadataFactory($this->getContainer()->get('doctrine')); + + return $factory->getClassMetadata($entity)->getMetadata(); + } +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/GenerateDoctrineCrudCommand.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/GenerateDoctrineCrudCommand.php new file mode 100644 index 0000000..dfe049a --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/GenerateDoctrineCrudCommand.php @@ -0,0 +1,274 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sensio\Bundle\GeneratorBundle\Command; + +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Output\Output; +use Symfony\Component\Console\Command\Command; +use Sensio\Bundle\GeneratorBundle\Generator\DoctrineCrudGenerator; +use Sensio\Bundle\GeneratorBundle\Generator\DoctrineFormGenerator; +use Sensio\Bundle\GeneratorBundle\Command\Helper\DialogHelper; +use Sensio\Bundle\GeneratorBundle\Manipulator\RoutingManipulator; + +/** + * Generates a CRUD for a Doctrine entity. + * + * @author Fabien Potencier + */ +class GenerateDoctrineCrudCommand extends GenerateDoctrineCommand +{ + private $generator; + private $formGenerator; + + /** + * @see Command + */ + protected function configure() + { + $this + ->setDefinition(array( + new InputOption('entity', '', InputOption::VALUE_REQUIRED, 'The entity class name to initialize (shortcut notation)'), + new InputOption('route-prefix', '', InputOption::VALUE_REQUIRED, 'The route prefix'), + new InputOption('with-write', '', InputOption::VALUE_NONE, 'Whether or not to generate create, new and delete actions'), + new InputOption('format', '', InputOption::VALUE_REQUIRED, 'Use the format for configuration files (php, xml, yml, or annotation)', 'annotation'), + )) + ->setDescription('Generates a CRUD based on a Doctrine entity') + ->setHelp(<<doctrine:generate:crud command generates a CRUD based on a Doctrine entity. + +The default command only generates the list and show actions. + +php app/console doctrine:generate:crud --entity=AcmeBlogBundle:Post --route-prefix=post_admin + +Using the --with-write option allows to generate the new, edit and delete actions. + +php app/console doctrine:generate:crud --entity=AcmeBlogBundle:Post --route-prefix=post_admin --with-write +EOT + ) + ->setName('doctrine:generate:crud') + ->setAliases(array('generate:doctrine:crud')) + ; + } + + /** + * @see Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $dialog = $this->getDialogHelper(); + + if ($input->isInteractive()) { + if (!$dialog->askConfirmation($output, $dialog->getQuestion('Do you confirm generation', 'yes', '?'), true)) { + $output->writeln('Command aborted'); + + return 1; + } + } + + $entity = Validators::validateEntityName($input->getOption('entity')); + list($bundle, $entity) = $this->parseShortcutNotation($entity); + + $format = Validators::validateFormat($input->getOption('format')); + $prefix = $this->getRoutePrefix($input, $entity); + $withWrite = $input->getOption('with-write'); + + $dialog->writeSection($output, 'CRUD generation'); + + $entityClass = $this->getContainer()->get('doctrine')->getEntityNamespace($bundle).'\\'.$entity; + $metadata = $this->getEntityMetadata($entityClass); + $bundle = $this->getContainer()->get('kernel')->getBundle($bundle); + + $generator = $this->getGenerator(); + $generator->generate($bundle, $entity, $metadata[0], $format, $prefix, $withWrite); + + $output->writeln('Generating the CRUD code: OK'); + + $errors = array(); + $runner = $dialog->getRunner($output, $errors); + + // form + if ($withWrite) { + $this->generateForm($bundle, $entity, $metadata); + $output->writeln('Generating the Form code: OK'); + } + + // routing + if ('annotation' != $format) { + $runner($this->updateRouting($dialog, $input, $output, $bundle, $format, $entity, $prefix)); + } + + $dialog->writeGeneratorSummary($output, $errors); + } + + protected function interact(InputInterface $input, OutputInterface $output) + { + $dialog = $this->getDialogHelper(); + $dialog->writeSection($output, 'Welcome to the Doctrine2 CRUD generator'); + + // namespace + $output->writeln(array( + '', + 'This command helps you generate CRUD controllers and templates.', + '', + 'First, you need to give the entity for which you want to generate a CRUD.', + 'You can give an entity that does not exist yet and the wizard will help', + 'you defining it.', + '', + 'You must use the shortcut notation like AcmeBlogBundle:Post.', + '', + )); + + $entity = $dialog->askAndValidate($output, $dialog->getQuestion('The Entity shortcut name', $input->getOption('entity')), array('Sensio\Bundle\GeneratorBundle\Command\Validators', 'validateEntityName'), false, $input->getOption('entity')); + $input->setOption('entity', $entity); + list($bundle, $entity) = $this->parseShortcutNotation($entity); + + // Entity exists? + $entityClass = $this->getContainer()->get('doctrine')->getEntityNamespace($bundle).'\\'.$entity; + $metadata = $this->getEntityMetadata($entityClass); + + // write? + $withWrite = $input->getOption('with-write') ?: false; + $output->writeln(array( + '', + 'By default, the generator creates two actions: list and show.', + 'You can also ask it to generate "write" actions: new, update, and delete.', + '', + )); + $withWrite = $dialog->askConfirmation($output, $dialog->getQuestion('Do you want to generate the "write" actions', $withWrite ? 'yes' : 'no', '?'), $withWrite); + $input->setOption('with-write', $withWrite); + + // format + $format = $input->getOption('format'); + $output->writeln(array( + '', + 'Determine the format to use for the generated CRUD.', + '', + )); + $format = $dialog->askAndValidate($output, $dialog->getQuestion('Configuration format (yml, xml, php, or annotation)', $format), array('Sensio\Bundle\GeneratorBundle\Command\Validators', 'validateFormat'), false, $format); + $input->setOption('format', $format); + + // route prefix + $prefix = $this->getRoutePrefix($input, $entity); + $output->writeln(array( + '', + 'Determine the routes prefix (all the routes will be "mounted" under this', + 'prefix: /prefix/, /prefix/new, ...).', + '', + )); + $prefix = $dialog->ask($output, $dialog->getQuestion('Routes prefix', '/'.$prefix), '/'.$prefix); + $input->setOption('route-prefix', $prefix); + + // summary + $output->writeln(array( + '', + $this->getHelper('formatter')->formatBlock('Summary before generation', 'bg=blue;fg=white', true), + '', + sprintf("You are going to generate a CRUD controller for \"%s:%s\"", $bundle, $entity), + sprintf("using the \"%s\" format.", $format), + '', + )); + } + + /** + * Tries to generate forms if they don't exist yet and if we need write operations on entities. + */ + private function generateForm($bundle, $entity, $metadata) + { + try { + $this->getFormGenerator()->generate($bundle, $entity, $metadata[0]); + } catch (\RuntimeException $e ) { + // form already exists + } + } + + private function updateRouting($dialog, InputInterface $input, OutputInterface $output, $bundle, $format, $entity, $prefix) + { + $auto = true; + if ($input->isInteractive()) { + $auto = $dialog->askConfirmation($output, $dialog->getQuestion('Confirm automatic update of the Routing', 'yes', '?'), true); + } + + $output->write('Importing the CRUD routes: '); + $this->getContainer()->get('filesystem')->mkdir($bundle->getPath().'/Resources/config/'); + $routing = new RoutingManipulator($bundle->getPath().'/Resources/config/routing.yml'); + try { + $ret = $auto ? $routing->addResource($bundle->getName(), $format, '/'.$prefix, 'routing/'.strtolower(str_replace('\\', '_', $entity))) : false; + } catch (\RuntimeException $exc) { + $ret = false; + } + + if (!$ret) { + $help = sprintf(" resource: \"@%s/Resources/config/routing/%s.%s\"\n", $bundle->getName(), strtolower(str_replace('\\', '_', $entity)), $format); + $help .= sprintf(" prefix: /%s\n", $prefix); + + return array( + '- Import the bundle\'s routing resource in the bundle routing file', + sprintf(' (%s).', $bundle->getPath().'/Resources/config/routing.yml'), + '', + sprintf(' %s:', $bundle->getName().('' !== $prefix ? '_'.str_replace('/', '_', $prefix) : '')), + $help, + '', + ); + } + } + + protected function getRoutePrefix(InputInterface $input, $entity) + { + $prefix = $input->getOption('route-prefix') ?: strtolower(str_replace(array('\\', '/'), '_', $entity)); + + if ($prefix && '/' === $prefix[0]) { + $prefix = substr($prefix, 1); + } + + return $prefix; + } + + protected function getGenerator() + { + if (null === $this->generator) { + $this->generator = new DoctrineCrudGenerator($this->getContainer()->get('filesystem'), __DIR__.'/../Resources/skeleton/crud'); + } + + return $this->generator; + } + + public function setGenerator(DoctrineCrudGenerator $generator) + { + $this->generator = $generator; + } + + protected function getFormGenerator() + { + if (null === $this->formGenerator) { + $this->formGenerator = new DoctrineFormGenerator($this->getContainer()->get('filesystem'), __DIR__.'/../Resources/skeleton/form'); + } + + return $this->formGenerator; + } + + public function setFormGenerator(DoctrineFormGenerator $formGenerator) + { + $this->formGenerator = $formGenerator; + } + + protected function getDialogHelper() + { + $dialog = $this->getHelperSet()->get('dialog'); + if (!$dialog || get_class($dialog) !== 'Sensio\Bundle\GeneratorBundle\Command\Helper\DialogHelper') { + $this->getHelperSet()->set($dialog = new DialogHelper()); + } + + return $dialog; + } +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/GenerateDoctrineEntityCommand.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/GenerateDoctrineEntityCommand.php new file mode 100644 index 0000000..5e0c89e --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/GenerateDoctrineEntityCommand.php @@ -0,0 +1,312 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sensio\Bundle\GeneratorBundle\Command; + +use Sensio\Bundle\GeneratorBundle\Generator\DoctrineEntityGenerator; +use Sensio\Bundle\GeneratorBundle\Command\Helper\DialogHelper; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Doctrine\DBAL\Types\Type; + +/** + * Initializes a Doctrine entity inside a bundle. + * + * @author Fabien Potencier + */ +class GenerateDoctrineEntityCommand extends GenerateDoctrineCommand +{ + private $generator; + + protected function configure() + { + $this + ->setName('doctrine:generate:entity') + ->setAliases(array('generate:doctrine:entity')) + ->setDescription('Generates a new Doctrine entity inside a bundle') + ->addOption('entity', null, InputOption::VALUE_REQUIRED, 'The entity class name to initialize (shortcut notation)') + ->addOption('fields', null, InputOption::VALUE_REQUIRED, 'The fields to create with the new entity') + ->addOption('format', null, InputOption::VALUE_REQUIRED, 'Use the format for configuration files (php, xml, yml, or annotation)', 'annotation') + ->addOption('with-repository', null, InputOption::VALUE_NONE, 'Whether to generate the entity repository or not') + ->setHelp(<<doctrine:generate:entity task generates a new Doctrine +entity inside a bundle: + +php app/console doctrine:generate:entity --entity=AcmeBlogBundle:Blog/Post + +The above command would initialize a new entity in the following entity +namespace Acme\BlogBundle\Entity\Blog\Post. + +You can also optionally specify the fields you want to generate in the new +entity: + +php app/console doctrine:generate:entity --entity=AcmeBlogBundle:Blog/Post --fields="title:string(255) body:text" + +The command can also generate the corresponding entity repository class with the +--with-repository option: + +php app/console doctrine:generate:entity --entity=AcmeBlogBundle:Blog/Post --with-repository + +By default, the command uses annotations for the mapping information; change it +with --format: + +php app/console doctrine:generate:entity --entity=AcmeBlogBundle:Blog/Post --format=yml + +To deactivate the interaction mode, simply use the `--no-interaction` option +without forgetting to pass all needed options: + +php app/console doctrine:generate:entity --entity=AcmeBlogBundle:Blog/Post --format=annotation --fields="title:string(255) body:text" --with-repository --no-interaction +EOT + ); + } + + /** + * @throws \InvalidArgumentException When the bundle doesn't end with Bundle (Example: "Bundle/MySampleBundle") + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $dialog = $this->getDialogHelper(); + + if ($input->isInteractive()) { + if (!$dialog->askConfirmation($output, $dialog->getQuestion('Do you confirm generation', 'yes', '?'), true)) { + $output->writeln('Command aborted'); + + return 1; + } + } + + $entity = Validators::validateEntityName($input->getOption('entity')); + list($bundle, $entity) = $this->parseShortcutNotation($entity); + $format = Validators::validateFormat($input->getOption('format')); + $fields = $this->parseFields($input->getOption('fields')); + + $dialog->writeSection($output, 'Entity generation'); + + $bundle = $this->getContainer()->get('kernel')->getBundle($bundle); + + $generator = $this->getGenerator(); + $generator->generate($bundle, $entity, $format, array_values($fields), $input->getOption('with-repository')); + + $output->writeln('Generating the entity code: OK'); + + $dialog->writeGeneratorSummary($output, array()); + } + + protected function interact(InputInterface $input, OutputInterface $output) + { + $dialog = $this->getDialogHelper(); + $dialog->writeSection($output, 'Welcome to the Doctrine2 entity generator'); + + // namespace + $output->writeln(array( + '', + 'This command helps you generate Doctrine2 entities.', + '', + 'First, you need to give the entity name you want to generate.', + 'You must use the shortcut notation like AcmeBlogBundle:Post.', + '' + )); + + while (true) { + $entity = $dialog->askAndValidate($output, $dialog->getQuestion('The Entity shortcut name', $input->getOption('entity')), array('Sensio\Bundle\GeneratorBundle\Command\Validators', 'validateEntityName'), false, $input->getOption('entity')); + + list($bundle, $entity) = $this->parseShortcutNotation($entity); + + // check reserved words + if ($this->getGenerator()->isReservedKeyword($entity)){ + $output->writeln(sprintf(' "%s" is a reserved word.', $entity)); + continue; + } + + try { + $b = $this->getContainer()->get('kernel')->getBundle($bundle); + + if (!file_exists($b->getPath().'/Entity/'.str_replace('\\', '/', $entity).'.php')) { + break; + } + + $output->writeln(sprintf('Entity "%s:%s" already exists.', $bundle, $entity)); + } catch (\Exception $e) { + $output->writeln(sprintf('Bundle "%s" does not exist.', $bundle)); + } + } + $input->setOption('entity', $bundle.':'.$entity); + + // format + $output->writeln(array( + '', + 'Determine the format to use for the mapping information.', + '', + )); + $format = $dialog->askAndValidate($output, $dialog->getQuestion('Configuration format (yml, xml, php, or annotation)', $input->getOption('format')), array('Sensio\Bundle\GeneratorBundle\Command\Validators', 'validateFormat'), false, $input->getOption('format')); + $input->setOption('format', $format); + + // fields + $input->setOption('fields', $this->addFields($input, $output, $dialog)); + + // repository? + $output->writeln(''); + $withRepository = $dialog->askConfirmation($output, $dialog->getQuestion('Do you want to generate an empty repository class', $input->getOption('with-repository') ? 'yes' : 'no', '?'), $input->getOption('with-repository')); + $input->setOption('with-repository', $withRepository); + + // summary + $output->writeln(array( + '', + $this->getHelper('formatter')->formatBlock('Summary before generation', 'bg=blue;fg=white', true), + '', + sprintf("You are going to generate a \"%s:%s\" Doctrine2 entity", $bundle, $entity), + sprintf("using the \"%s\" format.", $format), + '', + )); + } + + private function parseFields($input) + { + if (is_array($input)) { + return $input; + } + + $fields = array(); + foreach (explode(' ', $input) as $value) { + $elements = explode(':', $value); + $name = $elements[0]; + if (strlen($name)) { + $type = isset($elements[1]) ? $elements[1] : 'string'; + preg_match_all('/(.*)\((.*)\)/', $type, $matches); + $type = isset($matches[1][0]) ? $matches[1][0] : $type; + $length = isset($matches[2][0]) ? $matches[2][0] : null; + + $fields[$name] = array('fieldName' => $name, 'type' => $type, 'length' => $length); + } + } + + return $fields; + } + + private function addFields(InputInterface $input, OutputInterface $output, DialogHelper $dialog) + { + $fields = $this->parseFields($input->getOption('fields')); + $output->writeln(array( + '', + 'Instead of starting with a blank entity, you can add some fields now.', + 'Note that the primary key will be added automatically (named id).', + '', + )); + $output->write('Available types: '); + + $types = array_keys(Type::getTypesMap()); + $count = 20; + foreach ($types as $i => $type) { + if ($count > 50) { + $count = 0; + $output->writeln(''); + } + $count += strlen($type); + $output->write(sprintf('%s', $type)); + if (count($types) != $i + 1) { + $output->write(', '); + } else { + $output->write('.'); + } + } + $output->writeln(''); + + $fieldValidator = function ($type) use ($types) { + // FIXME: take into account user-defined field types + if (!in_array($type, $types)) { + throw new \InvalidArgumentException(sprintf('Invalid type "%s".', $type)); + } + + return $type; + }; + + $lengthValidator = function ($length) { + if (!$length) { + return $length; + } + + $result = filter_var($length, FILTER_VALIDATE_INT, array( + 'options' => array('min_range' => 1) + )); + + if (false === $result) { + throw new \InvalidArgumentException(sprintf('Invalid length "%s".', $length)); + } + + return $length; + }; + + while (true) { + $output->writeln(''); + $self = $this; + $name = $dialog->askAndValidate($output, $dialog->getQuestion('New field name (press to stop adding fields)', null), function ($name) use ($fields, $self) { + if (isset($fields[$name]) || 'id' == $name) { + throw new \InvalidArgumentException(sprintf('Field "%s" is already defined.', $name)); + } + + // check reserved words + if ($self->getGenerator()->isReservedKeyword($name)){ + throw new \InvalidArgumentException(sprintf('Name "%s" is a reserved word.', $name)); + } + + return $name; + }); + if (!$name) { + break; + } + + $defaultType = 'string'; + + if (substr($name, -3) == '_at') { + $defaultType = 'datetime'; + } elseif (substr($name, -3) == '_id') { + $defaultType = 'integer'; + } + + $type = $dialog->askAndValidate($output, $dialog->getQuestion('Field type', $defaultType), $fieldValidator, false, $defaultType); + + $data = array('fieldName' => $name, 'type' => $type); + + if ($type == 'string') { + $data['length'] = $dialog->askAndValidate($output, $dialog->getQuestion('Field length', 255), $lengthValidator, false, 255); + } + + $fields[$name] = $data; + } + + return $fields; + } + + public function getGenerator() + { + if (null === $this->generator) { + $this->generator = new DoctrineEntityGenerator($this->getContainer()->get('filesystem'), $this->getContainer()->get('doctrine')); + } + + return $this->generator; + } + + public function setGenerator(DoctrineEntityGenerator $generator) + { + $this->generator = $generator; + } + + protected function getDialogHelper() + { + $dialog = $this->getHelperSet()->get('dialog'); + if (!$dialog || get_class($dialog) !== 'Sensio\Bundle\GeneratorBundle\Command\Helper\DialogHelper') { + $this->getHelperSet()->set($dialog = new DialogHelper()); + } + + return $dialog; + } +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/GenerateDoctrineFormCommand.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/GenerateDoctrineFormCommand.php new file mode 100644 index 0000000..412b46a --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/GenerateDoctrineFormCommand.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 Sensio\Bundle\GeneratorBundle\Command; + +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Output\Output; +use Symfony\Component\Console\Command\Command; +use Sensio\Bundle\GeneratorBundle\Generator\DoctrineFormGenerator; + +/** + * Generates a form type class for a given Doctrine entity. + * + * @author Fabien Potencier + * @author Hugo Hamon + */ +class GenerateDoctrineFormCommand extends GenerateDoctrineCommand +{ + /** + * @see Command + */ + protected function configure() + { + $this + ->setDefinition(array( + new InputArgument('entity', InputArgument::REQUIRED, 'The entity class name to initialize (shortcut notation)'), + )) + ->setDescription('Generates a form type class based on a Doctrine entity') + ->setHelp(<<doctrine:generate:form command generates a form class based on a Doctrine entity. + +php app/console doctrine:generate:form AcmeBlogBundle:Post +EOT + ) + ->setName('doctrine:generate:form') + ->setAliases(array('generate:doctrine:form')) + ; + } + + /** + * @see Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $entity = Validators::validateEntityName($input->getArgument('entity')); + list($bundle, $entity) = $this->parseShortcutNotation($entity); + + $entityClass = $this->getContainer()->get('doctrine')->getEntityNamespace($bundle).'\\'.$entity; + $metadata = $this->getEntityMetadata($entityClass); + $bundle = $this->getApplication()->getKernel()->getBundle($bundle); + + $generator = new DoctrineFormGenerator($this->getContainer()->get('filesystem'), __DIR__.'/../Resources/skeleton/form'); + $generator->generate($bundle, $entity, $metadata[0]); + + $output->writeln(sprintf( + 'The new %s.php class file has been created under %s.', + $generator->getClassName(), + $generator->getClassPath() + )); + } +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/Helper/DialogHelper.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/Helper/DialogHelper.php new file mode 100644 index 0000000..c0d8c10 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/Helper/DialogHelper.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 Sensio\Bundle\GeneratorBundle\Command\Helper; + +use Symfony\Component\Console\Helper\DialogHelper as BaseDialogHelper; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Generates bundles. + * + * @author Fabien Potencier + */ +class DialogHelper extends BaseDialogHelper +{ + public function writeGeneratorSummary(OutputInterface $output, $errors) + { + if (!$errors) { + $this->writeSection($output, 'You can now start using the generated code!'); + } else { + $this->writeSection($output, array( + 'The command was not able to configure everything automatically.', + 'You must do the following changes manually.', + ), 'error'); + + $output->writeln($errors); + } + } + + public function getRunner(OutputInterface $output, &$errors) + { + $runner = function ($err) use ($output, &$errors) { + if ($err) { + $output->writeln('FAILED'); + $errors = array_merge($errors, $err); + } else { + $output->writeln('OK'); + } + }; + + return $runner; + } + + public function writeSection(OutputInterface $output, $text, $style = 'bg=blue;fg=white') + { + $output->writeln(array( + '', + $this->getHelperSet()->get('formatter')->formatBlock($text, $style, true), + '', + )); + } + + public function getQuestion($question, $default, $sep = ':') + { + return $default ? sprintf('%s [%s]%s ', $question, $default, $sep) : sprintf('%s%s ', $question, $sep); + } +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/Validators.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/Validators.php new file mode 100644 index 0000000..7904da2 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Command/Validators.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 Sensio\Bundle\GeneratorBundle\Command; + +/** + * Validator functions. + * + * @author Fabien Potencier + */ +class Validators +{ + static public function validateBundleNamespace($namespace) + { + if (!preg_match('/Bundle$/', $namespace)) { + throw new \InvalidArgumentException('The namespace must end with Bundle.'); + } + + $namespace = strtr($namespace, '/', '\\'); + if (!preg_match('/^(?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\\\?)+$/', $namespace)) { + throw new \InvalidArgumentException('The namespace contains invalid characters.'); + } + + // validate reserved keywords + $reserved = self::getReservedWords(); + foreach (explode('\\', $namespace) as $word) { + if (in_array(strtolower($word), $reserved)) { + throw new \InvalidArgumentException(sprintf('The namespace cannot contain PHP reserved words ("%s").', $word)); + } + } + + // validate that the namespace is at least one level deep + if (false === strpos($namespace, '\\')) { + $msg = array(); + $msg[] = sprintf('The namespace must contain a vendor namespace (e.g. "VendorName\%s" instead of simply "%s").', $namespace, $namespace); + $msg[] = 'If you\'ve specified a vendor namespace, did you forget to surround it with quotes (init:bundle "Acme\BlogBundle")?'; + + throw new \InvalidArgumentException(implode("\n\n", $msg)); + } + + return $namespace; + } + + static public function validateBundleName($bundle) + { + if (!preg_match('/Bundle$/', $bundle)) { + throw new \InvalidArgumentException('The bundle name must end with Bundle.'); + } + + return $bundle; + } + + static public function validateTargetDir($dir, $bundle, $namespace) + { + // add trailing / if necessary + return '/' === substr($dir, -1, 1) ? $dir : $dir.'/'; + } + + static public function validateFormat($format) + { + $format = strtolower($format); + + if (!in_array($format, array('php', 'xml', 'yml', 'annotation'))) { + throw new \RuntimeException(sprintf('Format "%s" is not supported.', $format)); + } + + return $format; + } + + static public function validateEntityName($entity) + { + if (false === $pos = strpos($entity, ':')) { + throw new \InvalidArgumentException(sprintf('The entity name must contain a : ("%s" given, expecting something like AcmeBlogBundle:Blog/Post)', $entity)); + } + + return $entity; + } + + static public function getReservedWords() + { + return array( + 'abstract', + 'and', + 'array', + 'as', + 'break', + 'case', + 'catch', + 'class', + 'clone', + 'const', + 'continue', + 'declare', + 'default', + 'do', + 'else', + 'elseif', + 'enddeclare', + 'endfor', + 'endforeach', + 'endif', + 'endswitch', + 'endwhile', + 'extends', + 'final', + 'for', + 'foreach', + 'function', + 'global', + 'goto', + 'if', + 'implements', + 'interface', + 'instanceof', + 'namespace', + 'new', + 'or', + 'private', + 'protected', + 'public', + 'static', + 'switch', + 'throw', + 'try', + 'use', + 'var', + 'while', + 'xor', + '__CLASS__', + '__DIR__', + '__FILE__', + '__LINE__', + '__FUNCTION__', + '__METHOD__', + '__NAMESPACE__', + 'die', + 'echo', + 'empty', + 'exit', + 'eval', + 'include', + 'include_once', + 'isset', + 'list', + 'require', + 'require_once', + 'return', + 'print', + 'unset', + ); + } +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Generator/BundleGenerator.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Generator/BundleGenerator.php new file mode 100644 index 0000000..049cdec --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Generator/BundleGenerator.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 Sensio\Bundle\GeneratorBundle\Generator; + +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\DependencyInjection\Container; + +/** + * Generates a bundle. + * + * @author Fabien Potencier + */ +class BundleGenerator extends Generator +{ + private $filesystem; + private $skeletonDir; + + public function __construct(Filesystem $filesystem, $skeletonDir) + { + $this->filesystem = $filesystem; + $this->skeletonDir = $skeletonDir; + } + + public function generate($namespace, $bundle, $dir, $format, $structure) + { + $dir .= '/'.strtr($namespace, '\\', '/'); + if (file_exists($dir)) { + throw new \RuntimeException(sprintf('Unable to generate the bundle as the target directory "%s" is not empty.', realpath($dir))); + } + + $basename = substr($bundle, 0, -6); + $parameters = array( + 'namespace' => $namespace, + 'bundle' => $bundle, + 'format' => $format, + 'bundle_basename' => $basename, + 'extension_alias' => Container::underscore($basename), + ); + + $this->renderFile($this->skeletonDir, 'Bundle.php', $dir.'/'.$bundle.'.php', $parameters); + $this->renderFile($this->skeletonDir, 'Extension.php', $dir.'/DependencyInjection/'.$basename.'Extension.php', $parameters); + $this->renderFile($this->skeletonDir, 'Configuration.php', $dir.'/DependencyInjection/Configuration.php', $parameters); + $this->renderFile($this->skeletonDir, 'DefaultController.php', $dir.'/Controller/DefaultController.php', $parameters); + $this->renderFile($this->skeletonDir, 'DefaultControllerTest.php', $dir.'/Tests/Controller/DefaultControllerTest.php', $parameters); + $this->renderFile($this->skeletonDir, 'index.html.twig', $dir.'/Resources/views/Default/index.html.twig', $parameters); + + if ('xml' === $format || 'annotation' === $format) { + $this->renderFile($this->skeletonDir, 'services.xml', $dir.'/Resources/config/services.xml', $parameters); + } else { + $this->renderFile($this->skeletonDir, 'services.'.$format, $dir.'/Resources/config/services.'.$format, $parameters); + } + + if ('annotation' != $format) { + $this->renderFile($this->skeletonDir, 'routing.'.$format, $dir.'/Resources/config/routing.'.$format, $parameters); + } + + if ($structure) { + $this->filesystem->mkdir($dir.'/Resources/doc'); + $this->filesystem->touch($dir.'/Resources/doc/index.rst'); + $this->filesystem->mkdir($dir.'/Resources/translations'); + $this->filesystem->copy($this->skeletonDir.'/messages.fr.xlf', $dir.'/Resources/translations/messages.fr.xlf'); + $this->filesystem->mkdir($dir.'/Resources/public/css'); + $this->filesystem->mkdir($dir.'/Resources/public/images'); + $this->filesystem->mkdir($dir.'/Resources/public/js'); + } + } +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Generator/DoctrineCrudGenerator.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Generator/DoctrineCrudGenerator.php new file mode 100644 index 0000000..72eb9aa --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Generator/DoctrineCrudGenerator.php @@ -0,0 +1,290 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sensio\Bundle\GeneratorBundle\Generator; + +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\HttpKernel\Bundle\BundleInterface; +use Doctrine\ORM\Mapping\ClassMetadataInfo; + +/** + * Generates a CRUD controller. + * + * @author Fabien Potencier + */ +class DoctrineCrudGenerator extends Generator +{ + protected $filesystem; + protected $skeletonDir; + protected $routePrefix; + protected $routeNamePrefix; + protected $bundle; + protected $entity; + protected $metadata; + protected $format; + protected $actions; + + /** + * Constructor. + * + * @param Filesystem $filesystem A Filesystem instance + * @param string $skeletonDir Path to the skeleton directory + */ + public function __construct(Filesystem $filesystem, $skeletonDir) + { + $this->filesystem = $filesystem; + $this->skeletonDir = $skeletonDir; + } + + /** + * Generate the CRUD controller. + * + * @param BundleInterface $bundle A bundle object + * @param string $entity The entity relative class name + * @param ClassMetadataInfo $metadata The entity class metadata + * @param string $format The configuration format (xml, yaml, annotation) + * @param string $routePrefix The route name prefix + * @param array $needWriteActions Wether or not to generate write actions + * + * @throws \RuntimeException + */ + public function generate(BundleInterface $bundle, $entity, ClassMetadataInfo $metadata, $format, $routePrefix, $needWriteActions) + { + $this->routePrefix = $routePrefix; + $this->routeNamePrefix = str_replace('/', '_', $routePrefix); + $this->actions = $needWriteActions ? array('index', 'show', 'new', 'edit', 'delete') : array('index', 'show'); + + if (count($metadata->identifier) > 1) { + throw new \RuntimeException('The CRUD generator does not support entity classes with multiple primary keys.'); + } + + if (!in_array('id', $metadata->identifier)) { + throw new \RuntimeException('The CRUD generator expects the entity object has a primary key field named "id" with a getId() method.'); + } + + $this->entity = $entity; + $this->bundle = $bundle; + $this->metadata = $metadata; + $this->setFormat($format); + + $this->generateControllerClass(); + + $dir = sprintf('%s/Resources/views/%s', $this->bundle->getPath(), str_replace('\\', '/', $this->entity)); + + if (!file_exists($dir)) { + $this->filesystem->mkdir($dir, 0777); + } + + $this->generateIndexView($dir); + + if (in_array('show', $this->actions)) { + $this->generateShowView($dir); + } + + if (in_array('new', $this->actions)) { + $this->generateNewView($dir); + } + + if (in_array('edit', $this->actions)) { + $this->generateEditView($dir); + } + + $this->generateTestClass(); + $this->generateConfiguration(); + } + + /** + * Sets the configuration format. + * + * @param string $format The configuration format + */ + private function setFormat($format) + { + switch ($format) { + case 'yml': + case 'xml': + case 'php': + case 'annotation': + $this->format = $format; + break; + default: + $this->format = 'yml'; + break; + } + } + + /** + * Generates the routing configuration. + * + */ + private function generateConfiguration() + { + if (!in_array($this->format, array('yml', 'xml', 'php'))) { + return; + } + + $target = sprintf( + '%s/Resources/config/routing/%s.%s', + $this->bundle->getPath(), + strtolower(str_replace('\\', '_', $this->entity)), + $this->format + ); + + $this->renderFile($this->skeletonDir, 'config/routing.'.$this->format, $target, array( + 'actions' => $this->actions, + 'route_prefix' => $this->routePrefix, + 'route_name_prefix' => $this->routeNamePrefix, + 'bundle' => $this->bundle->getName(), + 'entity' => $this->entity, + )); + } + + /** + * Generates the controller class only. + * + */ + private function generateControllerClass() + { + $dir = $this->bundle->getPath(); + + $parts = explode('\\', $this->entity); + $entityClass = array_pop($parts); + $entityNamespace = implode('\\', $parts); + + $target = sprintf( + '%s/Controller/%s/%sController.php', + $dir, + str_replace('\\', '/', $entityNamespace), + $entityClass + ); + + if (file_exists($target)) { + throw new \RuntimeException('Unable to generate the controller as it already exists.'); + } + + $this->renderFile($this->skeletonDir, 'controller.php', $target, array( + 'actions' => $this->actions, + 'route_prefix' => $this->routePrefix, + 'route_name_prefix' => $this->routeNamePrefix, + 'dir' => $this->skeletonDir, + 'bundle' => $this->bundle->getName(), + 'entity' => $this->entity, + 'entity_class' => $entityClass, + 'namespace' => $this->bundle->getNamespace(), + 'entity_namespace' => $entityNamespace, + 'format' => $this->format, + )); + } + + /** + * Generates the functional test class only. + * + */ + private function generateTestClass() + { + $parts = explode('\\', $this->entity); + $entityClass = array_pop($parts); + $entityNamespace = implode('\\', $parts); + + $dir = $this->bundle->getPath() .'/Tests/Controller'; + $target = $dir .'/'. str_replace('\\', '/', $entityNamespace).'/'. $entityClass .'ControllerTest.php'; + + $this->renderFile($this->skeletonDir, 'tests/test.php', $target, array( + 'route_prefix' => $this->routePrefix, + 'route_name_prefix' => $this->routeNamePrefix, + 'entity' => $this->entity, + 'entity_class' => $entityClass, + 'namespace' => $this->bundle->getNamespace(), + 'entity_namespace' => $entityNamespace, + 'actions' => $this->actions, + 'dir' => $this->skeletonDir, + )); + } + + /** + * Generates the index.html.twig template in the final bundle. + * + * @param string $dir The path to the folder that hosts templates in the bundle + */ + private function generateIndexView($dir) + { + $this->renderFile($this->skeletonDir, 'views/index.html.twig', $dir.'/index.html.twig', array( + 'dir' => $this->skeletonDir, + 'entity' => $this->entity, + 'fields' => $this->metadata->fieldMappings, + 'actions' => $this->actions, + 'record_actions' => $this->getRecordActions(), + 'route_prefix' => $this->routePrefix, + 'route_name_prefix' => $this->routeNamePrefix, + )); + } + + /** + * Generates the show.html.twig template in the final bundle. + * + * @param string $dir The path to the folder that hosts templates in the bundle + */ + private function generateShowView($dir) + { + $this->renderFile($this->skeletonDir, 'views/show.html.twig', $dir.'/show.html.twig', array( + 'dir' => $this->skeletonDir, + 'entity' => $this->entity, + 'fields' => $this->metadata->fieldMappings, + 'actions' => $this->actions, + 'route_prefix' => $this->routePrefix, + 'route_name_prefix' => $this->routeNamePrefix, + )); + } + + /** + * Generates the new.html.twig template in the final bundle. + * + * @param string $dir The path to the folder that hosts templates in the bundle + */ + private function generateNewView($dir) + { + $this->renderFile($this->skeletonDir, 'views/new.html.twig', $dir.'/new.html.twig', array( + 'dir' => $this->skeletonDir, + 'route_prefix' => $this->routePrefix, + 'route_name_prefix' => $this->routeNamePrefix, + 'entity' => $this->entity, + 'actions' => $this->actions, + )); + } + + /** + * Generates the edit.html.twig template in the final bundle. + * + * @param string $dir The path to the folder that hosts templates in the bundle + */ + private function generateEditView($dir) + { + $this->renderFile($this->skeletonDir, 'views/edit.html.twig', $dir.'/edit.html.twig', array( + 'dir' => $this->skeletonDir, + 'route_prefix' => $this->routePrefix, + 'route_name_prefix' => $this->routeNamePrefix, + 'entity' => $this->entity, + 'actions' => $this->actions, + )); + } + + /** + * Returns an array of record actions to generate (edit, show). + * + * @return array + */ + private function getRecordActions() + { + return array_filter($this->actions, function($item) { + return in_array($item, array('show', 'edit')); + }); + } +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Generator/DoctrineEntityGenerator.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Generator/DoctrineEntityGenerator.php new file mode 100644 index 0000000..cc050eb --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Generator/DoctrineEntityGenerator.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 Sensio\Bundle\GeneratorBundle\Generator; + +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\HttpKernel\Bundle\BundleInterface; +use Symfony\Bridge\Doctrine\RegistryInterface; +use Doctrine\ORM\Mapping\ClassMetadataInfo; +use Doctrine\ORM\Tools\EntityGenerator; +use Doctrine\ORM\Tools\EntityRepositoryGenerator; +use Doctrine\ORM\Tools\Export\ClassMetadataExporter; + +/** + * Generates a form class based on a Doctrine entity. + * + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class DoctrineEntityGenerator extends Generator +{ + private $filesystem; + private $registry; + + public function __construct(Filesystem $filesystem, RegistryInterface $registry) + { + $this->filesystem = $filesystem; + $this->registry = $registry; + } + + public function generate(BundleInterface $bundle, $entity, $format, array $fields, $withRepository) + { + // configure the bundle (needed if the bundle does not contain any Entities yet) + $config = $this->registry->getEntityManager(null)->getConfiguration(); + $config->setEntityNamespaces(array_merge( + array($bundle->getName() => $bundle->getNamespace().'\\Entity'), + $config->getEntityNamespaces() + )); + + $entityClass = $this->registry->getEntityNamespace($bundle->getName()).'\\'.$entity; + $entityPath = $bundle->getPath().'/Entity/'.str_replace('\\', '/', $entity).'.php'; + if (file_exists($entityPath)) { + throw new \RuntimeException(sprintf('Entity "%s" already exists.', $entityClass)); + } + + $class = new ClassMetadataInfo($entityClass); + if ($withRepository) { + $class->customRepositoryClassName = $entityClass.'Repository'; + } + $class->mapField(array('fieldName' => 'id', 'type' => 'integer', 'id' => true)); + $class->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO); + foreach ($fields as $field) { + $class->mapField($field); + } + + $entityGenerator = $this->getEntityGenerator(); + if ('annotation' === $format) { + $entityGenerator->setGenerateAnnotations(true); + $entityCode = $entityGenerator->generateEntityClass($class); + $mappingPath = $mappingCode = false; + } else { + $cme = new ClassMetadataExporter(); + $exporter = $cme->getExporter('yml' == $format ? 'yaml' : $format); + $mappingPath = $bundle->getPath().'/Resources/config/doctrine/'.str_replace('\\', '.', $entity).'.orm.'.$format; + + if (file_exists($mappingPath)) { + throw new \RuntimeException(sprintf('Cannot generate entity when mapping "%s" already exists.', $mappingPath)); + } + + $mappingCode = $exporter->exportClassMetadata($class); + $entityGenerator->setGenerateAnnotations(false); + $entityCode = $entityGenerator->generateEntityClass($class); + } + + $this->filesystem->mkdir(dirname($entityPath)); + file_put_contents($entityPath, $entityCode); + + if ($mappingPath) { + $this->filesystem->mkdir(dirname($mappingPath)); + file_put_contents($mappingPath, $mappingCode); + } + + if ($withRepository) { + $path = $bundle->getPath().str_repeat('/..', substr_count(get_class($bundle), '\\')); + $this->getRepositoryGenerator()->writeEntityRepositoryClass($class->customRepositoryClassName, $path); + } + } + + public function isReservedKeyword($keyword) + { + return $this->registry->getConnection()->getDatabasePlatform()->getReservedKeywordsList()->isKeyword($keyword); + } + + protected function getEntityGenerator() + { + $entityGenerator = new EntityGenerator(); + $entityGenerator->setGenerateAnnotations(false); + $entityGenerator->setGenerateStubMethods(true); + $entityGenerator->setRegenerateEntityIfExists(false); + $entityGenerator->setUpdateEntityIfExists(true); + $entityGenerator->setNumSpaces(4); + $entityGenerator->setAnnotationPrefix('ORM\\'); + + return $entityGenerator; + } + + protected function getRepositoryGenerator() + { + return new EntityRepositoryGenerator(); + } +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Generator/DoctrineFormGenerator.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Generator/DoctrineFormGenerator.php new file mode 100644 index 0000000..f083ebc --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Generator/DoctrineFormGenerator.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 Sensio\Bundle\GeneratorBundle\Generator; + +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\HttpKernel\Bundle\BundleInterface; +use Doctrine\ORM\Mapping\ClassMetadataInfo; + +/** + * Generates a form class based on a Doctrine entity. + * + * @author Fabien Potencier + * @author Hugo Hamon + */ +class DoctrineFormGenerator extends Generator +{ + private $filesystem; + private $skeletonDir; + private $className; + private $classPath; + + public function __construct(Filesystem $filesystem, $skeletonDir) + { + $this->filesystem = $filesystem; + $this->skeletonDir = $skeletonDir; + } + + public function getClassName() + { + return $this->className; + } + + public function getClassPath() + { + return $this->classPath; + } + + /** + * Generates the entity form class if it does not exist. + * + * @param BundleInterface $bundle The bundle in which to create the class + * @param string $entity The entity relative class name + * @param ClassMetadataInfo $metadata The entity metadata class + */ + public function generate(BundleInterface $bundle, $entity, ClassMetadataInfo $metadata) + { + $parts = explode('\\', $entity); + $entityClass = array_pop($parts); + + $this->className = $entityClass.'Type'; + $dirPath = $bundle->getPath().'/Form'; + $this->classPath = $dirPath.'/'.str_replace('\\', '/', $entity).'Type.php'; + + if (file_exists($this->classPath)) { + throw new \RuntimeException(sprintf('Unable to generate the %s form class as it already exists under the %s file', $this->className, $this->classPath)); + } + + if (count($metadata->identifier) > 1) { + throw new \RuntimeException('The form generator does not support entity classes with multiple primary keys.'); + } + + $parts = explode('\\', $entity); + array_pop($parts); + + $this->renderFile($this->skeletonDir, 'FormType.php', $this->classPath, array( + 'dir' => $this->skeletonDir, + 'fields' => $this->getFieldsFromMetadata($metadata), + 'namespace' => $bundle->getNamespace(), + 'entity_namespace' => implode('\\', $parts), + 'entity_class' => $entityClass, + 'form_class' => $this->className, + 'form_type_name' => strtolower(str_replace('\\', '_', $bundle->getNamespace()).($parts ? '_' : '').implode('_', $parts).'_'.$this->className), + )); + } + + /** + * Returns an array of fields. Fields can be both column fields and + * association fields. + * + * @param ClassMetadataInfo $metadata + * @return array $fields + */ + private function getFieldsFromMetadata(ClassMetadataInfo $metadata) + { + $fields = (array) $metadata->fieldNames; + + // Remove the primary key field if it's not managed manually + if (!$metadata->isIdentifierNatural()) { + $fields = array_diff($fields, $metadata->identifier); + } + + foreach ($metadata->associationMappings as $fieldName => $relation) { + if ($relation['type'] !== ClassMetadataInfo::ONE_TO_MANY) { + $fields[] = $fieldName; + } + } + + return $fields; + } +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Generator/Generator.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Generator/Generator.php new file mode 100644 index 0000000..a5d9f3f --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Generator/Generator.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 Sensio\Bundle\GeneratorBundle\Generator; + +/** + * Generator is the base class for all generators. + * + * @author Fabien Potencier + */ +class Generator +{ + protected function render($skeletonDir, $template, $parameters) + { + $twig = new \Twig_Environment(new \Twig_Loader_Filesystem($skeletonDir), array( + 'debug' => true, + 'cache' => false, + 'strict_variables' => true, + 'autoescape' => false, + )); + + return $twig->render($template, $parameters); + } + + protected function renderFile($skeletonDir, $template, $target, $parameters) + { + if (!is_dir(dirname($target))) { + mkdir(dirname($target), 0777, true); + } + + return file_put_contents($target, $this->render($skeletonDir, $template, $parameters)); + } +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/LICENSE b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/LICENSE new file mode 100644 index 0000000..c60ef6c --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2011 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/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Manipulator/KernelManipulator.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Manipulator/KernelManipulator.php new file mode 100644 index 0000000..8b1bbe7 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Manipulator/KernelManipulator.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 Sensio\Bundle\GeneratorBundle\Manipulator; + +use Symfony\Component\HttpKernel\KernelInterface; + +/** + * Changes the PHP code of a Kernel. + * + * @author Fabien Potencier + */ +class KernelManipulator extends Manipulator +{ + private $kernel; + private $reflected; + + /** + * Constructor. + * + * @param KernelInterface $kernel A KernelInterface instance + */ + public function __construct(KernelInterface $kernel) + { + $this->kernel = $kernel; + $this->reflected = new \ReflectionObject($kernel); + } + + /** + * Adds a bundle at the end of the existing ones. + * + * @param string $bundle The bundle class name + * + * @return Boolean true if it worked, false otherwise + * + * @throws \RuntimeException If bundle is already defined + */ + public function addBundle($bundle) + { + if (!$this->reflected->getFilename()) { + return false; + } + + $src = file($this->reflected->getFilename()); + $method = $this->reflected->getMethod('registerBundles'); + $lines = array_slice($src, $method->getStartLine() - 1, $method->getEndLine() - $method->getStartLine() + 1); + + // Don't add same bundle twice + if (false !== strpos(implode('', $lines), $bundle)) { + throw new \RuntimeException(sprintf('Bundle "%s" is already defined in "AppKernel::registerBundles()".', $bundle)); + } + + $this->setCode(token_get_all('getStartLine()); + while ($token = $this->next()) { + // $bundles + if (T_VARIABLE !== $token[0] || '$bundles' !== $token[1]) { + continue; + } + + // = + $this->next(); + + // array + $token = $this->next(); + if (T_ARRAY !== $token[0]) { + return false; + } + + // add the bundle at the end of the array + while ($token = $this->next()) { + // look for ); + if (')' !== $this->value($token)) { + continue; + } + + if (';' !== $this->value($this->peek())) { + continue; + } + + // ; + $this->next(); + + $lines = array_merge( + array_slice($src, 0, $this->line - 2), + // Appends a separator comma to the current last position of the array + array(rtrim(rtrim($src[$this->line - 2]), ',') . ",\n"), + array(sprintf(" new %s(),\n", $bundle)), + array_slice($src, $this->line - 1) + ); + + file_put_contents($this->reflected->getFilename(), implode('', $lines)); + + return true; + } + } + } +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Manipulator/Manipulator.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Manipulator/Manipulator.php new file mode 100644 index 0000000..a97baa7 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Manipulator/Manipulator.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sensio\Bundle\GeneratorBundle\Manipulator; + + +/** + * Changes the PHP code of a Kernel. + * + * @author Fabien Potencier + */ +class Manipulator +{ + protected $tokens; + protected $line; + + /** + * Sets the code to manipulate. + * + * @param array $tokens An array of PHP tokens + * @param integer $line The start line of the code + */ + protected function setCode(array $tokens, $line = 0) + { + $this->tokens = $tokens; + $this->line = $line; + } + + /** + * Gets the next token. + * + * @param mixed A PHP token + */ + protected function next() + { + while ($token = array_shift($this->tokens)) { + $this->line += substr_count($this->value($token), "\n"); + + if (is_array($token) && in_array($token[0], array(T_WHITESPACE, T_COMMENT, T_DOC_COMMENT))) { + continue; + } + + return $token; + } + } + + /** + * Peeks the next token. + * + * @param mixed A PHP token + */ + protected function peek($nb = 1) + { + $i = 0; + $tokens = $this->tokens; + while ($token = array_shift($tokens)) { + if (is_array($token) && in_array($token[0], array(T_WHITESPACE, T_COMMENT, T_DOC_COMMENT))) { + continue; + } + + ++$i; + if ($i == $nb) { + return $token; + } + } + } + + /** + * Gets the value of a token. + * + * @param string The token value + */ + protected function value($token) + { + return is_array($token) ? $token[1] : $token; + } +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Manipulator/RoutingManipulator.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Manipulator/RoutingManipulator.php new file mode 100644 index 0000000..0026c47 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Manipulator/RoutingManipulator.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 Sensio\Bundle\GeneratorBundle\Manipulator; + +/** + * Changes the PHP code of a YAML routing file. + * + * @author Fabien Potencier + */ +class RoutingManipulator extends Manipulator +{ + private $file; + + /** + * Constructor. + * + * @param string $file The YAML routing file path + */ + public function __construct($file) + { + $this->file = $file; + } + + /** + * Adds a routing resource at the top of the existing ones. + * + * @param string $bundle + * @param string $format + * @param string $prefix + * @param string $path + * + * @return Boolean true if it worked, false otherwise + * + * @throws \RuntimeException If bundle is already imported + */ + public function addResource($bundle, $format, $prefix = '/', $path = 'routing') + { + $current = ''; + if (file_exists($this->file)) { + $current = file_get_contents($this->file); + + // Don't add same bundle twice + if (false !== strpos($current, $bundle)) { + throw new \RuntimeException(sprintf('Bundle "%s" is already imported.', $bundle)); + } + } elseif (!is_dir($dir = dirname($this->file))) { + mkdir($dir, 0777, true); + } + + $code = sprintf("%s:\n", $bundle.('/' !== $prefix ? '_'.str_replace('/', '_', substr($prefix, 1)) : '')); + if ('annotation' == $format) { + $code .= sprintf(" resource: \"@%s/Controller/\"\n type: annotation\n", $bundle); + } else { + $code .= sprintf(" resource: \"@%s/Resources/config/%s.%s\"\n", $bundle, $path, $format); + } + $code .= sprintf(" prefix: %s\n", $prefix); + $code .= "\n"; + $code .= $current; + + if (false === file_put_contents($this->file, $code)) { + return false; + } + + return true; + } +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/README.md b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/README.md new file mode 100644 index 0000000..8b033db --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/README.md @@ -0,0 +1,10 @@ +SensioGeneratorBundle +===================== + +The `SensioGeneratorBundle` extends the default Symfony2 command line +interface by providing new interactive and intuitive commands for generating +code skeletons like bundles, form classes, or CRUD controllers based on a +Doctrine 2 schema. + +More information in the official +[documentation](http://symfony.com/doc/current/bundles/SensioGeneratorBundle/index.html). diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/doc/commands/generate_bundle.rst b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/doc/commands/generate_bundle.rst new file mode 100644 index 0000000..90d04ba --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/doc/commands/generate_bundle.rst @@ -0,0 +1,68 @@ +Generating a New Bundle Skeleton +================================ + +Usage +----- + +The ``generate:bundle`` generates a new bundle structure and automatically +activates it in the application. + +By default the command is run in the interactive mode and asks questions to +determine the bundle name, location, configuration format and default +structure: + +.. code-block:: bash + + php app/console generate:bundle + +To deactivate the interactive mode, use the `--no-interaction` option but don't +forget to pass all needed options: + +.. code-block:: bash + + php app/console generate:bundle --namespace=Acme/Bundle/BlogBundle --no-interaction + +Available Options +----------------- + +* ``--namespace``: The namespace of the bundle to create. The namespace should + begin with a "vendor" name like your company name, your project name, or + your client name, followed by one or more optional category sub-namespaces, + and it should end with the bundle name itself (which must have Bundle as a + suffix): + + .. code-block:: bash + + php app/console generate:bundle --namespace=Acme/Bundle/BlogBundle + +* ``--bundle-name``: The optional bundle name. It must be a string ending with + the ``Bundle`` suffix: + + .. code-block:: bash + + php app/console generate:bundle --bundle-name=AcmeBlogBundle + +* ``--dir``: The directory in which to store the bundle. By convention, the + command detects and uses the applications's ``src/`` folder: + + .. code-block:: bash + + php app/console generate:bundle --dir=/var/www/myproject/src + +* ``--format``: (**annotation**) [values: yml, xml, php or annotation] + Determine the format to use for the generated configuration files like + routing. By default, the command uses the ``annotation`` format. Choosing + the ``annotation`` format expects the ``SensioFrameworkExtraBundle`` is + already installed: + + .. code-block:: bash + + php app/console generate:bundle --format=annotation + +* ``--structure``: (**no**) [values: yes|no] Whether or not to generate a + complete default directory structure including empty public folders for + documentation, web assets and translations dictionaries: + + .. code-block:: bash + + php app/console generate:bundle --structure=yes diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/doc/commands/generate_doctrine_crud.rst b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/doc/commands/generate_doctrine_crud.rst new file mode 100644 index 0000000..07acc08 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/doc/commands/generate_doctrine_crud.rst @@ -0,0 +1,65 @@ +Generating a CRUD Controller Based on a Doctrine Entity +======================================================= + +Usage +----- + +The ``generate:doctrine:crud`` generates a basic controller for a given entity +located in a given bundle. This controller allows to perform the five basic +operations on a model. + +* Listing all records, +* Showing one given record identified by its primary key, +* Creating a new record, +* Editing an existing record, +* Deleting an existing record. + +By default the command is run in the interactive mode and asks questions to +determine the entity name, the route prefix or whether or not to generate write +actions: + +.. code-block:: bash + + php app/console generate:doctrine:crud + +To deactivate the interactive mode, use the `--no-interaction` option but don't +forget to pass all needed options: + +.. code-block:: bash + + php app/console generate:doctrine:crud --entity=AcmeBlogBundle:Post --format=annotation --with-write --no-interaction + +Available Options +----------------- + +* ``--entity``: The entity name given as a shortcut notation containing the + bundle name in which the entity is located and the name of the entity. For + example: ``AcmeBlogBundle:Post``: + + .. code-block:: bash + + php app/console generate:doctrine:crud --entity=AcmeBlogBundle:Post + +* ``--route-prefix``: The prefix to use for each route that identifies an + action: + + .. code-block:: bash + + php app/console generate:doctrine:crud --route-prefix=acme_post + +* ``--with-write``: (**no**) [values: yes|no] Whether or not to generate the + `new`, `create`, `edit`, `update` and `delete` actions: + + .. code-block:: bash + + php app/console generate:doctrine:crud --with-write + +* ``--format``: (**annotation**) [values: yml, xml, php or annotation] + Determine the format to use for the generated configuration files like + routing. By default, the command uses the ``annotation`` format. Choosing + the ``annotation`` format expects the ``SensioFrameworkExtraBundle`` is + already installed: + + .. code-block:: bash + + php app/console generate:doctrine:crud --format=annotation diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/doc/commands/generate_doctrine_entity.rst b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/doc/commands/generate_doctrine_entity.rst new file mode 100644 index 0000000..7c362bd --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/doc/commands/generate_doctrine_entity.rst @@ -0,0 +1,55 @@ +Generating a New Doctrine Entity Stub +===================================== + +Usage +----- + +The ``generate:doctrine:entity`` command generates a new Doctrine entity stub +including the mapping definition and the class properties, getters and setters. + +By default the command is run in the interactive mode and asks questions to +determine the bundle name, location, configuration format and default +structure: + +.. code-block:: bash + + php app/console generate:doctrine:entity + +The command can be run in a non interactive mode by using the +``--non-interaction`` option without forgetting all needed options: + +.. code-block:: bash + + php app/console generate:doctrine:entity --non-interaction --entity=AcmeBlogBundle:Post --fields="title:string(100) body:text" --format=xml + +Available Options +----------------- + +* ``--entity``: The entity name given as a shortcut notation containing the + bundle name in which the entity is located and the name of the entity. For + example: ``AcmeBlogBundle:Post``: + + .. code-block:: bash + + php app/console generate:doctrine:entity --entity=AcmeBlogBundle:Post + +* ``--fields``: The list of fields to generate in the entity class: + + .. code-block:: bash + + php app/console generate:doctrine:entity --fields="title:string(100) body:text" + +* ``--format``: (**annotation**) [values: yml, xml, php or annotation] This + option determines the format to use for the generated configuration files + like routing. By default, the command uses the ``annotation`` format: + + .. code-block:: bash + + php app/console generate:doctrine:entity --format=annotation + +* ``--with-repository``: This option tells whether or not to generate the + related Doctrine `EntityRepository` class: + + .. code-block:: bash + + php app/console generate:doctrine:entity --with-repository diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/doc/commands/generate_doctrine_form.rst b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/doc/commands/generate_doctrine_form.rst new file mode 100644 index 0000000..6bc9a60 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/doc/commands/generate_doctrine_form.rst @@ -0,0 +1,23 @@ +Generating a New Form Type Class Based on a Doctrine Entity +=========================================================== + +Usage +----- + +The ``generate:doctrine:form`` generates a basic form type class by using the +metadata mapping of a given entity class: + +.. code-block:: bash + + php app/console generate:doctrine:form AcmeBlogBundle:Post + +Required Arguments +------------------ + +* ``entity``: The entity name given as a shortcut notation containing the + bundle name in which the entity is located and the name of the entity. For + example: ``AcmeBlogBundle:Post``: + + .. code-block:: bash + + php app/console generate:doctrine:form AcmeBlogBundle:Post diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/doc/index.rst b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/doc/index.rst new file mode 100644 index 0000000..a3ae3bc --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/doc/index.rst @@ -0,0 +1,42 @@ +SensioGeneratorBundle +========================== + +The ``SensioGeneratorBundle`` extends the default Symfony2 command line +interface by providing new interactive and intuitive commands for generating +code skeletons like bundles, form classes or CRUD controllers based on a +Doctrine 2 schema. + +Installation +------------ + +`Download`_ the bundle and put it under the ``Sensio\\Bundle\\`` namespace. +Then, like for any other bundle, include it in your Kernel class:: + + public function registerBundles() + { + $bundles = array( + ... + + new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle(), + ); + + ... + } + +List of Available Commands +-------------------------- + +The ``SensioGeneratorBundle`` comes with four new commands that can be run in +interactive mode or not. The interactive mode asks you some questions to +configure the command parameters to generate the definitive code. The list of +new commands are listed below: + +.. toctree:: + :maxdepth: 1 + + commands/generate_bundle + commands/generate_doctrine_crud + commands/generate_doctrine_entity + commands/generate_doctrine_form + +.. _Download: http://github.com/sensio/SensioGeneratorBundle \ No newline at end of file diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/Bundle.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/Bundle.php new file mode 100644 index 0000000..7721df5 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/Bundle.php @@ -0,0 +1,9 @@ +root('{{ extension_alias }}'); + + // Here you should define the parameters that are allowed to + // configure your bundle. See the documentation linked above for + // more information on that topic. + + return $treeBuilder; + } +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/DefaultController.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/DefaultController.php new file mode 100644 index 0000000..2d98904 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/DefaultController.php @@ -0,0 +1,28 @@ +render('{{ bundle }}:Default:index.html.twig', array('name' => $name)); + {%- else -%} + return array('name' => $name); + {%- endif %} + + } +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/DefaultControllerTest.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/DefaultControllerTest.php new file mode 100644 index 0000000..9c76faa --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/DefaultControllerTest.php @@ -0,0 +1,17 @@ +request('GET', '/hello/Fabien'); + + $this->assertTrue($crawler->filter('html:contains("Hello Fabien")')->count() > 0); + } +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/Extension.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/Extension.php new file mode 100644 index 0000000..e493003 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/Extension.php @@ -0,0 +1,37 @@ +processConfiguration($configuration, $configs); + + {% if format == 'yml' -%} + $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('services.yml'); + {%- elseif format == 'xml' or format == 'annotation' -%} + $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('services.xml'); + {%- elseif format == 'php' -%} + $loader = new Loader\PhpFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('services.php'); + {%- endif %} + + } +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/index.html.twig b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/index.html.twig new file mode 100644 index 0000000..e64fdb0 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/index.html.twig @@ -0,0 +1 @@ +Hello {% raw %}{{ name }}{% endraw %}! diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/messages.fr.xlf b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/messages.fr.xlf new file mode 100644 index 0000000..fd59e6c --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/messages.fr.xlf @@ -0,0 +1,11 @@ + + + + + + Symfony2 is great + J'aime Symfony2 + + + + diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/routing.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/routing.php new file mode 100644 index 0000000..67ae142 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/routing.php @@ -0,0 +1,11 @@ +add('{{ bundle }}_homepage', new Route('/hello/{name}', array( + '_controller' => '{{ bundle }}:Default:index', +))); + +return $collection; diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/routing.xml b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/routing.xml new file mode 100644 index 0000000..b3164bf --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/routing.xml @@ -0,0 +1,10 @@ + + + + + + {{ bundle }}:Default:index + + diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/routing.yml b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/routing.yml new file mode 100644 index 0000000..c418ad9 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/routing.yml @@ -0,0 +1,3 @@ +{{ bundle }}_homepage: + pattern: /hello/{name} + defaults: { _controller: {{ bundle }}:Default:index } diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/services.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/services.php new file mode 100644 index 0000000..71d6080 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/services.php @@ -0,0 +1,21 @@ +setDefinition( + '{{ extension_alias }}.example', + new Definition( + '{{ namespace }}\Example', + array( + new Reference('service_id'), + "plain_value", + new Parameter('parameter_name'), + ) + ) +); + +*/ \ No newline at end of file diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/services.xml b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/services.xml new file mode 100644 index 0000000..5f2c82f --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/services.xml @@ -0,0 +1,20 @@ + + + + + + diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/services.yml b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/services.yml new file mode 100644 index 0000000..411a0f3 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/bundle/services.yml @@ -0,0 +1,7 @@ +parameters: +# {{ extension_alias }}.example.class: {{ namespace }}\Example + +services: +# {{ extension_alias }}.example: +# class: %{{ extension_alias }}.example.class% +# arguments: [@service_id, "plain_value", %parameter%] diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/create.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/create.php new file mode 100644 index 0000000..455e11f --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/create.php @@ -0,0 +1,42 @@ + + /** + * Creates a new {{ entity }} entity. + * +{% if 'annotation' == format %} + * @Route("/create", name="{{ route_name_prefix }}_create") + * @Method("post") + * @Template("{{ bundle }}:{{ entity }}:new.html.twig") +{% endif %} + */ + public function createAction() + { + $entity = new {{ entity_class }}(); + $request = $this->getRequest(); + $form = $this->createForm(new {{ entity_class }}Type(), $entity); + $form->bindRequest($request); + + if ($form->isValid()) { + $em = $this->getDoctrine()->getManager(); + $em->persist($entity); + $em->flush(); + + {% if 'show' in actions -%} + return $this->redirect($this->generateUrl('{{ route_name_prefix }}_show', array('id' => $entity->getId()))); + {%- else -%} + return $this->redirect($this->generateUrl('{{ route_name_prefix }}')); + {%- endif %} + + } + +{% if 'annotation' == format %} + return array( + 'entity' => $entity, + 'form' => $form->createView(), + ); +{% else %} + return $this->render('{{ bundle }}:{{ entity|replace({'\\': '/'}) }}:new.html.twig', array( + 'entity' => $entity, + 'form' => $form->createView(), + )); +{% endif %} + } diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/delete.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/delete.php new file mode 100644 index 0000000..1d01735 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/delete.php @@ -0,0 +1,38 @@ + + /** + * Deletes a {{ entity }} entity. + * +{% if 'annotation' == format %} + * @Route("/{id}/delete", name="{{ route_name_prefix }}_delete") + * @Method("post") +{% endif %} + */ + public function deleteAction($id) + { + $form = $this->createDeleteForm($id); + $request = $this->getRequest(); + + $form->bindRequest($request); + + if ($form->isValid()) { + $em = $this->getDoctrine()->getManager(); + $entity = $em->getRepository('{{ bundle }}:{{ entity }}')->find($id); + + if (!$entity) { + throw $this->createNotFoundException('Unable to find {{ entity }} entity.'); + } + + $em->remove($entity); + $em->flush(); + } + + return $this->redirect($this->generateUrl('{{ route_name_prefix }}')); + } + + private function createDeleteForm($id) + { + return $this->createFormBuilder(array('id' => $id)) + ->add('id', 'hidden') + ->getForm() + ; + } \ No newline at end of file diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/edit.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/edit.php new file mode 100644 index 0000000..2371bed --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/edit.php @@ -0,0 +1,36 @@ + + /** + * Displays a form to edit an existing {{ entity }} entity. + * +{% if 'annotation' == format %} + * @Route("/{id}/edit", name="{{ route_name_prefix }}_edit") + * @Template() +{% endif %} + */ + public function editAction($id) + { + $em = $this->getDoctrine()->getManager(); + + $entity = $em->getRepository('{{ bundle }}:{{ entity }}')->find($id); + + if (!$entity) { + throw $this->createNotFoundException('Unable to find {{ entity }} entity.'); + } + + $editForm = $this->createForm(new {{ entity_class }}Type(), $entity); + $deleteForm = $this->createDeleteForm($id); + +{% if 'annotation' == format %} + return array( + 'entity' => $entity, + 'edit_form' => $editForm->createView(), + 'delete_form' => $deleteForm->createView(), + ); +{% else %} + return $this->render('{{ bundle }}:{{ entity|replace({'\\': '/'}) }}:edit.html.twig', array( + 'entity' => $entity, + 'edit_form' => $editForm->createView(), + 'delete_form' => $deleteForm->createView(), + )); +{% endif %} + } diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/index.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/index.php new file mode 100644 index 0000000..6da9ec0 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/index.php @@ -0,0 +1,25 @@ + + /** + * Lists all {{ entity }} entities. + * +{% if 'annotation' == format %} + * @Route("/", name="{{ route_name_prefix }}") + * @Template() +{% endif %} + */ + public function indexAction() + { + $em = $this->getDoctrine()->getManager(); + + $entities = $em->getRepository('{{ bundle }}:{{ entity }}')->findAll(); + +{% if 'annotation' == format %} + return array( + 'entities' => $entities, + ); +{% else %} + return $this->render('{{ bundle }}:{{ entity|replace({'\\': '/'}) }}:index.html.twig', array( + 'entities' => $entities, + )); +{% endif %} + } diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/new.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/new.php new file mode 100644 index 0000000..b79c311 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/new.php @@ -0,0 +1,26 @@ + + /** + * Displays a form to create a new {{ entity }} entity. + * +{% if 'annotation' == format %} + * @Route("/new", name="{{ route_name_prefix }}_new") + * @Template() +{% endif %} + */ + public function newAction() + { + $entity = new {{ entity_class }}(); + $form = $this->createForm(new {{ entity_class }}Type(), $entity); + +{% if 'annotation' == format %} + return array( + 'entity' => $entity, + 'form' => $form->createView(), + ); +{% else %} + return $this->render('{{ bundle }}:{{ entity|replace({'\\': '/'}) }}:new.html.twig', array( + 'entity' => $entity, + 'form' => $form->createView(), + )); +{% endif %} + } diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/show.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/show.php new file mode 100644 index 0000000..abe5000 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/show.php @@ -0,0 +1,39 @@ + + /** + * Finds and displays a {{ entity }} entity. + * +{% if 'annotation' == format %} + * @Route("/{id}/show", name="{{ route_name_prefix }}_show") + * @Template() +{% endif %} + */ + public function showAction($id) + { + $em = $this->getDoctrine()->getManager(); + + $entity = $em->getRepository('{{ bundle }}:{{ entity }}')->find($id); + + if (!$entity) { + throw $this->createNotFoundException('Unable to find {{ entity }} entity.'); + } +{% if 'delete' in actions %} + + $deleteForm = $this->createDeleteForm($id); +{% endif %} + +{% if 'annotation' == format %} + return array( + 'entity' => $entity, +{% if 'delete' in actions %} + 'delete_form' => $deleteForm->createView(), +{% endif %} + ); +{% else %} + return $this->render('{{ bundle }}:{{ entity|replace({'\\': '/'}) }}:show.html.twig', array( + 'entity' => $entity, +{% if 'delete' in actions %} + 'delete_form' => $deleteForm->createView(), +{%- endif %} + )); +{% endif %} + } diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/update.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/update.php new file mode 100644 index 0000000..1b2a6a2 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/actions/update.php @@ -0,0 +1,48 @@ + + /** + * Edits an existing {{ entity }} entity. + * +{% if 'annotation' == format %} + * @Route("/{id}/update", name="{{ route_name_prefix }}_update") + * @Method("post") + * @Template("{{ bundle }}:{{ entity }}:edit.html.twig") +{% endif %} + */ + public function updateAction($id) + { + $em = $this->getDoctrine()->getManager(); + + $entity = $em->getRepository('{{ bundle }}:{{ entity }}')->find($id); + + if (!$entity) { + throw $this->createNotFoundException('Unable to find {{ entity }} entity.'); + } + + $editForm = $this->createForm(new {{ entity_class }}Type(), $entity); + $deleteForm = $this->createDeleteForm($id); + + $request = $this->getRequest(); + + $editForm->bindRequest($request); + + if ($editForm->isValid()) { + $em->persist($entity); + $em->flush(); + + return $this->redirect($this->generateUrl('{{ route_name_prefix }}_edit', array('id' => $id))); + } + +{% if 'annotation' == format %} + return array( + 'entity' => $entity, + 'edit_form' => $editForm->createView(), + 'delete_form' => $deleteForm->createView(), + ); +{% else %} + return $this->render('{{ bundle }}:{{ entity|replace({'\\': '/'}) }}:edit.html.twig', array( + 'entity' => $entity, + 'edit_form' => $editForm->createView(), + 'delete_form' => $deleteForm->createView(), + )); +{% endif %} + } diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/config/routing.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/config/routing.php new file mode 100644 index 0000000..a47d00d --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/config/routing.php @@ -0,0 +1,52 @@ +add('{{ route_name_prefix }}', new Route('/', array( + '_controller' => '{{ bundle }}:{{ entity }}:index', +))); +{% endif %} + +{% if 'show' in actions %} +$collection->add('{{ route_name_prefix }}_show', new Route('/{id}/show', array( + '_controller' => '{{ bundle }}:{{ entity }}:show', +))); +{% endif %} + +{% if 'new' in actions %} +$collection->add('{{ route_name_prefix }}_new', new Route('/new', array( + '_controller' => '{{ bundle }}:{{ entity }}:new', +))); + +$collection->add('{{ route_name_prefix }}_create', new Route( + '/create', + array('_controller' => '{{ bundle }}:{{ entity }}:create'), + array('_method' => 'post') +)); +{% endif %} + +{% if 'edit' in actions %} +$collection->add('{{ route_name_prefix }}_edit', new Route('/{id}/edit', array( + '_controller' => '{{ bundle }}:{{ entity }}:edit', +))); + +$collection->add('{{ route_name_prefix }}_update', new Route( + '/{id}/update', + array('_controller' => '{{ bundle }}:{{ entity }}:update'), + array('_method' => 'post') +)); +{% endif %} + +{% if 'delete' in actions %} +$collection->add('{{ route_name_prefix }}_delete', new Route( + '/{id}/delete', + array('_controller' => '{{ bundle }}:{{ entity }}:delete'), + array('_method' => 'post') +)); +{% endif %} + +return $collection; diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/config/routing.xml b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/config/routing.xml new file mode 100644 index 0000000..50fd85e --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/config/routing.xml @@ -0,0 +1,44 @@ + + + + + + {{ bundle }}:{{ entity }}:index + + + + {{ bundle }}:{{ entity }}:show + + +{% if 'new' in actions %} + + {{ bundle }}:{{ entity }}:new + + + + {{ bundle }}:{{ entity }}:create + post + +{% endif %} + +{% if 'edit' in actions %} + + {{ bundle }}:{{ entity }}:edit + + + + {{ bundle }}:{{ entity }}:update + post + +{% endif %} + +{% if 'delete' in actions %} + + {{ bundle }}:{{ entity }}:delete + post + +{% endif %} + + diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/config/routing.yml b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/config/routing.yml new file mode 100644 index 0000000..a992678 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/config/routing.yml @@ -0,0 +1,40 @@ +{% if 'index' in actions %} +{{ route_name_prefix }}: + pattern: / + defaults: { _controller: "{{ bundle }}:{{ entity }}:index" } +{% endif %} + +{% if 'show' in actions %} +{{ route_name_prefix }}_show: + pattern: /{id}/show + defaults: { _controller: "{{ bundle }}:{{ entity }}:show" } +{% endif %} + +{% if 'new' in actions %} +{{ route_name_prefix }}_new: + pattern: /new + defaults: { _controller: "{{ bundle }}:{{ entity }}:new" } + +{{ route_name_prefix }}_create: + pattern: /create + defaults: { _controller: "{{ bundle }}:{{ entity }}:create" } + requirements: { _method: post } +{% endif %} + +{% if 'edit' in actions %} +{{ route_name_prefix }}_edit: + pattern: /{id}/edit + defaults: { _controller: "{{ bundle }}:{{ entity }}:edit" } + +{{ route_name_prefix }}_update: + pattern: /{id}/update + defaults: { _controller: "{{ bundle }}:{{ entity }}:update" } + requirements: { _method: post } +{% endif %} + +{% if 'delete' in actions %} +{{ route_name_prefix }}_delete: + pattern: /{id}/delete + defaults: { _controller: "{{ bundle }}:{{ entity }}:delete" } + requirements: { _method: post } +{% endif %} \ No newline at end of file diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/controller.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/controller.php new file mode 100644 index 0000000..e58856d --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/controller.php @@ -0,0 +1,49 @@ +request('GET', '/{{ route_prefix }}/'); + $this->assertTrue(200 === $client->getResponse()->getStatusCode()); + $crawler = $client->click($crawler->selectLink('Create a new entry')->link()); + + // Fill in the form and submit it + $form = $crawler->selectButton('Create')->form(array( + '{{ entity_class|lower }}[field_name]' => 'Test', + // ... other fields to fill + )); + + $client->submit($form); + $crawler = $client->followRedirect(); + + // Check data in the show view + $this->assertTrue($crawler->filter('td:contains("Test")')->count() > 0); + + // Edit the entity + $crawler = $client->click($crawler->selectLink('Edit')->link()); + + $form = $crawler->selectButton('Edit')->form(array( + '{{ entity_class|lower }}[field_name]' => 'Foo', + // ... other fields to fill + )); + + $client->submit($form); + $crawler = $client->followRedirect(); + + // Check the element contains an attribute with value equals "Foo" + $this->assertTrue($crawler->filter('[value="Foo"]')->count() > 0); + + // Delete the entity + $client->submit($crawler->selectButton('Delete')->form()); + $crawler = $client->followRedirect(); + + // Check the entity has been delete on the list + $this->assertNotRegExp('/Foo/', $client->getResponse()->getContent()); + } \ No newline at end of file diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/tests/others/short_scenario.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/tests/others/short_scenario.php new file mode 100644 index 0000000..09866f0 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/tests/others/short_scenario.php @@ -0,0 +1,14 @@ + + public function testCompleteScenario() + { + // Create a new client to browse the application + $client = static::createClient(); + + // Go to the list view + $crawler = $client->request('GET', '/{{ route_prefix }}/'); + $this->assertTrue(200 === $client->getResponse()->getStatusCode()); + + // Go to the show view + $crawler = $client->click($crawler->selectLink('show')->link()); + $this->assertTrue(200 === $client->getResponse()->getStatusCode()); + } \ No newline at end of file diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/tests/test.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/tests/test.php new file mode 100644 index 0000000..afb382f --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/tests/test.php @@ -0,0 +1,18 @@ +{{ entity }} edit + +
    + {{ "{{ form_widget(edit_form) }}" }} +

    + +

    + + +{% set hide_edit, hide_delete = true, false %} +{% include 'views/others/record_actions.html.twig' %} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/views/index.html.twig b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/views/index.html.twig new file mode 100644 index 0000000..882984e --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/views/index.html.twig @@ -0,0 +1,56 @@ +

    {{ entity }} list

    + +
    + + + {%- for field, metadata in fields %} + + + + {%- endfor %} + + + + + + {{ '{% for entity in entities %}' }} + + + {%- for field, metadata in fields %} + {%- if loop.first and ('show' in actions) %} + + + + {%- elseif metadata.type in ['date', 'datetime'] %} + + + + {%- else %} + + + + {%- endif %} + + {%- if loop.last %} + + + + {%- endif %} + {%- endfor %} + + + {{ '{% endfor %}' }} + +
    {{ field|capitalize }}Actions
    {{ '{{ entity.'~ field|replace({'_': ''}) ~' }}' }}{{ '{% if entity.'~ field|replace({'_': ''}) ~' %}{{ entity.'~ field|replace({'_': ''}) ~'|date(\'Y-m-d H:i:s\') }}{% endif %}' }}{{ '{{ entity.'~ field|replace({'_': ''}) ~' }}' }} + {%- include "views/others/actions.html.twig" %} +
    + +{% if 'new' in actions %} + +{% endif %} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/views/new.html.twig b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/views/new.html.twig new file mode 100644 index 0000000..06422f6 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/views/new.html.twig @@ -0,0 +1,11 @@ +

    {{ entity }} creation

    + +
    + {{ "{{ form_widget(form) }}" }} +

    + +

    +
    + +{% set hide_edit, hide_delete = true, true %} +{% include 'views/others/record_actions.html.twig' %} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/views/others/actions.html.twig b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/views/others/actions.html.twig new file mode 100644 index 0000000..5137ff2 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/views/others/actions.html.twig @@ -0,0 +1,12 @@ + +
      + + {%- for action in record_actions %} + +
    • + {{ action }} +
    • + + {%- endfor %} + +
    diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/views/others/record_actions.html.twig b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/views/others/record_actions.html.twig new file mode 100644 index 0000000..13c2673 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/views/others/record_actions.html.twig @@ -0,0 +1,22 @@ +
      +
    • + + Back to the list + +
    • +{% if ('edit' in actions) and (not hide_edit) %} +
    • + + Edit + +
    • +{% endif %} +{% if ('delete' in actions) and (not hide_delete) %} +
    • +
      + {{ '{{ form_widget(delete_form) }}' }} + +
      +
    • +{% endif %} +
    diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/views/show.html.twig b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/views/show.html.twig new file mode 100644 index 0000000..2badbd0 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/crud/views/show.html.twig @@ -0,0 +1,28 @@ +

    {{ entity }}

    + + + + {%- for field, metadata in fields %} + + + + + {%- if metadata.type in ['date', 'datetime'] %} + + + + {%- else %} + + + + {%- endif %} + + + + {%- endfor %} + + +
    {{ field|capitalize }}{{ '{{ entity.'~ field|replace({'_': ''}) ~'|date(\'Y-m-d H:i:s\') }}' }}{{ '{{ entity.'~ field|replace({'_': ''}) ~' }}' }}
    + +{% set hide_edit, hide_delete = false, false %} +{% include 'views/others/record_actions.html.twig' %} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/form/FormType.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/form/FormType.php new file mode 100644 index 0000000..60154ee --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/form/FormType.php @@ -0,0 +1,34 @@ +add('{{ field }}') + + {%- endfor %} + + ; + } + + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $resolver->setDefaults(array( + 'data_class' => '{{ namespace }}\Entity{{ entity_namespace ? '\\' ~ entity_namespace : '' }}\{{ entity_class }}' + )); + } + + public function getName() + { + return '{{ form_type_name }}'; + } +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/SensioGeneratorBundle.php b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/SensioGeneratorBundle.php new file mode 100644 index 0000000..5c4e799 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/SensioGeneratorBundle.php @@ -0,0 +1,23 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Sensio\Bundle\GeneratorBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +/** + * SensioGeneratorBundle. + * + * @author Fabien Potencier + */ +class SensioGeneratorBundle extends Bundle +{ +} diff --git a/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/composer.json b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/composer.json new file mode 100644 index 0000000..9195908 --- /dev/null +++ b/vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/composer.json @@ -0,0 +1,30 @@ +{ + "name": "sensio/generator-bundle", + "description": "This bundle generates code for you", + "keywords": [], + "type": "symfony-bundle", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "require": { + "symfony/framework-bundle": "2.1.*" + }, + "require-dev": { + "symfony/doctrine-bridge": "2.1.*", + "doctrine/orm": ">=2.1,<2.4-dev", + "twig/twig": ">=1.8,<2.0-dev" + }, + "autoload": { + "psr-0": { "Sensio\\Bundle\\GeneratorBundle": "" } + }, + "target-dir": "Sensio/Bundle/GeneratorBundle", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + } +} diff --git a/vendor/swiftmailer/swiftmailer/LICENSE b/vendor/swiftmailer/swiftmailer/LICENSE new file mode 100644 index 0000000..fc8a5de --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/vendor/swiftmailer/swiftmailer/VERSION b/vendor/swiftmailer/swiftmailer/VERSION new file mode 100644 index 0000000..16dd027 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/VERSION @@ -0,0 +1 @@ +Swift-4.1.9 diff --git a/vendor/swiftmailer/swiftmailer/composer.json b/vendor/swiftmailer/swiftmailer/composer.json new file mode 100644 index 0000000..1ed07af --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/composer.json @@ -0,0 +1,29 @@ +{ + "name": "swiftmailer/swiftmailer", + "type": "library", + "description": "Swiftmailer, free feature-rich PHP mailer", + "keywords": ["mail","mailer"], + "homepage": "http://swiftmailer.org", + "license": "LGPL", + "authors": [ + { + "name": "Chris Corbyn", + "email": "" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "require": { + "php": ">=5.2.4" + }, + "autoload": { + "files": ["lib/swift_required.php"] + }, + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + } +} diff --git a/vendor/swiftmailer/swiftmailer/doc/headers.rst b/vendor/swiftmailer/swiftmailer/doc/headers.rst new file mode 100644 index 0000000..18796ec --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/doc/headers.rst @@ -0,0 +1,742 @@ +Message Headers +=============== + +Sometimes you'll want to add your own headers to a message or modify/remove +headers that are already present. You work with the message's HeaderSet to do +this. + +Header Basics +------------- + +All MIME entities in Swift Mailer -- including the message itself -- +store their headers in a single object called a HeaderSet. This HeaderSet is +retrieved with the ``getHeaders()`` method. + +As mentioned in the previous chapter, everything that forms a part of a message +in Swift Mailer is a MIME entity that is represented by an instance of +``Swift_Mime_MimeEntity``. This includes -- most notably -- the message object +itself, attachments, MIME parts and embedded images. Each of these MIME entities +consists of a body and a set of headers that describe the body. + +For all of the "standard" headers in these MIME entities, such as the +``Content-Type``, there are named methods for working with them, such as +``setContentType()`` and ``getContentType()``. This is because headers are a +moderately complex area of the library. Each header has a slightly different +required structure that it must meet in order to comply with the standards that +govern email (and that are checked by spam blockers etc). + +You fetch the HeaderSet from a MIME entity like so: + +.. code-block:: php + + $message = Swift_Message::newInstance(); + + // Fetch the HeaderSet from a Message object + $headers = $message->getHeaders(); + + $attachment = Swift_Attachment::fromPath('document.pdf'); + + // Fetch the HeaderSet from an attachment object + $headers = $attachment->getHeaders(); + +The job of the HeaderSet is to contain and manage instances of Header objects. +Depending upon the MIME entity the HeaderSet came from, the contents of the +HeaderSet will be different, since an attachment for example has a different +set of headers to those in a message. + +You can find out what the HeaderSet contains with a quick loop, dumping out +the names of the headers: + +.. code-block:: php + + foreach ($headers->getAll() as $header) { + printf("%s
    \n", $header->getFieldName()); + } + + /* + Content-Transfer-Encoding + Content-Type + MIME-Version + Date + Message-ID + From + Subject + To + */ + +You can also dump out the rendered HeaderSet by calling its ``toString()`` +method: + +.. code-block:: php + + echo $headers->toString(); + + /* + Message-ID: <1234869991.499a9ee7f1d5e@swift.generated> + Date: Tue, 17 Feb 2009 22:26:31 +1100 + Subject: Awesome subject! + From: sender@example.org + To: recipient@example.org + MIME-Version: 1.0 + Content-Type: text/plain; charset=utf-8 + Content-Transfer-Encoding: quoted-printable + */ + +Where the complexity comes in is when you want to modify an existing header. +This complexity comes from the fact that each header can be of a slightly +different type (such as a Date header, or a header that contains email +addresses, or a header that has key-value parameters on it!). Each header in the +HeaderSet is an instance of ``Swift_Mime_Header``. They all have common +functionality, but knowing exactly what type of header you're working with will +allow you a little more control. + +You can determine the type of header by comparing the return value of its +``getFieldType()`` method with the constants ``TYPE_TEXT``, +``TYPE_PARAMETERIZED``, ``TYPE_DATE``, ``TYPE_MAILBOX``, ``TYPE_ID`` and +``TYPE_PATH`` which are defined in ``Swift_Mime_Header``. + + +.. code-block:: php + + foreach ($headers->getAll() as $header) { + switch ($header->getFieldType()) { + case Swift_Mime_Header::TYPE_TEXT: $type = 'text'; + break; + case Swift_Mime_Header::TYPE_PARAMETERIZED: $type = 'parameterized'; + break; + case Swift_Mime_Header::TYPE_MAILBOX: $type = 'mailbox'; + break; + case Swift_Mime_Header::TYPE_DATE: $type = 'date'; + break; + case Swift_Mime_Header::TYPE_ID: $type = 'ID'; + break; + case Swift_Mime_Header::TYPE_PATH: $type = 'path'; + break; + } + printf("%s: is a %s header
    \n", $header->getFieldName(), $type); + } + + /* + Content-Transfer-Encoding: is a text header + Content-Type: is a parameterized header + MIME-Version: is a text header + Date: is a date header + Message-ID: is a ID header + From: is a mailbox header + Subject: is a text header + To: is a mailbox header + */ + +Headers can be removed from the set, modified within the set, or added to the +set. + +The following sections show you how to work with the HeaderSet and explain the +details of each implementation of ``Swift_Mime_Header`` that may +exist within the HeaderSet. + +Header Types +------------ + +Because all headers are modeled on different data (dates, addresses, text!) +there are different types of Header in Swift Mailer. Swift Mailer attempts to +categorize all possible MIME headers into more general groups, defined by a +small number of classes. + +Text Headers +~~~~~~~~~~~~ + +Text headers are the simplest type of Header. They contain textual information +with no special information included within it -- for example the Subject +header in a message. + +There's nothing particularly interesting about a text header, though it is +probably the one you'd opt to use if you need to add a custom header to a +message. It represents text just like you'd think it does. If the text +contains characters that are not permitted in a message header (such as new +lines, or non-ascii characters) then the header takes care of encoding the +text so that it can be used. + +No header -- including text headers -- in Swift Mailer is vulnerable to +header-injection attacks. Swift Mailer breaks any attempt at header injection by +encoding the dangerous data into a non-dangerous form. + +It's easy to add a new text header to a HeaderSet. You do this by calling the +HeaderSet's ``addTextHeader()`` method. + +.. code-block:: php + + $message = Swift_Message::newInstance(); + + $headers = $message->getHeaders(); + + $headers->addTextHeader('Your-Header-Name', 'the header value'); + +Changing the value of an existing text header is done by calling it's +``setValue()`` method. + +.. code-block:: php + + $subject = $message->getHeaders()->get('Subject'); + + $subject->setValue('new subject'); + +When output via ``toString()``, a text header produces something like the +following: + +.. code-block:: php + + $subject = $message->getHeaders()->get('Subject'); + + $subject->setValue('amazing subject line'); + + echo $subject->toString(); + + /* + + Subject: amazing subject line + + */ + +If the header contains any characters that are outside of the US-ASCII range +however, they will be encoded. This is nothing to be concerned about since +mail clients will decode them back. + +.. code-block:: php + + $subject = $message->getHeaders()->get('Subject'); + + $subject->setValue('contains – dash'); + + echo $subject->toString(); + + /* + + Subject: contains =?utf-8?Q?=E2=80=93?= dash + + */ + +Parameterized Headers +~~~~~~~~~~~~~~~~~~~~~ + +Parameterized headers are text headers that contain key-value parameters +following the textual content. The Content-Type header of a message is a +parameterized header since it contains charset information after the content +type. + +The parameterized header type is a special type of text header. It extends the +text header by allowing additional information to follow it. All of the methods +from text headers are available in addition to the methods described here. + +Adding a parameterized header to a HeaderSet is done by using the +``addParameterizedHeader()`` method which takes a text value like +``addTextHeader()`` but it also accepts an associative array of +key-value parameters. + +.. code-block:: php + + $message = Swift_Message::newInstance(); + + $headers = $message->getHeaders(); + + $headers->addParameterizedHeader( + 'Header-Name', 'header value', + array('foo' => 'bar') + ); + +To change the text value of the header, call it's ``setValue()`` method just as +you do with text headers. + +To change the parameters in the header, call the header's ``setParameters()`` +method or the ``setParameter()`` method (note the pluralization). + +.. code-block:: php + + $type = $message->getHeaders()->get('Content-Type'); + + // setParameters() takes an associative array + $type->setParameters(array( + 'name' => 'file.txt', + 'charset' => 'iso-8859-1' + )); + + // setParameter() takes two args for $key and $value + $type->setParameter('charset', 'iso-8859-1'); + +When output via ``toString()``, a parameterized header produces something like +the following: + +.. code-block:: php + + $type = $message->getHeaders()->get('Content-Type'); + + $type->setValue('text/html'); + $type->setParameter('charset', 'utf-8'); + + echo $type->toString(); + + /* + + Content-Type: text/html; charset=utf-8 + + */ + +If the header contains any characters that are outside of the US-ASCII range +however, they will be encoded, just like they are for text headers. This is +nothing to be concerned about since mail clients will decode them back. +Likewise, if the parameters contain any non-ascii characters they will be +encoded so that they can be transmitted safely. + +.. code-block:: php + + $attachment = Swift_Attachment::newInstance(); + + $disp = $attachment->getHeaders()->get('Content-Disposition'); + + $disp->setValue('attachment'); + $disp->setParameter('filename', 'report–may.pdf'); + + echo $disp->toString(); + + /* + + Content-Disposition: attachment; filename*=utf-8''report%E2%80%93may.pdf + + */ + +Date Headers +~~~~~~~~~~~~ + +Date headers contains an RFC 2822 formatted date (i.e. what PHP's ``date('r')`` +returns). They are used anywhere a date or time is needed to be presented as a +message header. + +The data on which a date header is modeled is simply a UNIX timestamp such as +that returned by ``time()`` or ``strtotime()``. The timestamp is used to create +a correctly structured RFC 2822 formatted date such as +``Tue, 17 Feb 2009 22:26:31 +1100``. + +The obvious place this header type is used is in the ``Date:`` header of the +message itself. + +It's easy to add a new date header to a HeaderSet. You do this by calling +the HeaderSet's ``addDateHeader()`` method. + +.. code-block:: php + + $message = Swift_Message::newInstance(); + + $headers = $message->getHeaders(); + + $headers->addDateHeader('Your-Header-Name', strtotime('3 days ago')); + +Changing the value of an existing date header is done by calling it's +``setTimestamp()`` method. + +.. code-block:: php + + $date = $message->getHeaders()->get('Date'); + + $date->setTimestamp(time()); + +When output via ``toString()``, a date header produces something like the +following: + +.. code-block:: php + + $date = $message->getHeaders()->get('Date'); + + echo $date->toString(); + + /* + + Date: Wed, 18 Feb 2009 13:35:02 +1100 + + */ + +Mailbox (e-mail address) Headers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Mailbox headers contain one or more email addresses, possibly with +personalized names attached to them. The data on which they are modeled is +represented by an associative array of email addresses and names. + +Mailbox headers are probably the most complex header type to understand in +Swift Mailer because they accept their input as an array which can take various +forms, as described in the previous chapter. + +All of the headers that contain e-mail addresses in a message -- with the +exception of ``Return-Path:`` which has a stricter syntax -- use this header +type. That is, ``To:``, ``From:`` etc. + +You add a new mailbox header to a HeaderSet by calling the HeaderSet's +``addMailboxHeader()`` method. + +.. code-block:: php + + $message = Swift_Message::newInstance(); + + $headers = $message->getHeaders(); + + $headers->addMailboxHeader('Your-Header-Name', array( + 'person1@example.org' => 'Person Name One', + 'person2@example.org', + 'person3@example.org', + 'person4@example.org' => 'Another named person' + )); + +Changing the value of an existing mailbox header is done by calling it's +``setNameAddresses()`` method. + +.. code-block:: php + + $to = $message->getHeaders()->get('To'); + + $to->setNameAddresses(array( + 'joe@example.org' => 'Joe Bloggs', + 'john@example.org' => 'John Doe', + 'no-name@example.org' + )); + +If you don't wish to concern yourself with the complicated accepted input +formats accepted by ``setNameAddresses()`` as described in the previous chapter +and you only want to set one or more addresses (not names) then you can just +use the ``setAddresses()`` method instead. + +.. code-block:: php + + $to = $message->getHeaders()->get('To'); + + $to->setAddresses(array( + 'joe@example.org', + 'john@example.org', + 'no-name@example.org' + )); + +.. note:: + + Both methods will accept the above input format in practice. + +If all you want to do is set a single address in the header, you can use a +string as the input parameter to ``setAddresses()`` and/or +``setNameAddresses()``. + +.. code-block:: php + + $to = $message->getHeaders()->get('To'); + + $to->setAddresses('joe-bloggs@example.org'); + +When output via ``toString()``, a mailbox header produces something like the +following: + +.. code-block:: php + + $to = $message->getHeaders()->get('To'); + + $to->setNameAddresses(array( + 'person1@example.org' => 'Name of Person', + 'person2@example.org', + 'person3@example.org' => 'Another Person' + )); + + echo $to->toString(); + + /* + + To: Name of Person , person2@example.org, Another Person + + + */ + +ID Headers +~~~~~~~~~~ + +ID headers contain identifiers for the entity (or the message). The most +notable ID header is the Message-ID header on the message itself. + +An ID that exists inside an ID header looks more-or-less less like an email +address. For example, ``]]>``. +The part to the left of the @ sign is usually unique, based on the current time +and some random factor. The part on the right is usually a domain name. + +Any ID passed the an ID header's ``setId()`` method absolutely MUST conform to +this structure, otherwise you'll get an Exception thrown at you by Swift Mailer +(a ``Swift_RfcComplianceException``). This is to ensure that the generated +email complies with relevant RFC documents and therefore is less likely to be +blocked as spam. + +It's easy to add a new ID header to a HeaderSet. You do this by calling +the HeaderSet's ``addIdHeader()`` method. + +.. code-block:: php + + $message = Swift_Message::newInstance(); + + $headers = $message->getHeaders(); + + $headers->addIdHeader('Your-Header-Name', '123456.unqiue@example.org'); + +Changing the value of an existing date header is done by calling its +``setId()`` method. + +.. code-block:: php + + $msgId = $message->getHeaders()->get('Message-ID'); + + $msgId->setId(time() . '.' . uniqid('thing') . '@example.org'); + +When output via ``toString()``, an ID header produces something like the +following: + +.. code-block:: php + + $msgId = $message->getHeaders()->get('Message-ID'); + + echo $msgId->toString(); + + /* + + Message-ID: <1234955437.499becad62ec2@example.org> + + */ + +Path Headers +~~~~~~~~~~~~ + +Path headers are like very-restricted mailbox headers. They contain a single +email address with no associated name. The Return-Path header of a message is +a path header. + +You add a new path header to a HeaderSet by calling the HeaderSet's +``addPathHeader()`` method. + +.. code-block:: php + + $message = Swift_Message::newInstance(); + + $headers = $message->getHeaders(); + + $headers->addPathHeader('Your-Header-Name', 'person@example.org'); + + +Changing the value of an existing path header is done by calling its +``setAddress()`` method. + +.. code-block:: php + + $return = $message->getHeaders()->get('Return-Path'); + + $return->setAddress('my-address@example.org'); + +When output via ``toString()``, a path header produces something like the +following: + +.. code-block:: php + + $return = $message->getHeaders()->get('Return-Path'); + + $return->setAddress('person@example.org'); + + echo $return->toString(); + + /* + + Return-Path: + + */ + +Header Operations +----------------- + +Working with the headers in a message involves knowing how to use the methods +on the HeaderSet and on the individual Headers within the HeaderSet. + +Adding new Headers +~~~~~~~~~~~~~~~~~~ + +New headers can be added to the HeaderSet by using one of the provided +``add..Header()`` methods. + +To add a header to a MIME entity (such as the message): + +Get the HeaderSet from the entity by via its ``getHeaders()`` method. + +* Add the header to the HeaderSet by calling one of the ``add..Header()`` + methods. + +The added header will appear in the message when it is sent. + +.. code-block:: php + + // Adding a custom header to a message + $message = Swift_Message::newInstance(); + $headers = $message->getHeaders(); + $headers->addTextHeader('X-Mine', 'something here'); + + // Adding a custom header to an attachment + $attachment = Swift_Attachment::fromPath('/path/to/doc.pdf'); + $attachment->getHeaders()->addDateHeader('X-Created-Time', time()); + +Retrieving Headers +~~~~~~~~~~~~~~~~~~ + +Headers are retrieved through the HeaderSet's ``get()`` and ``getAll()`` +methods. + +To get a header, or several headers from a MIME entity: + +* Get the HeaderSet from the entity by via its ``getHeaders()`` method. + +* Get the header(s) from the HeaderSet by calling either ``get()`` or + ``getAll()``. + +When using ``get()`` a single header is returned that matches the name (case +insensitive) that is passed to it. When using ``getAll()`` with a header name, +an array of headers with that name are returned. Calling ``getAll()`` with no +arguments returns an array of all headers present in the entity. + +.. note:: + + It's valid for some headers to appear more than once in a message (e.g. + the Received header). For this reason ``getAll()`` exists to fetch all + headers with a specified name. In addition, ``get()`` accepts an optional + numerical index, starting from zero to specify which header you want more + specifically. + +.. note:: + + If you want to modify the contents of the header and you don't know for + sure what type of header it is then you may need to check the type by + calling its ``getFieldType()`` method. + + .. code-block:: php + + $headers = $message->getHeaders(); + + // Get the To: header + $toHeader = $headers->get('To'); + + // Get all headers named "X-Foo" + $fooHeaders = $headers->getAll('X-Foo'); + + // Get the second header named "X-Foo" + $foo = $headers->get('X-Foo', 1); + + // Get all headers that are present + $all = $headers->getAll(); + +Check if a Header Exists +~~~~~~~~~~~~~~~~~~~~~~~~ + +You can check if a named header is present in a HeaderSet by calling its +``has()`` method. + +To check if a header exists: + +* Get the HeaderSet from the entity by via its ``getHeaders()`` method. + +* Call the HeaderSet's ``has()`` method specifying the header you're looking + for. + +If the header exists, ``true`` will be returned or ``false`` if not. + +.. note:: + + It's valid for some headers to appear more than once in a message (e.g. + the Received header). For this reason ``has()`` accepts an optional + numerical index, starting from zero to specify which header you want to + check more specifically. + + .. code-block:: php + + $headers = $message->getHeaders(); + + // Check if the To: header exists + if ($headers->has('To')) { + echo 'To: exists'; + } + + // Check if an X-Foo header exists twice (i.e. check for the 2nd one) + if ($headers->has('X-Foo', 1)) { + echo 'Second X-Foo header exists'; + } + +Removing Headers +~~~~~~~~~~~~~~~~ + +Removing a Header from the HeaderSet is done by calling the HeaderSet's +``remove()`` or ``removeAll()`` methods. + +To remove an existing header: + +* Get the HeaderSet from the entity by via its ``getHeaders()`` method. + +* Call the HeaderSet's ``remove()`` or ``removeAll()`` methods specifying the + header you want to remove. + +When calling ``remove()`` a single header will be removed. When calling +``removeAll()`` all headers with the given name will be removed. If no headers +exist with the given name, no errors will occur. + +.. note:: + + It's valid for some headers to appear more than once in a message (e.g. + the Received header). For this reason ``remove()`` accepts an optional + numerical index, starting from zero to specify which header you want to + check more specifically. For the same reason, ``removeAll()`` exists to + remove all headers that have the given name. + + .. code-block:: php + + $headers = $message->getHeaders(); + + // Remove the Subject: header + $headers->remove('Subject'); + + // Remove all X-Foo headers + $headers->removeAll('X-Foo'); + + // Remove only the second X-Foo header + $headers->remove('X-Foo', 1); + +Modifying a Header's Content +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To change a Header's content you should know what type of header it is and then +call it's appropriate setter method. All headers also have a +``setFieldBodyModel()`` method that accepts a mixed parameter and delegates to +the correct setter. + +To modify an existing header: + +* Get the HeaderSet from the entity by via its ``getHeaders()`` method. + +* Get the Header by using the HeaderSet's ``get()``. + +* Call the Header's appropriate setter method or call the header's + ``setFieldBodyModel()`` method. + +The header will be updated inside the HeaderSet and the changes will be seen +when the message is sent. + +.. code-block:: php + + $headers = $message->getHeaders(); + + // Change the Subject: header + $subj = $headers->get('Subject'); + $subj->setValue('new subject here'); + + // Change the To: header + $to = $headers->get('To'); + $to->setNameAddresses(array( + 'person@example.org' => 'Person', + 'thing@example.org' + )); + + // Using the setFieldBodyModel() just delegates to the correct method + // So here to calls setNameAddresses() + $to->setFieldBodyModel(array( + 'person@example.org' => 'Person', + 'thing@example.org' + )); diff --git a/vendor/swiftmailer/swiftmailer/doc/help-resources.rst b/vendor/swiftmailer/swiftmailer/doc/help-resources.rst new file mode 100644 index 0000000..9820653 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/doc/help-resources.rst @@ -0,0 +1,44 @@ +Getting Help +============ + +There are a number of ways you can get help when using Swift Mailer, depending +upon the nature of your problem. For bug reports and feature requests create a +new ticket in Github. For general advice ask on the Google Group +(swiftmailer). + +Submitting Bugs & Feature Requests +---------------------------------- + +Bugs and feature requests should be posted on Github. + +If you post a bug or request a feature in the forum, or on the Google Group +you will most likely be asked to create a ticket in `Github`_ since it is +the simply not feasible to manage such requests from a number of a different +sources. + +When you go to Github you will be asked to create a username and password +before you can create a ticket. This is free and takes very little time. + +When you create your ticket, do not assign it to any milestones. A developer +will assess your ticket and re-assign it as needed. + +If your ticket is reporting a bug present in the current version, which was +not present in the previous version please include the tag "regression" in +your ticket. + +Github will update you when work is performed on your ticket. + +Ask on the Google Group +----------------------- + +You can seek advice at Google Groups, within the "swiftmailer" `group`_. + +You can post messages to this group if you want help, or there's something you +wish to discuss with the developers and with other users. + +This is probably the fastest way to get help since it is primarily email-based +for most users, though bug reports should not be posted here since they may +not be resolved. + +.. _`Github`: https://github.com/swiftmailer/swiftmailer/issues +.. _`group`: http://groups.google.com/group/swiftmailer diff --git a/vendor/swiftmailer/swiftmailer/doc/including-the-files.rst b/vendor/swiftmailer/swiftmailer/doc/including-the-files.rst new file mode 100644 index 0000000..34d0a4f --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/doc/including-the-files.rst @@ -0,0 +1,30 @@ +Including Swift Mailer (Autoloading) +==================================== + +Swift Mailer uses an autoloader so the only file you need to include is the +``lib/swift_required.php`` file. + +To use Swift Mailer's autoloader: + +* Put Swift Mailer somewhere accessible to your PHP scripts (this does not + need to be in the web root). + +* Include, or require the ``lib/swift_required.php`` file. + +* Follow the remainder of the documentation for using the available + components. + +.. note:: + + While Swift Mailer's autoloader is designed to play nicely with other + autoloaders, sometimes you may have a need to avoid using Swift Mailer's + autoloader and use your own instead. Include the ``swift_init.php`` + instead of the ``swift_required.php`` if you need to do this. The very + minimum include is the ``swift_init.php`` file since Swift Mailer will not + work without the dependency injection this file sets up: + + .. code-block:: php + + require_once '/path/to/swift-mailer/lib/swift_required.php'; + + /* rest of code goes here */ diff --git a/vendor/swiftmailer/swiftmailer/doc/index.rst b/vendor/swiftmailer/swiftmailer/doc/index.rst new file mode 100644 index 0000000..7c75658 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/doc/index.rst @@ -0,0 +1,15 @@ +Swiftmailer +=========== + +.. toctree:: + :maxdepth: 2 + + introduction + overview + installing + help-resources + including-the-files + messages + headers + sending + plugins diff --git a/vendor/swiftmailer/swiftmailer/doc/installing.rst b/vendor/swiftmailer/swiftmailer/doc/installing.rst new file mode 100644 index 0000000..31d8fe5 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/doc/installing.rst @@ -0,0 +1,201 @@ +Installing the Library +====================== + +Installing Swift Mailer is trivial. Usually it's just a case of uploading the +extracted source files to your web server. + +Installing from PEAR +-------------------- + +If you want to install Swift Mailer globally on your machine, the easiest +installation method is using the PEAR channel. + +To install the Swift Mailer PEAR package: + +* Run the command ``pear channel-discover pear.swiftmailer.org``. + +* Then, run the command ``pear install swift/swift``. + +Installing from a Package +------------------------- + +Most users will download a package from the Swift Mailer website and install +Swift Mailer using this. + +If you downloaded Swift Mailer as a ``.tar.gz`` or +``.zip`` file installation is as simple as extracting the archive +and uploading it to your web server. + +Extracting the Library +~~~~~~~~~~~~~~~~~~~~~~ + +You extract the archive by using your favorite unarchiving tool such as +``tar`` or 7-Zip. + +You will need to have access to a program that can open uncompress the +archive. On Windows computers, 7-Zip will work. On Mac and Linux systems you +can use ``tar`` on the command line. + +To extract your downloaded package: + +* Use the "extract" facility of your archiving software. + +The source code will be placed into a directory with the same name as the +archive (e.g. Swift-4.0.0-b1). + +The following example shows the process on Mac OS X and Linux systems using +the ``tar`` command. + +.. code-block:: bash + + $ ls + Swift-4.0.0-dev.tar.gz + $ tar xvzf Swift-4.0.0-dev.tar.gz + Swift-4.0.0-dev/ + Swift-4.0.0-dev/lib/ + Swift-4.0.0-dev/lib/classes/ + Swift-4.0.0-dev/lib/classes/Swift/ + Swift-4.0.0-dev/lib/classes/Swift/ByteStream/ + Swift-4.0.0-dev/lib/classes/Swift/CharacterReader/ + Swift-4.0.0-dev/lib/classes/Swift/CharacterReaderFactory/ + Swift-4.0.0-dev/lib/classes/Swift/CharacterStream/ + Swift-4.0.0-dev/lib/classes/Swift/Encoder/ + + ... etc etc ... + + Swift-4.0.0-dev/tests/unit/Swift/Transport/LoadBalancedTransportTest.php + Swift-4.0.0-dev/tests/unit/Swift/Transport/SendmailTransportTest.php + Swift-4.0.0-dev/tests/unit/Swift/Transport/StreamBufferTest.php + $ cd Swift-4.0.0-dev + $ ls + CHANGES LICENSE.GPL LICENSE.LGPL README VERSION examples lib test-suite tests + $ + +Installing from Git +------------------- + +It's possible to download and install Swift Mailer directly from github.com if +you want to keep up-to-date with ease. + +Swift Mailer's source code is kept in a git repository at github.com so you +can get the source directly from the repository. + +.. note:: + + You do not need to have git installed to use Swift Mailer from github. If + you don't have git installed, go to `github`_ and click the "Download" + button. + +Cloning the Repository +~~~~~~~~~~~~~~~~~~~~~~ + +The repository can be cloned from git://github.com/swiftmailer/swiftmailer.git +using the ``git clone`` command. + +You will need to have ``git`` installed before you can use the +``git clone`` command. + +To clone the repository: + +* Open your favorite terminal environment (command line). + +* Move to the directory you want to clone to. + +* Run the command ``git clone git://github.com/swiftmailer/swiftmailer.git + swiftmailer``. + +The source code will be downloaded into a directory called "swiftmailer". + +The example shows the process on a UNIX-like system such as Linux, BSD or Mac +OS X. + +.. code-block:: bash + + $ cd source_code/ + $ git clone git://github.com/swiftmailer/swiftmailer.git swiftmailer + Initialized empty Git repository in /Users/chris/source_code/swiftmailer/.git/ + remote: Counting objects: 6815, done. + remote: Compressing objects: 100% (2761/2761), done. + remote: Total 6815 (delta 3641), reused 6326 (delta 3286) + Receiving objects: 100% (6815/6815), 4.35 MiB | 162 KiB/s, done. + Resolving deltas: 100% (3641/3641), done. + Checking out files: 100% (1847/1847), done. + $ cd swiftmailer/ + $ ls + CHANGES LICENSE.LGPL README.git VERSION docs lib test-suite util + LICENSE.GPL README TODO build.xml examples notes tests + $ + +Uploading to your Host +---------------------- + +You only need to upload the "lib/" directory to your web host for production +use. All other files and directories are support files not needed in +production. + +You will need FTP, ``rsync`` or similar software installed in order to upload +the "lib/" directory to your web host. + +To upload Swift Mailer: + +* Open your FTP program, or a command line if you prefer rsync/scp. + +* Upload the "lib/" directory to your hosting account. + +The files needed to use Swift Mailer should now be accessible to PHP on your +host. + +The following example shows show you can upload the files using +``rsync`` on Linux or OS X. + +.. note:: + + You do not need to place the files inside your web root. They only need to + be in a place where your PHP scripts can "include" them. + + .. code-block:: bash + + $ rsync -rvz lib d11wtq@swiftmailer.org:swiftmailer + building file list ... done + created directory swiftmailer + lib/ + lib/mime_types.php + lib/preferences.php + lib/swift_required.php + lib/classes/ + lib/classes/Swift/ + lib/classes/Swift/Attachment.php + lib/classes/Swift/CharacterReader.php + ... etc etc ... + lib/dependency_maps/ + lib/dependency_maps/cache_deps.php + lib/dependency_maps/mime_deps.php + lib/dependency_maps/transport_deps.php + + sent 151692 bytes received 2974 bytes 5836.45 bytes/sec + total size is 401405 speedup is 2.60 + $ + +.. _`github`: http://github.com/swiftmailer/swiftmailer + +Troubleshooting +--------------- + +Swift Mailer does not work when used with function overloading as implemented +by ``mbstring`` (``mbstring.func_overload`` set to ``2``). A workaround is to +temporarily change the internal encoding to ``ASCII`` when sending an email: + +.. code-block:: php + + if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) + { + $mbEncoding = mb_internal_encoding(); + mb_internal_encoding('ASCII'); + } + + // Create your message and send it with Swift Mailer + + if (isset($mbEncoding)) + { + mb_internal_encoding($mbEncoding); + } diff --git a/vendor/swiftmailer/swiftmailer/doc/introduction.rst b/vendor/swiftmailer/swiftmailer/doc/introduction.rst new file mode 100644 index 0000000..39ab034 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/doc/introduction.rst @@ -0,0 +1,135 @@ +Introduction +============ + +Swift Mailer is a component-based library for sending e-mails from PHP +applications. + +Organization of this Book +------------------------- + +This book has been written so that those who need information quickly are able +to find what they need, and those who wish to learn more advanced topics can +read deeper into each chapter. + +The book begins with an overview of Swift Mailer, discussing what's included +in the package and preparing you for the remainder of the book. + +It is possible to read this user guide just like any other book (from +beginning to end). Each chapter begins with a discussion of the contents it +contains, followed by a short code sample designed to give you a head start. +As you get further into a chapter you will learn more about Swift Mailer's +capabilities, but often you will be able to head directly to the topic you +wish to learn about. + +Throughout this book you will be presented with code samples, which most +people should find ample to implement Swift Mailer appropriately in their own +projects. We will also use diagrams where appropriate, and where we believe +readers may find it helpful we will discuss some related theory, including +reference to certain documents you are able to find online. + +Code Samples +------------ + +Code samples presented in this book will be displayed on a different colored +background in a monospaced font. Samples are not to be taken as copy & paste +code snippets. + +Code examples are used through the book to clarify what is written in text. +They will sometimes be usable as-is, but they should always be taken as +outline/pseudo code only. + +A code sample will look like this:: + + class AClass + { + ... + } + + //A Comment + $obj = new AClass($arg1, $arg2, ... ); + + /* A note about another way of doing something + $obj = AClass::newInstance($arg1, $arg2, ... ); + + */ + +The presence of 3 dots ``...`` in a code sample indicates that we have left +out a chunk of the code for brevity, they are not actually part of the code. + +We will often place multi-line comments ``/* ... */`` in the code so that we +can show alternative ways of achieving the same result. + +You should read the code examples given and try to understand them. They are +kept concise so that you are not overwhelmed with information. + +History of Swift Mailer +----------------------- + +Swift Mailer began back in 2005 as a one-class project for sending mail over +SMTP. It has since grown into the flexible component-based library that is in +development today. + +Chris Corbyn first posted Swift Mailer on a web forum asking for comments from +other developers. It was never intended as a fully supported open source +project, but members of the forum began to adopt it and make use of it. + +Very quickly feature requests were coming for the ability to add attachments +and use SMTP authentication, along with a number of other "obvious" missing +features. Considering the only alternative was PHPMailer it seemed like a good +time to bring some fresh tools to the table. Chris began working towards a +more component based, PHP5-like approach unlike the existing single-class, +legacy PHP4 approach taken by PHPMailer. + +Members of the forum offered a lot of advice and critique on the code as he +worked through this project and released versions 2 and 3 of the library in +2005 and 2006, which by then had been broken down into smaller classes +offering more flexibility and supporting plugins. To this day the Swift Mailer +team still receive a lot of feature requests from users both on the forum and +in by email. + +Until 2008 Chris was the sole developer of Swift Mailer, but entering 2009 he +gained the support of two experienced developers well-known to him: Paul +Annesley and Christopher Thompson. This has been an extremely welcome change. + +As of September 2009, Chris handed over the maintenance of Swift Mailer to +Fabien Potencier. + +Now 2009 and in its fourth major version Swift Mailer is more object-oriented +and flexible than ever, both from a usability standpoint and from a +development standpoint. + +By no means is Swift Mailer ready to call "finished". There are still many +features that can be added to the library along with the constant refactoring +that happens behind the scenes. + +It's a Library! +--------------- + +Swift Mailer is not an application - it's a library. + +To most experienced developers this is probably an obvious point to make, but +it's certainly worth mentioning. Many people often contact us having gotten +the completely wrong end of the stick in terms of what Swift Mailer is +actually for. + +It's not an application. It does not have a graphical user interface. It +cannot be opened in your web browser directly. + +It's a library (or a framework if you like). It provides a whole lot of +classes that do some very complicated things, so that you don't have to. You +"use" Swift Mailer within an application so that your application can have the +ability to send emails. + +The component-based structure of the library means that you are free to +implement it in a number of different ways and that you can pick and choose +what you want to use. + +An application on the other hand (such as a blog or a forum) is already "put +together" in a particular way, (usually) provides a graphical user interface +and most likely doesn't offer a great deal of integration with your own +application. + +Embrace the structure of the library and use the components it offers to your +advantage. Learning what the components do, rather than blindly copying and +pasting existing code will put you in a great position to build a powerful +application! diff --git a/vendor/swiftmailer/swiftmailer/doc/messages.rst b/vendor/swiftmailer/swiftmailer/doc/messages.rst new file mode 100644 index 0000000..fd24d31 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/doc/messages.rst @@ -0,0 +1,964 @@ +Creating Messages +================= + +Creating messages in Swift Mailer is done by making use of the various MIME +entities provided with the library. Complex messages can be quickly created +with very little effort. + +Quick Reference for Creating a Message +--------------------------------------- + +You can think of creating a Message as being similar to the steps you perform +when you click the Compose button in your mail client. You give it a subject, +specify some recipients, add any attachments and write your message. + +To create a Message: + +* Call the ``newInstance()`` method of ``Swift_Message``. + +* Set your sender address (``From:``) with ``setFrom()`` or ``setSender()``. + +* Set a subject line with ``setSubject()``. + +* Set recipients with ``setTo()``, ``setCc()`` and/or ``setBcc()``. + +* Set a body with ``setBody()``. + +* Add attachments with ``attach()``. + +.. code-block:: php + + require_once 'lib/swift_required.php'; + + // Create the message + $message = Swift_Message::newInstance() + + // Give the message a subject + ->setSubject('Your subject') + + // Set the From address with an associative array + ->setFrom(array('john@doe.com' => 'John Doe')) + + // Set the To addresses with an associative array + ->setTo(array('receiver@domain.org', 'other@domain.org' => 'A name')) + + // Give it a body + ->setBody('Here is the message itself') + + // And optionally an alternative body + ->addPart('Here is the message itself', 'text/html') + + // Optionally add any attachments + ->attach(Swift_Attachment::fromPath('my-document.pdf')) + ; + +Message Basics +-------------- + +A message is a container for anything you want to send to somebody else. There +are several basic aspects of a message that you should know. + +An e-mail message is made up of several relatively simple entities that are +combined in different ways to achieve different results. All of these entities +have the same fundamental outline but serve a different purpose. The Message +itself can be defined as a MIME entity, an Attachment is a MIME entity, all +MIME parts are MIME entities -- and so on! + +The basic units of each MIME entity -- be it the Message itself, or an +Attachment -- are its Headers and its body: + +.. code-block:: text + + Header-Name: A header value + Other-Header: Another value + + The body content itself + +The Headers of a MIME entity, and its body must conform to some strict +standards defined by various RFC documents. Swift Mailer ensures that these +specifications are followed by using various types of object, including +Encoders and different Header types to generate the entity. + +The Structure of a Message +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Of all of the MIME entities, a message -- ``Swift_Message`` +is the largest and most complex. It has many properties that can be updated +and it can contain other MIME entities -- attachments for example -- +nested inside it. + +A Message has a lot of different Headers which are there to present +information about the message to the recipients' mail client. Most of these +headers will be familiar to the majority of users, but we'll list the basic +ones. Although it's possible to work directly with the Headers of a Message +(or other MIME entity), the standard Headers have accessor methods provided to +abstract away the complex details for you. For example, although the Date on a +message is written with a strict format, you only need to pass a UNIX +timestamp to ``setDate()``. + ++-------------------------------+------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------+ +| Header | Description | Accessors | ++===============================+====================================================================================================================================+=============================================+ +| ``Message-ID`` | Identifies this message with a unique ID, usually containing the domain name and time generated | ``getId()`` / ``setId()`` | ++-------------------------------+------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------+ +| ``Return-Path`` | Specifies where bounces should go (Swift Mailer reads this for other uses) | ``getReturnPath()`` / ``setReturnPath()`` | ++-------------------------------+------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------+ +| ``From`` | Specifies the address of the person who the message is from. This can be multiple addresses if multiple people wrote the message. | ``getFrom()`` / ``setFrom()`` | ++-------------------------------+------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------+ +| ``Sender`` | Specifies the address of the person who physically sent the message (higher precedence than ``From:``) | ``getSender()`` / ``setSender()`` | ++-------------------------------+------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------+ +| ``To`` | Specifies the addresses of the intended recipients | ``getTo()`` / ``setTo()`` | ++-------------------------------+------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------+ +| ``Cc`` | Specifies the addresses of recipients who will be copied in on the message | ``getCc()`` / ``setCc()`` | ++-------------------------------+------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------+ +| ``Bcc`` | Specifies the addresses of recipients who the message will be blind-copied to. Other recipients will not be aware of these copies. | ``getBcc()`` / ``setBcc()`` | ++-------------------------------+------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------+ +| ``Reply-To`` | Specifies the address where replies are sent to | ``getReplyTo()`` / ``setReplyTo()`` | ++-------------------------------+------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------+ +| ``Subject`` | Specifies the subject line that is displayed in the recipients' mail client | ``getSubject()`` / ``setSubject()`` | ++-------------------------------+------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------+ +| ``Date`` | Specifies the date at which the message was sent | ``getDate()`` / ``setDate()`` | ++-------------------------------+------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------+ +| ``Content-Type`` | Specifies the format of the message (usually text/plain or text/html) | ``getContentType()`` / ``setContentType()`` | ++-------------------------------+------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------+ +| ``Content-Transfer-Encoding`` | Specifies the encoding scheme in the message | ``getEncoder()`` / ``setEncoder()`` | ++-------------------------------+------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------+ + +Working with a Message Object +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Although there are a lot of available methods on a message object, you only +need to make use of a small subset of them. Usually you'll use +``setSubject()``, ``setTo()`` and +``setFrom()`` before setting the body of your message with +``setBody()``. + +Calling methods is simple. You just call them like functions, but using the +object operator "``]]>``" to do so. If you've created +a message object and called it ``$message`` then you'd set a +subject on it like so: + +.. code-block:: php + + require_once 'lib/swift_required.php'; + + $message = Swift_Message::newInstance(); + $message->setSubject('My subject'); + +All MIME entities (including a message) have a ``toString()`` +method that you can call if you want to take a look at what is going to be +sent. For example, if you ``toString();]]>`` you would see something like this: + +.. code-block:: bash + + Message-ID: <1230173678.4952f5eeb1432@swift.generated> + Date: Thu, 25 Dec 2008 13:54:38 +1100 + Subject: Example subject + From: Chris Corbyn + To: Receiver Name + MIME-Version: 1.0 + Content-Type: text/plain; charset=utf-8 + Content-Transfer-Encoding: quoted-printable + + Here is the message + +We'll take a closer look at the methods you use to create your message in the +following sections. + +Adding Content to Your Message +------------------------------ + +Rich content can be added to messages in Swift Mailer with relative ease by +calling methods such as ``setSubject()``, ``setBody()``, ``addPart()`` and +``attach()``. + +Setting the Subject Line +~~~~~~~~~~~~~~~~~~~~~~~~ + +The subject line, displayed in the recipients' mail client can be set with the +``setSubject()`` method, or as a parameter to ``Swift_Message::newInstance()``. + +To set the subject of your Message: + +* Call the ``setSubject()`` method of the Message, or specify it at the time + you create the message. + + .. code-block:: php + + // Pass it as a parameter when you create the message + $message = Swift_Message::newInstance('My amazing subject'); + + // Or set it after like this + $message->setSubject('My amazing subject'); + +Setting the Body Content +~~~~~~~~~~~~~~~~~~~~~~~~ + +The body of the message -- seen when the user opens the message -- +is specified by calling the ``setBody()`` method. If an alternative body is to +be included ``addPart()`` can be used. + +The body of a message is the main part that is read by the user. Often people +want to send a message in HTML format (``text/html``), other +times people want to send in plain text (``text/plain``), or +sometimes people want to send both versions and allow the recipient to chose +how they view the message. + +As a rule of thumb, if you're going to send a HTML email, always include a +plain-text equivalent of the same content so that users who prefer to read +plain text can do so. + +To set the body of your Message: + +* Call the ``setBody()`` method of the Message, or specify it at the time you + create the message. + +* Add any alternative bodies with ``addPart()``. + +If the recipient's mail client offers preferences for displaying text vs. HTML +then the mail client will present that part to the user where available. In +other cases the mail client will display the "best" part it can - usually HTML +if you've included HTML. + +.. code-block:: php + + // Pass it as a parameter when you create the message + $message = Swift_Message::newInstance('Subject here', 'My amazing body'); + + // Or set it after like this + $message->setBody('My amazing body', 'text/html'); + + // Add alternative parts with addPart() + $message->addPart('My amazing body in plain text', 'text/plain'); + +Attaching Files +--------------- + +Attachments are downloadable parts of a message and can be added by calling +the ``attach()`` method on the message. You can add attachments that exist on +disk, or you can create attachments on-the-fly. + +Attachments are actually an interesting area of Swift Mailer and something +that could put a lot of power at your fingertips if you grasp the concept +behind the way a message is held together. + +Although we refer to files sent over e-mails as "attachments" -- because +they're attached to the message -- lots of other parts of the message are +actually "attached" even if we don't refer to these parts as attachments. + +File attachments are created by the ``Swift_Attachment`` class +and then attached to the message via the ``attach()`` method on +it. For all of the "every day" MIME types such as all image formats, word +documents, PDFs and spreadsheets you don't need to explicitly set the +content-type of the attachment, though it would do no harm to do so. For less +common formats you should set the content-type -- which we'll cover in a +moment. + +Attaching Existing Files +~~~~~~~~~~~~~~~~~~~~~~~~ + +Files that already exist, either on disk or at a URL can be attached to a +message with just one line of code, using ``Swift_Attachment::fromPath()``. + +You can attach files that exist locally, or if your PHP installation has +``allow_url_fopen`` turned on you can attach files from other +websites. + +To attach an existing file: + +* Create an attachment with ``Swift_Attachment::fromPath()``. + +* Add the attachment to the message with ``attach()``. + +The attachment will be presented to the recipient as a downloadable file with +the same filename as the one you attached. + +.. code-block:: php + + // Create the attachment + // * Note that you can technically leave the content-type parameter out + $attachment = Swift_Attachment::fromPath('/path/to/image.jpg', 'image/jpeg'); + + // Attach it to the message + $message->attach($attachment); + + + // The two statements above could be written in one line instead + $message->attach(Swift_Attachment::fromPath('/path/to/image.jpg')); + + + // You can attach files from a URL if allow_url_fopen is on in php.ini + $message->attach(Swift_Attachment::fromPath('http://site.tld/logo.png')); + +Setting the Filename +~~~~~~~~~~~~~~~~~~~~ + +Usually you don't need to explicitly set the filename of an attachment because +the name of the attached file will be used by default, but if you want to set +the filename you use the ``setFilename()`` method of the Attachment. + +To change the filename of an attachment: + +* Call its ``setFilename()`` method. + +The attachment will be attached in the normal way, but meta-data sent inside +the email will rename the file to something else. + +.. code-block:: php + + // Create the attachment and call its setFilename() method + $attachment = Swift_Attachment::fromPath('/path/to/image.jpg') + ->setFilename('cool.jpg'); + + + // Because there's a fluid interface, you can do this in one statement + $message->attach( + Swift_Attachment::fromPath('/path/to/image.jpg')->setFilename('cool.jpg') + ); + +Attaching Dynamic Content +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Files that are generated at runtime, such as PDF documents or images created +via GD can be attached directly to a message without writing them out to disk. +Use the standard ``Swift_Attachment::newInstance()`` method. + +To attach dynamically created content: + +* Create your content as you normally would. + +* Create an attachment with ``Swift_Attachment::newInstance()``, specifying + the source data of your content along with a name and the content-type. + +* Add the attachment to the message with ``attach()``. + +The attachment will be presented to the recipient as a downloadable file +with the filename and content-type you specify. + +.. note:: + + If you would usually write the file to disk anyway you should just attach + it with ``Swift_Attachment::fromPath()`` since this will use less memory: + + .. code-block:: php + + // Create your file contents in the normal way, but don't write them to disk + $data = create_my_pdf_data(); + + // Create the attachment with your data + $attachment = Swift_Attachment::newInstance($data, 'my-file.pdf', 'application/pdf'); + + // Attach it to the message + $message->attach($attachment); + + + // You can alternatively use method chaining to build the attachment + $attachment = Swift_Attachment::newInstance() + ->setFilename('my-file.pdf') + ->setContentType('application/pdf') + ->setBody($data) + ; + +Changing the Disposition +~~~~~~~~~~~~~~~~~~~~~~~~ + +Attachments just appear as files that can be saved to the Desktop if desired. +You can make attachment appear inline where possible by using the +``setDisposition()`` method of an attachment. + +To make an attachment appear inline: + +* Call its ``setDisposition()`` method. + +The attachment will be displayed within the email viewing window if the mail +client knows how to display it. + +.. note:: + + If you try to create an inline attachment for a non-displayable file type + such as a ZIP file, the mail client should just present the attachment as + normal: + + .. code-block:: php + + // Create the attachment and call its setDisposition() method + $attachment = Swift_Attachment::fromPath('/path/to/image.jpg') + ->setDisposition('inline'); + + + // Because there's a fluid interface, you can do this in one statement + $message->attach( + Swift_Attachment::fromPath('/path/to/image.jpg')->setDisposition('inline') + ); + +Embedding Inline Media Files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Often people want to include an image or other content inline with a HTML +message. It's easy to do this with HTML linking to remote resources, but this +approach is usually blocked by mail clients. Swift Mailer allows you to embed +your media directly into the message. + +Mail clients usually block downloads from remote resources because this +technique was often abused as a mean of tracking who opened an email. If +you're sending a HTML email and you want to include an image in the message +another approach you can take is to embed the image directly. + +Swift Mailer makes embedding files into messages extremely streamlined. You +embed a file by calling the ``embed()`` method of the message, +which returns a value you can use in a ``src`` or +``href`` attribute in your HTML. + +Just like with attachments, it's possible to embed dynamically generated +content without having an existing file available. + +The embedded files are sent in the email as a special type of attachment that +has a unique ID used to reference them within your HTML attributes. On mail +clients that do not support embedded files they may appear as attachments. + +Although this is commonly done for images, in theory it will work for any +displayable (or playable) media type. Support for other media types (such as +video) is dependent on the mail client however. + +Embedding Existing Files +........................ + +Files that already exist, either on disk or at a URL can be embedded in a +message with just one line of code, using ``Swift_EmbeddedFile::fromPath()``. + +You can embed files that exist locally, or if your PHP installation has +``allow_url_fopen`` turned on you can embed files from other websites. + +To embed an existing file: + +* Create a message object with ``Swift_Message::newInstance()``. + +* Set the body as HTML, and embed a file at the correct point in the message with ``embed()``. + +The file will be displayed with the message inline with the HTML wherever its ID +is used as a ``src`` attribute. + +.. note:: + + ``Swift_Image`` and ``Swift_EmbeddedFile`` are just aliases of one + another. ``Swift_Image`` exists for semantic purposes. + +.. note:: + + You can embed files in two stages if you prefer. Just capture the return + value of ``embed()`` in a variable and use that as the ``src`` attribute. + + .. code-block:: php + + // Create the message + $message = Swift_Message::newInstance('My subject'); + + // Set the body + $message->setBody( + '' . + ' ' . + ' ' . + ' Here is an image Image' . + ' Rest of message' . + ' ' . + '', + 'text/html' // Mark the content-type as HTML + ); + + // You can embed files from a URL if allow_url_fopen is on in php.ini + $message->setBody( + '' . + ' ' . + ' ' . + ' Here is an image Image' . + ' Rest of message' . + ' ' . + '', + 'text/html' + ); + + + // If placing the embed() code inline becomes cumbersome + // it's easy to do this in two steps + $cid = $message->embed(Swift_Image::fromPath('image.png')); + + $message->setBody( + '' . + ' ' . + ' ' . + ' Here is an image Image' . + ' Rest of message' . + ' ' . + '', + 'text/html' // Mark the content-type as HTML + ); + +Embedding Dynamic Content +......................... + +Images that are generated at runtime, such as images created via GD can be +embedded directly to a message without writing them out to disk. Use the +standard ``Swift_Image::newInstance()`` method. + +To embed dynamically created content: + +* Create a message object with ``Swift_Message::newInstance()``. + +* Set the body as HTML, and embed a file at the correct point in the message + with ``embed()``. You will need to specify a filename and a content-type. + +The file will be displayed with the message inline with the HTML wherever its ID +is used as a ``src`` attribute. + +.. note:: + + ``Swift_Image`` and ``Swift_EmbeddedFile`` are just aliases of one + another. ``Swift_Image`` exists for semantic purposes. + +.. note:: + + You can embed files in two stages if you prefer. Just capture the return + value of ``embed()`` in a variable and use that as the ``src`` attribute. + + .. code-block:: php + + // Create your file contents in the normal way, but don't write them to disk + $img_data = create_my_image_data(); + + //Create the message + $message = Swift_Message::newInstance('My subject'); + + //Set the body + $message->setBody( + '' . + ' ' . + ' ' . + ' Here is an image Image' . + ' Rest of message' . + ' ' . + '', + 'text/html' // Mark the content-type as HTML + ); + + + // If placing the embed() code inline becomes cumbersome + // it's easy to do this in two steps + $cid = $message->embed(Swift_Image::newInstance($img_data, 'image.jpg', 'image/jpeg')); + + $message->setBody( + '' . + ' ' . + ' ' . + ' Here is an image Image' . + ' Rest of message' . + ' ' . + '', + 'text/html' // Mark the content-type as HTML + ); + +Adding Recipients to Your Message +--------------------------------- + +Recipients are specified within the message itself via ``setTo()``, ``setCc()`` +and ``setBcc()``. Swift Mailer reads these recipients from the message when it +gets sent so that it knows where to send the message to. + +Message recipients are one of three types: + +* ``To:`` recipients -- the primary recipients (required) + +* ``Cc:`` recipients -- receive a copy of the message (optional) + +* ``Bcc:`` recipients -- hidden from other recipients (optional) + +Each type can contain one, or several addresses. It's possible to list only +the addresses of the recipients, or you can personalize the address by +providing the real name of the recipient. + +.. sidebar:: Syntax for Addresses + + If you only wish to refer to a single email address (for example your + ``From:`` address) then you can just use a string. + + .. code-block:: php + + $message->setFrom('some@address.tld'); + + If you want to include a name then you must use an associative array. + + .. code-block:: php + + $message->setFrom(array('some@address.tld' => 'The Name')); + + If you want to include multiple addresses then you must use an array. + + .. code-block:: php + + $message->setTo(array('some@address.tld', 'other@address.tld')); + + You can mix personalized (addresses with a name) and non-personalized + addresses in the same list by mixing the use of associative and + non-associative array syntax. + + .. code-block:: php + + $message->setTo(array( + 'recipient-with-name@example.org' => 'Recipient Name One', + 'no-name@example.org', // Note that this is not a key-value pair + 'named-recipient@example.org' => 'Recipient Name Two' + )); + +Setting ``To:`` Recipients +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``To:`` recipients are required in a message and are set with the +``setTo()`` or ``addTo()`` methods of the message. + +To set ``To:`` recipients, create the message object using either +``new Swift_Message( ... )`` or ``Swift_Message::newInstance( ... )``, +then call the ``setTo()`` method with a complete array of addresses, or use the +``addTo()`` method to iteratively add recipients. + +The ``setTo()`` method accepts input in various formats as described earlier in +this chapter. The ``addTo()`` method takes either one or two parameters. The +first being the email address and the second optional parameter being the name +of the recipient. + +``To:`` recipients are visible in the message headers and will be +seen by the other recipients. + +.. note:: + + Multiple calls to ``setTo()`` will not add new recipients -- each + call overrides the previous calls. If you want to iteratively add + recipients, use the ``addTo()`` method. + + .. code-block:: php + + // Using setTo() to set all recipients in one go + $message->setTo(array( + 'person1@example.org', + 'person2@otherdomain.org' => 'Person 2 Name', + 'person3@example.org', + 'person4@example.org', + 'person5@example.org' => 'Person 5 Name' + )); + + // Using addTo() to add recipients iteratively + $message->addTo('person1@example.org'); + $message->addTo('person2@example.org', 'Person 2 Name'); + +Setting ``Cc:`` Recipients +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``Cc:`` recipients are set with the ``setCc()`` or ``addCc()`` methods of the +message. + +To set ``Cc:`` recipients, create the message object using either +``new Swift_Message( ... )`` or ``Swift_Message::newInstance( ... )``, then call +the ``setCc()`` method with a complete array of addresses, or use the +``addCc()`` method to iteratively add recipients. + +The ``setCc()`` method accepts input in various formats as described earlier in +this chapter. The ``addCc()`` method takes either one or two parameters. The +first being the email address and the second optional parameter being the name +of the recipient. + +``Cc:`` recipients are visible in the message headers and will be +seen by the other recipients. + +.. note:: + + Multiple calls to ``setCc()`` will not add new recipients -- each + call overrides the previous calls. If you want to iteratively add Cc: + recipients, use the ``addCc()`` method. + + .. code-block:: php + + // Using setCc() to set all recipients in one go + $message->setCc(array( + 'person1@example.org', + 'person2@otherdomain.org' => 'Person 2 Name', + 'person3@example.org', + 'person4@example.org', + 'person5@example.org' => 'Person 5 Name' + )); + + // Using addCc() to add recipients iteratively + $message->addCc('person1@example.org'); + $message->addCc('person2@example.org', 'Person 2 Name'); + +Setting ``Bcc:`` Recipients +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``Bcc:`` recipients receive a copy of the message without anybody else knowing +it, and are set with the ``setBcc()`` or ``addBcc()`` methods of the message. + +To set ``Bcc:`` recipients, create the message object using either ``new +Swift_Message( ... )`` or ``Swift_Message::newInstance( ... )``, then call the +``setBcc()`` method with a complete array of addresses, or use +the ``addBcc()`` method to iteratively add recipients. + +The ``setBcc()`` method accepts input in various formats as described earlier in +this chapter. The ``addBcc()`` method takes either one or two parameters. The +first being the email address and the second optional parameter being the name +of the recipient. + +Only the individual ``Bcc:`` recipient will see their address in the message +headers. Other recipients (including other ``Bcc:`` recipients) will not see the +address. + +.. note:: + + Multiple calls to ``setBcc()`` will not add new recipients -- each + call overrides the previous calls. If you want to iteratively add Bcc: + recipients, use the ``addBcc()`` method. + + .. code-block:: php + + // Using setBcc() to set all recipients in one go + $message->setBcc(array( + 'person1@example.org', + 'person2@otherdomain.org' => 'Person 2 Name', + 'person3@example.org', + 'person4@example.org', + 'person5@example.org' => 'Person 5 Name' + )); + + // Using addBcc() to add recipients iteratively + $message->addBcc('person1@example.org'); + $message->addBcc('person2@example.org', 'Person 2 Name'); + +Specifying Sender Details +------------------------- + +An email must include information about who sent it. Usually this is managed +by the ``From:`` address, however there are other options. + +The sender information is contained in three possible places: + +* ``From:`` -- the address(es) of who wrote the message (required) + +* ``Sender:`` -- the address of the single person who sent the message + (optional) + +* ``Return-Path:`` -- the address where bounces should go to (optional) + +You must always include a ``From:`` address by using ``setFrom()`` on the +message. Swift Mailer will use this as the default ``Return-Path:`` unless +otherwise specified. + +The ``Sender:`` address exists because the person who actually sent the email +may not be the person who wrote the email. It has a higher precedence than the +``From:`` address and will be used as the ``Return-Path:`` unless otherwise +specified. + +Setting the ``From:`` Address +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A ``From:`` address is required and is set with the ``setFrom()`` method of the +message. ``From:`` addresses specify who actually wrote the email, and usually who sent it. + +What most people probably don't realise is that you can have more than one +``From:`` address if more than one person wrote the email -- for example if an +email was put together by a committee. + +To set the ``From:`` address(es): + +* Call the ``setFrom()`` method on the Message. + +The ``From:`` address(es) are visible in the message headers and +will be seen by the recipients. + +.. note:: + + If you set multiple ``From:`` addresses then you absolutely must set a + ``Sender:`` address to indicate who physically sent the message. + + .. code-block:: php + + // Set a single From: address + $message->setFrom('your@address.tld'); + + // Set a From: address including a name + $message->setFrom(array('your@address.tld' => 'Your Name')); + + // Set multiple From: addresses if multiple people wrote the email + $message->setFrom(array( + 'person1@example.org' => 'Sender One', + 'person2@example.org' => 'Sender Two' + )); + +Setting the ``Sender:`` Address +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A ``Sender:`` address specifies who sent the message and is set with the +``setSender()`` method of the message. + +To set the ``Sender:`` address: + +* Call the ``setSender()`` method on the Message. + +The ``Sender:`` address is visible in the message headers and will be seen by +the recipients. + +This address will be used as the ``Return-Path:`` unless otherwise specified. + +.. note:: + + If you set multiple ``From:`` addresses then you absolutely must set a + ``Sender:`` address to indicate who physically sent the message. + +You must not set more than one sender address on a message because it's not +possible for more than one person to send a single message. + +.. code-block:: php + + $message->setSender('your@address.tld'); + +Setting the ``Return-Path:`` (Bounce) Address +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``Return-Path:`` address specifies where bounce notifications should +be sent and is set with the ``setReturnPath()`` method of the message. + +You can only have one ``Return-Path:`` and it must not include +a personal name. + +To set the ``Return-Path:`` address: + +* Call the ``setReturnPath()`` method on the Message. + +Bouce notifications will be sent to this address. + +.. code-block:: php + + $message->setReturnPath('bounces@address.tld'); + +Requesting a Read Receipt +------------------------- + +It is possible to request a read-receipt to be sent to an address when the +email is opened. To request a read receipt set the address with +``setReadReceiptTo()``. + +To request a read receipt: + +* Set the address you want the receipt to be sent to with the + ``setReadReceiptTo()`` method on the Message. + +When the email is opened, if the mail client supports it a notification will be sent to this address. + +.. note:: + + Read receipts won't work for the majority of recipients since many mail + clients auto-disable them. Those clients that will send a read receipt + will make the user aware that one has been requested. + + .. code-block:: php + + $message->setReadReceiptTo('your@address.tld'); + +Setting the Character Set +------------------------- + +The character set of the message (and it's MIME parts) is set with the +``setCharset()`` method. You can also change the global default of UTF-8 by +working with the ``Swift_Preferences`` class. + +Swift Mailer will default to the UTF-8 character set unless otherwise +overridden. UTF-8 will work in most instances since it includes all of the +standard US keyboard characters in addition to most international characters. + +It is absolutely vital however that you know what character set your message +(or it's MIME parts) are written in otherwise your message may be received +completely garbled. + +There are two places in Swift Mailer where you can change the character set: + +* In the ``Swift_Preferences`` class + +* On each individual message and/or MIME part + +To set the character set of your Message: + +* Change the global UTF-8 setting by calling + ``Swift_Preferences::setCharset()``; or + +* Call the ``setCharset()`` method on the message or the MIME part. + + .. code-block:: php + + // Approach 1: Change the global setting (suggested) + Swift_Preferences::getInstance()->setCharset('iso-8859-2'); + + // Approach 2: Call the setCharset() method of the message + $message = Swift_Message::newInstance() + ->setCharset('iso-8859-2'); + + // Apprach 3: Specify the charset when setting the body + $message->setBody('My body', 'text/html', 'iso-8859-2'); + + // Approach 4: Specify the charset for each part added + $message->addPart('My part', 'text/plain', 'iso-8859-2'); + +Setting the Line Length +----------------------- + +The length of lines in a message can be changed by using the ``setMaxLineLength()`` method on the message. It should be kept to less than +1000 characters. + +Swift Mailer defaults to using 78 characters per line in a message. This is +done for historical reasons and so that the message can be easily viewed in +plain-text terminals. + +To change the maximum length of lines in your Message: + +* Call the ``setMaxLineLength()`` method on the Message. + +Lines that are longer than the line length specified will be wrapped between +words. + +.. note:: + + You should never set a maximum length longer than 1000 characters + according to RFC 2822. Doing so could have unspecified side-effects such + as truncating parts of your message when it is transported between SMTP + servers. + + .. code-block:: php + + $message->setMaxLineLength(1000); + +Setting the Message Priority +---------------------------- + +You can change the priority of the message with ``setPriority()``. Setting the +priority will not change the way your email is sent -- it is purely an +indicative setting for the recipient. + +The priority of a message is an indication to the recipient what significance +it has. Swift Mailer allows you to set the priority by calling the ``setPriority`` method. This method takes an integer value between 1 and 5: + +* Highest +* High +* Normal +* Low +* Lowest + +To set the message priority: + +* Set the priority as an integer between 1 and 5 with the ``setPriority()`` + method on the Message. + +.. code-block:: php + + // Indicate "High" priority + $message->setPriority(2); diff --git a/vendor/swiftmailer/swiftmailer/doc/overview.rst b/vendor/swiftmailer/swiftmailer/doc/overview.rst new file mode 100644 index 0000000..c912617 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/doc/overview.rst @@ -0,0 +1,161 @@ +Library Overview +================ + +Most features (and more) of your every day mail client software are provided +by Swift Mailer, using object-oriented PHP code as the interface. + +In this chapter we will take a short tour of the various components, which put +together form the Swift Mailer library as a whole. You will learn key +terminology used throughout the rest of this book and you will gain a little +understanding of the classes you will work with as you integrate Swift Mailer +into your application. + +This chapter is intended to prepare you for the information contained in the +subsequent chapters of this book. You may choose to skip this chapter if you +are fairly technically minded, though it is likely to save you some time in +the long run if you at least read between the lines here. + +System Requirements +------------------- + +The basic requirements to operate Swift Mailer are extremely minimal and +easily achieved. Historically, Swift Mailer has supported both PHP 4 and PHP 5 +by following a parallel development workflow. Now in it's fourth major +version, and Swift Mailer operates on servers running PHP 5.2 or higher. + +The library aims to work with as many PHP 5 projects as possible: + +* PHP 5.2 or higher, with the SPL extension (standard) + +* Limited network access to connect to remote SMTP servers + +* 8 MB or more memory limit (Swift Mailer uses around 2 MB) + +Component Breakdown +------------------- + +Swift Mailer is made up of many classes. Each of these classes can be grouped +into a general "component" group which describes the task it is designed to +perform. + +We'll take a brief look at the components which form Swift Mailer in this +section of the book. + +The Mailer +~~~~~~~~~~ + +The mailer class, ``Swift_Mailer`` is the central class in the library where +all of the other components meet one another. ``Swift_Mailer`` acts as a sort +of message dispatcher, communicating with the underlying Transport to deliver +your Message to all intended recipients. + +If you were to dig around in the source code for Swift Mailer you'd notice +that ``Swift_Mailer`` itself is pretty bare. It delegates to other objects for +most tasks and in theory, if you knew the internals of Swift Mailer well you +could by-pass this class entirely. We wouldn't advise doing such a thing +however -- there are reasons this class exists: + +* for consistency, regardless of the Transport used + +* to provide abstraction from the internals in the event internal API changes + are made + +* to provide convenience wrappers around aspects of the internal API + +An instance of ``Swift_Mailer`` is created by the developer before sending any +Messages. + +Transports +~~~~~~~~~~ + +Transports are the classes in Swift Mailer that are responsible for +communicating with a service in order to deliver a Message. There are several +types of Transport in Swift Mailer, all of which implement the Swift_Transport +interface and offer underlying start(), stop() and send() methods. + +Typically you will not need to know how a Transport works under-the-surface, +you will only need to know how to create an instance of one, and which one to +use for your environment. + ++---------------------------------+---------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+ +| Class | Features | Pros/cons | ++=================================+=============================================================================================+===============================================================================================================================================+ +| ``Swift_SmtpTransport`` | Sends messages over SMTP; Supports Authentication; Supports Encryption | Very portable; Pleasingly predictable results; Provides good feedback | ++---------------------------------+---------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+ +| ``Swift_SendmailTransport`` | Communicates with a locally installed ``sendmail`` executable (Linux/UNIX) | Quick time-to-run; Provides less-accurate feedback than SMTP; Requires ``sendmail`` installation | ++---------------------------------+---------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+ +| ``Swift_MailTransport`` | Uses PHP's built-in ``mail()`` function | Very portable; Potentially unpredictable results; Provides extremely weak feedback | ++---------------------------------+---------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+ +| ``Swift_LoadBalancedTransport`` | Cycles through a collection of the other Transports to manage load-reduction | Provides graceful fallback if one Transport fails (e.g. an SMTP server is down); Keeps the load on remote services down by spreading the work | ++---------------------------------+---------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+ +| ``Swift_FailoverTransport`` | Works in conjunction with a collection of the other Transports to provide high-availability | Provides graceful fallback if one Transport fails (e.g. an SMTP server is down) | ++---------------------------------+---------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+ + +MIME Entities +~~~~~~~~~~~~~ + +Everything that forms part of a Message is called a MIME Entity. All MIME +entities in Swift Mailer share a common set of features. There are various +types of MIME entity that serve different purposes such as Attachments and +MIME parts. + +An e-mail message is made up of several relatively simple entities that are +combined in different ways to achieve different results. All of these entities +have the same fundamental outline but serve a different purpose. The Message +itself can be defined as a MIME entity, an Attachment is a MIME entity, all +MIME parts are MIME entities -- and so on! + +The basic units of each MIME entity -- be it the Message itself, or an +Attachment -- are its Headers and its body: + +.. code-block:: text + + Other-Header: Another value + + The body content itself + +The Headers of a MIME entity, and its body must conform to some strict +standards defined by various RFC documents. Swift Mailer ensures that these +specifications are followed by using various types of object, including +Encoders and different Header types to generate the entity. + +Each MIME component implements the base ``Swift_Mime_MimeEntity`` interface, +which offers methods for retrieving Headers, adding new Headers, changing the +Encoder, updating the body and so on! + +All MIME entities have one Header in common -- the Content-Type Header, +updated with the entity's ``setContentType()`` method. + +Encoders +~~~~~~~~ + +Encoders are used to transform the content of Messages generated in Swift +Mailer into a format that is safe to send across the internet and that +conforms to RFC specifications. + +Generally speaking you will not need to interact with the Encoders in Swift +Mailer -- the correct settings will be handled by the library itself. +However they are probably worth a brief mention in the event that you do want +to play with them. + +Both the Headers and the body of all MIME entities (including the Message +itself) use Encoders to ensure the data they contain can be sent over the +internet without becoming corrupted or misinterpreted. + +There are two types of Encoder: Base64 and Quoted-Printable. + +Plugins +~~~~~~~ + +Plugins exist to extend, or modify the behaviour of Swift Mailer. They respond +to Events that are fired within the Transports during sending. + +There are a number of Plugins provided as part of the base Swift Mailer +package and they all follow a common interface to respond to Events fired +within the library. Interfaces are provided to "listen" to each type of Event +fired and to act as desired when a listened-to Event occurs. + +Although several plugins are provided with Swift Mailer out-of-the-box, the +Events system has been specifically designed to make it easy for experienced +object-oriented developers to write their own plugins in order to achieve +goals that may not be possible with the base library. diff --git a/vendor/swiftmailer/swiftmailer/doc/plugins.rst b/vendor/swiftmailer/swiftmailer/doc/plugins.rst new file mode 100644 index 0000000..e423476 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/doc/plugins.rst @@ -0,0 +1,385 @@ +Plugins +======= + +Plugins are provided with Swift Mailer and can be used to extend the behavior +of the library in ways that simple class inheritance would be more complex. + +AntiFlood Plugin +---------------- + +Many SMTP servers have limits on the number of messages that may be sent +during any single SMTP connection. The AntiFlood plugin provides a way to stay +within this limit while still managing a large number of emails. + +A typical limit for a single connection is 100 emails. If the server you +connect to imposes such a limit, it expects you to disconnect after that +number of emails has been sent. You could manage this manually within a loop, +but the AntiFlood plugin provides the necessary wrapper code so that you don't +need to worry about this logic. + +Regardless of limits imposed by the server, it's usually a good idea to be +conservative with the resources of the SMTP server. Sending will become +sluggish if the server is being over-used so using the AntiFlood plugin will +not be a bad idea even if no limits exist. + +The AntiFlood plugin's logic is basically to disconnect and the immediately +re-connect with the SMTP server every X number of emails sent, where X is a +number you specify to the plugin. + +You can also specify a time period in seconds that Swift Mailer should pause +for between the disconnect/re-connect process. It's a good idea to pause for a +short time (say 30 seconds every 100 emails) simply to give the SMTP server a +chance to process its queue and recover some resources. + +Using the AntiFlood Plugin +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The AntiFlood Plugin -- like all plugins -- is added with the Mailer class' +``registerPlugin()`` method. It takes two constructor parameters: the number of +emails to pause after, and optionally the number of seconds to pause for. + +To use the AntiFlood plugin: + +* Create an instance of the Mailer using any Transport you choose. + +* Create an instance of the ``Swift_Plugins_AntiFloodPlugin`` class, passing + in one or two constructor parameters. + +* Register the plugin using the Mailer's ``registerPlugin()`` method. + +* Continue using Swift Mailer to send messages as normal. + +When Swift Mailer sends messages it will count the number of messages that +have been sent since the last re-connect. Once the number hits your specified +threshold it will disconnect and re-connect, optionally pausing for a +specified amount of time. + +.. code-block:: php + + require_once 'lib/swift_required.php'; + + // Create the Mailer using any Transport + $mailer = Swift_Mailer::newInstance( + Swift_SmtpTransport::newInstance('smtp.example.org', 25) + ); + + // Use AntiFlood to re-connect after 100 emails + $mailer->registerPlugin(new Swift_Plugins_AntiFloodPlugin(100)); + + // And specify a time in seconds to pause for (30 secs) + $mailer->registerPlugin(new Swift_Plugins_AntiFloodPlugin(100, 30)); + + // Continue sending as normal + for ($lotsOfRecipients as $recipient) { + ... + + $mailer->send( ... ); + } + +Throttler Plugin +---------------- + +If your SMTP server has restrictions in place to limit the rate at which you +send emails, then your code will need to be aware of this rate-limiting. The +Throttler plugin makes Swift Mailer run at a rate-limited speed. + +Many shared hosts don't open their SMTP servers as a free-for-all. Usually +they have policies in place (probably to discourage spammers) that only allow +you to send a fixed number of emails per-hour/day. + +The Throttler plugin supports two modes of rate-limiting and with each, you +will need to do that math to figure out the values you want. The plugin can +limit based on the number of emails per minute, or the number of +bytes-transferred per-minute. + +Using the Throttler Plugin +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Throttler Plugin -- like all plugins -- is added with the Mailer class' +``registerPlugin()`` method. It has two required constructor parameters that +tell it how to do its rate-limiting. + +To use the Throttler plugin: + +* Create an instance of the Mailer using any Transport you choose. + +* Create an instance of the ``Swift_Plugins_ThrottlerPlugin`` class, passing + the number of emails, or bytes you wish to limit by, along with the mode + you're using. + +* Register the plugin using the Mailer's ``registerPlugin()`` method. + +* Continue using Swift Mailer to send messages as normal. + +When Swift Mailer sends messages it will keep track of the rate at which sending +messages is occurring. If it realises that sending is happening too fast, it +will cause your program to ``sleep()`` for enough time to average out the rate. + +.. code-block:: php + + require_once 'lib/swift_required.php'; + + // Create the Mailer using any Transport + $mailer = Swift_Mailer::newInstance( + Swift_SmtpTransport::newInstance('smtp.example.org', 25) + ); + + // Rate limit to 100 emails per-minute + $mailer->registerPlugin(new Swift_Plugins_ThrottlerPlugin( + 100, Swift_Plugins_ThrottlerPlugin::MESSAGES_PER_MINUTE + )); + + // Rate limit to 10MB per-minute + $mailer->registerPlugin(new Swift_Plugins_ThrottlerPlugin( + 1024 * 1024 * 10, Swift_Plugins_ThrottlerPlugin::BYTES_PER_MINUTE + )); + + // Continue sending as normal + for ($lotsOfRecipients as $recipient) { + ... + + $mailer->send( ... ); + } + +Logger Plugin +------------- + +The Logger plugins helps with debugging during the process of sending. It can +help to identify why an SMTP server is rejecting addresses, or any other +hard-to-find problems that may arise. + +The Logger plugin comes in two parts. There's the plugin itself, along with +one of a number of possible Loggers that you may choose to use. For example, +the logger may output messages directly in realtime, or it may capture +messages in an array. + +One other notable feature is the way in which the Logger plugin changes +Exception messages. If Exceptions are being thrown but the error message does +not provide conclusive information as to the source of the problem (such as an +ambiguous SMTP error) the Logger plugin includes the entire SMTP transcript in +the error message so that debugging becomes a simpler task. + +There are a few available Loggers included with Swift Mailer, but writing your +own implementation is incredibly simple and is achieved by creating a short +class that implements the ``Swift_Plugins_Logger`` interface. + +* ``Swift_Plugins_Loggers_ArrayLogger``: Keeps a collection of log messages + inside an array. The array content can be cleared or dumped out to the + screen. + +* ``Swift_Plugins_Loggers_EchoLogger``: Prints output to the screen in + realtime. Handy for very rudimentary debug output. + +Using the Logger Plugin +~~~~~~~~~~~~~~~~~~~~~~~ + +The Logger Plugin -- like all plugins -- is added with the Mailer class' +``registerPlugin()`` method. It accepts an instance of ``Swift_Plugins_Logger`` +in its constructor. + +To use the Logger plugin: + +* Create an instance of the Mailer using any Transport you choose. + +* Create an instance of the a Logger implementation of + ``Swift_Plugins_Logger``. + +* Create an instance of the ``Swift_Plugins_LoggerPlugin`` class, passing the + created Logger instance to its constructor. + +* Register the plugin using the Mailer's ``registerPlugin()`` method. + +* Continue using Swift Mailer to send messages as normal. + +* Dump the contents of the log with the logger's ``dump()`` method. + +When Swift Mailer sends messages it will keep a log of all the interactions +with the underlying Transport being used. Depending upon the Logger that has +been used the behaviour will differ, but all implementations offer a way to +get the contents of the log. + +.. code-block:: php + + require_once 'lib/swift_required.php'; + + // Create the Mailer using any Transport + $mailer = Swift_Mailer::newInstance( + Swift_SmtpTransport::newInstance('smtp.example.org', 25) + ); + + // To use the ArrayLogger + $logger = new Swift_Plugins_Loggers_ArrayLogger(); + $mailer->registerPlugin(new Swift_Plugins_LoggerPlugin($logger)); + + // Or to use the Echo Logger + $logger = new Swift_Plugins_Loggers_EchoLogger(); + $mailer->registerPlugin(new Swift_Plugins_LoggerPlugin($logger)); + + // Continue sending as normal + for ($lotsOfRecipients as $recipient) { + ... + + $mailer->send( ... ); + } + + // Dump the log contents + // NOTE: The EchoLogger dumps in realtime so dump() does nothing for it + echo $logger->dump(); + +Decorator Plugin +---------------- + +Often there's a need to send the same message to multiple recipients, but with +tiny variations such as the recipient's name being used inside the message +body. The Decorator plugin aims to provide a solution for allowing these small +differences. + +The decorator plugin works by intercepting the sending process of Swift +Mailer, reading the email address in the To: field and then looking up a set +of replacements for a template. + +While the use of this plugin is simple, it is probably the most commonly +misunderstood plugin due to the way in which it works. The typical mistake +users make is to try registering the plugin multiple times (once for each +recipient) -- inside a loop for example. This is incorrect. + +The Decorator plugin should be registered just once, but containing the list +of all recipients prior to sending. It will use this list of recipients to +find the required replacements during sending. + +Using the Decorator Plugin +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To use the Decorator plugin, simply create an associative array of replacements +based on email addresses and then use the mailer's ``registerPlugin()`` method +to add the plugin. + +First create an associative array of replacements based on the email addresses +you'll be sending the message to. + +.. note:: + + The replacements array becomes a 2-dimensional array whose keys are the + email addresses and whose values are an associative array of replacements + for that email address. The curly braces used in this example can be any + type of syntax you choose, provided they match the placeholders in your + email template. + + .. code-block:: php + + $replacements = array(); + foreach ($users as $user) { + $replacements[$user['email']] = array( + '{username}'=>$user['username'], + '{password}'=>$user['password'] + ); + } + +Now create an instance of the Decorator plugin using this array of replacements +and then register it with the Mailer. Do this only once! + +.. code-block:: php + + $decorator = new Swift_Plugins_DecoratorPlugin($replacements); + + $mailer->registerPlugin($decorator); + +When you create your message, replace elements in the body (and/or the subject +line) with your placeholders. + +.. code-block:: php + + $message = Swift_Message::newInstance() + ->setSubject('Important notice for {username}') + ->setBody( + "Hello {username}, we have reset your password to {password}\n" . + "Please log in and change it at your earliest convenience." + ) + ; + + foreach ($users as $user) { + $message->addTo($user['email']); + } + +When you send this message to each of your recipients listed in your +``$replacements`` array they will receive a message customized for just +themselves. For example, the message used above when received may appear like +this to one user: + +.. code-block:: text + + Subject: Important notice for smilingsunshine2009 + + Hello smilingsunshine2009, we have reset your password to rainyDays + Please log in and change it at your earliest convenience. + +While another use may receive the message as: + +.. code-block:: text + + Subject: Important notice for billy-bo-bob + + Hello billy-bo-bob, we have reset your password to dancingOctopus + Please log in and change it at your earliest convenience. + +While the decorator plugin provides a means to solve this problem, there are +various ways you could tackle this problem without the need for a plugin. +We're trying to come up with a better way ourselves and while we have several +(obvious) ideas we don't quite have the perfect solution to go ahead and +implement it. Watch this space. + +Providing Your Own Replacements Lookup for the Decorator +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Filling an array with replacements may not be the best solution for providing +replacement information to the decorator. If you have a more elegant algorithm +that performs replacement lookups on-the-fly you may provide your own +implementation. + +Providing your own replacements lookup implementation for the Decorator is +simply a matter of passing an instance of ``Swift_Plugins_Decorator_Replacements`` to the decorator plugin's constructor, +rather than passing in an array. + +The Replacements interface is very simple to implement since it has just one +method: ``getReplacementsFor($address)``. + +Imagine you want to look up replacements from a database on-the-fly, you might +provide an implementation that does this. You need to create a small class. + +.. code-block:: php + + class DbReplacements implements Swift_Plugins_Decorator_Replacements { + public function getReplacementsFor($address) { + $sql = sprintf( + "SELECT * FROM user WHERE email = '%s'", + mysql_real_escape_string($address) + ); + + $result = mysql_query($sql); + + if ($row = mysql_fetch_assoc($result)) { + return array( + '{username}'=>$row['username'], + '{password}'=>$row['password'] + ); + } + } + } + +Now all you need to do is pass an instance of your class into the Decorator +plugin's constructor instead of passing an array. + +.. code-block:: php + + $decorator = new Swift_Plugins_DecoratorPlugin(new DbReplacements()); + + $mailer->registerPlugin($decorator); + +For each message sent, the plugin will call your class' ``getReplacementsFor()`` +method to find the array of replacements it needs. + +.. note:: + + If your lookup algorithm is case sensitive, you should transform the + ``$address`` argument as appropriate -- for example by passing it + through ``strtolower()``. diff --git a/vendor/swiftmailer/swiftmailer/doc/sending.rst b/vendor/swiftmailer/swiftmailer/doc/sending.rst new file mode 100644 index 0000000..29bf05e --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/doc/sending.rst @@ -0,0 +1,592 @@ +Sending Messages +================ + +Quick Reference for Sending a Message +------------------------------------- + +Sending a message is very straightforward. You create a Transport, use it to +create the Mailer, then you use the Mailer to send the message. + +To send a Message: + +* Create a Transport from one of the provided Transports -- + ``Swift_SmtpTransport``, ``Swift_SendmailTransport``, ``Swift_MailTransport`` + or one of the aggregate Transports. + +* Create an instance of the ``Swift_Mailer`` class, using the Transport as + it's constructor parameter. + +* Create a Message. + +* Send the message via the ``send()`` method on the Mailer object. + +.. caution:: + + The ``Swift_SmtpTransport`` and ``Swift_SendmailTransport`` transports use + ``proc_*`` PHP functions, which might not be available on your PHP + installation. You can easily check if that the case by running the + following PHP script: ``setUsername('your username') + ->setPassword('your password') + ; + + /* + You could alternatively use a different transport such as Sendmail or Mail: + + // Sendmail + $transport = Swift_SendmailTransport::newInstance('/usr/sbin/sendmail -bs'); + + // Mail + $transport = Swift_MailTransport::newInstance(); + */ + + // Create the Mailer using your created Transport + $mailer = Swift_Mailer::newInstance($transport); + + // Create a message + $message = Swift_Message::newInstance('Wonderful Subject') + ->setFrom(array('john@doe.com' => 'John Doe')) + ->setTo(array('receiver@domain.org', 'other@domain.org' => 'A name')) + ->setBody('Here is the message itself') + ; + + // Send the message + $result = $mailer->send($message); + +Transport Types +~~~~~~~~~~~~~~~ + +A Transport is the component which actually does the sending. You need to +provide a Transport object to the Mailer class and there are several possible +options. + +Typically you will not need to know how a Transport works under-the-surface, +you will only need to know how to create an instance of one, and which one to +use for your environment. + +The SMTP Transport +.................. + +The SMTP Transport sends messages over the (standardized) Simple Message +Transfer Protocol. It can deal with encryption and authentication. + +The SMTP Transport, ``Swift_SmtpTransport`` is without doubt the most commonly +used Transport because it will work on 99% of web servers (I just made that +number up, but you get the idea). All the server needs is the ability to +connect to a remote (or even local) SMTP server on the correct port number +(usually 25). + +SMTP servers often require users to authenticate with a username and password +before any mail can be sent to other domains. This is easily achieved using +Swift Mailer with the SMTP Transport. + +SMTP is a protocol -- in other words it's a "way" of communicating a job +to be done (i.e. sending a message). The SMTP protocol is the fundamental +basis on which messages are delivered all over the internet 7 days a week, 365 +days a year. For this reason it's the most "direct" method of sending messages +you can use and it's the one that will give you the most power and feedback +(such as delivery failures) when using Swift Mailer. + +Because SMTP is generally run as a remote service (i.e. you connect to it over +the network/internet) it's extremely portable from server-to-server. You can +easily store the SMTP server address and port number in a configuration file +within your application and adjust the settings accordingly if the code is +moved or if the SMTP server is changed. + +Some SMTP servers -- Google for example -- use encryption for security reasons. +Swift Mailer supports using both SSL and TLS encryption settings. + +Using the SMTP Transport +^^^^^^^^^^^^^^^^^^^^^^^^ + +The SMTP Transport is easy to use. Most configuration options can be set with +the constructor. + +To use the SMTP Transport you need to know which SMTP server your code needs +to connect to. Ask your web host if you're not sure. Lots of people ask me who +to connect to -- I really can't answer that since it's a setting that's +extremely specific to your hosting environment. + +To use the SMTP Transport: + +* Call ``Swift_SmtpTransport::newInstance()`` with the SMTP server name and + optionally with a port number (defaults to 25). + +* Use the returned object to create the Mailer. + +A connection to the SMTP server will be established upon the first call to +``send()``. + +.. code-block:: php + + require_once 'lib/swift_required.php'; + + // Create the Transport + $transport = Swift_SmtpTransport::newInstance('smtp.example.org', 25); + + // Create the Mailer using your created Transport + $mailer = Swift_Mailer::newInstance($transport); + + /* + It's also possible to use multiple method calls + + $transport = Swift_SmtpTransport::newInstance() + ->setHost('smtp.example.org') + ->setPort(25) + ; + */ + +Encrypted SMTP +^^^^^^^^^^^^^^ + +You can use SSL or TLS encryption with the SMTP Transport by specifying it as +a parameter or with a method call. + +To use encryption with the SMTP Transport: + +* Pass the encryption setting as a third parameter to + ``Swift_SmtpTransport::newInstance()``; or + +* Call the ``setEncryption()`` method on the Transport. + +A connection to the SMTP server will be established upon the first call to +``send()``. The connection will be initiated with the correct encryption +settings. + +.. note:: + + For SSL or TLS encryption to work your PHP installation must have + appropriate OpenSSL transports wrappers. You can check if "tls" and/or + "ssl" are present in your PHP installation by using the PHP function + ``stream_get_transports()`` + + .. code-block:: php + + require_once 'lib/swift_required.php'; + + // Create the Transport + $transport = Swift_SmtpTransport::newInstance('smtp.example.org', 587, 'ssl'); + + // Create the Mailer using your created Transport + $mailer = Swift_Mailer::newInstance($transport); + + /* + It's also possible to use multiple method calls + + $transport = Swift_SmtpTransport::newInstance() + ->setHost('smtp.example.org') + ->setPort(587) + ->setEncryption('ssl') + ; + */ + +SMTP with a Username and Password +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Some servers require authentication. You can provide a username and password +with ``setUsername()`` and ``setPassword()`` methods. + +To use a username and password with the SMTP Transport: + +* Create the Transport with ``Swift_SmtpTransport::newInstance()``. + +* Call the ``setUsername()`` and ``setPassword()`` methods on the Transport. + +Your username and password will be used to authenticate upon first connect +when ``send()`` are first used on the Mailer. + +If authentication fails, an Exception of type ``Swift_TransportException`` will +be thrown. + +.. note:: + + If you need to know early whether or not authentication has failed and an + Exception is going to be thrown, call the ``start()`` method on the + created Transport. + + .. code-block:: php + + require_once 'lib/swift_required.php'; + + // Create the Transport the call setUsername() and setPassword() + $transport = Swift_SmtpTransport::newInstance('smtp.example.org', 25) + ->setUsername('username') + ->setPassword('password') + ; + + // Create the Mailer using your created Transport + $mailer = Swift_Mailer::newInstance($transport); + +The Sendmail Transport +...................... + +The Sendmail Transport sends messages by communicating with a locally +installed MTA -- such as ``sendmail``. + +The Sendmail Transport, ``Swift_SendmailTransport`` does not directly connect to +any remote services. It is designed for Linux servers that have ``sendmail`` +installed. The Transport starts a local ``sendmail`` process and sends messages +to it. Usually the ``sendmail`` process will respond quickly as it spools your +messages to disk before sending them. + +The Transport is named the Sendmail Transport for historical reasons +(``sendmail`` was the "standard" UNIX tool for sending e-mail for years). It +will send messages using other transfer agents such as Exim or Postfix despite +its name, provided they have the relevant sendmail wrappers so that they can be +started with the correct command-line flags. + +It's a common misconception that because the Sendmail Transport returns a +result very quickly it must therefore deliver messages to recipients quickly +-- this is not true. It's not slow by any means, but it's certainly not +faster than SMTP when it comes to getting messages to the intended recipients. +This is because sendmail itself sends the messages over SMTP once they have +been quickly spooled to disk. + +The Sendmail Transport has the potential to be just as smart of the SMTP +Transport when it comes to notifying Swift Mailer about which recipients were +rejected, but in reality the majority of locally installed ``sendmail`` +instances are not configured well enough to provide any useful feedback. As such +Swift Mailer may report successful deliveries where they did in fact fail before +they even left your server. + +You can run the Sendmail Transport in two different modes specified by command +line flags: + +* "``-bs``" runs in SMTP mode so theoretically it will act like the SMTP + Transport + +* "``-t``" runs in piped mode with no feedback, but theoretically faster, + though not advised + +You can think of the Sendmail Transport as a sort of asynchronous SMTP Transport +-- though if you have problems with delivery failures you should try using the +SMTP Transport instead. Swift Mailer isn't doing the work here, it's simply +passing the work to somebody else (i.e. ``sendmail``). + +Using the Sendmail Transport +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To use the Sendmail Transport you simply need to call +``Swift_SendmailTransport::newInstance()`` with the command as a parameter. + +To use the Sendmail Transport you need to know where ``sendmail`` or another MTA +exists on the server. Swift Mailer uses a default value of +``/usr/sbin/sendmail``, which should work on most systems. + +You specify the entire command as a parameter (i.e. including the command line +flags). Swift Mailer supports operational modes of "``-bs``" (default) and +"``-t``". + +.. note:: + + If you run sendmail in "``-t``" mode you will get no feedback as to whether + or not sending has succeeded. Use "``-bs``" unless you have a reason not to. + +To use the Sendmail Transport: + +* Call ``Swift_SendmailTransport::newInstance()`` with the command, including + the correct command line flags. The default is to use ``/usr/sbin/sendmail + -bs`` if this is not specified. + +* Use the returned object to create the Mailer. + +A sendmail process will be started upon the first call to ``send()``. If the +process cannot be started successfully an Exception of type +``Swift_TransportException`` will be thrown. + +.. code-block:: php + + require_once 'lib/swift_required.php'; + + // Create the Transport + $transport = Swift_SendmailTransport::newInstance('/usr/sbin/exim -bs'); + + // Create the Mailer using your created Transport + $mailer = Swift_Mailer::newInstance($transport); + +The Mail Transport +.................. + +The Mail Transport sends messages by delegating to PHP's internal +``mail()`` function. + +In my experience -- and others' -- the ``mail()`` function is not particularly +predictable, or helpful. + +Quite notably, the ``mail()`` function behaves entirely differently between +Linux and Windows servers. On linux it uses ``sendmail``, but on Windows it uses +SMTP. + +In order for the ``mail()`` function to even work at all ``php.ini`` needs to be +configured correctly, specifying the location of sendmail or of an SMTP server. + +The problem with ``mail()`` is that it "tries" to simplify things to the point +that it actually makes things more complex due to poor interface design. The +developers of Swift Mailer have gone to a lot of effort to make the Mail +Transport work with a reasonable degree of consistency. + +Serious drawbacks when using this Transport are: + +* Unpredictable message headers + +* Lack of feedback regarding delivery failures + +* Lack of support for several plugins that require real-time delivery feedback + +It's a last resort, and we say that with a passion! + +Using the Mail Transport +^^^^^^^^^^^^^^^^^^^^^^^^ + +To use the Mail Transport you simply need to call +``Swift_MailTransport::newInstance()``. It's unlikely you'll need to configure +the Transport. + +To use the Mail Transport: + +* Call ``Swift_MailTransport::newInstance()``. + +* Use the returned object to create the Mailer. + +Messages will be sent using the ``mail()`` function. + +.. note:: + + The ``mail()`` function can take a ``$additional_parameters`` parameter. + Swift Mailer sets this to "``-f%s``" by default, where the "%s" is + substituted with the address of the sender (via a ``sprintf()``) at send + time. You may override this default by passing an argument to + ``newInstance()``. + + .. code-block:: php + + require_once 'lib/swift_required.php'; + + // Create the Transport + $transport = Swift_MailTransport::newInstance(); + + // Create the Mailer using your created Transport + $mailer = Swift_Mailer::newInstance($transport); + +Available Methods for Sending Messages +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Mailer class offers two methods for sending Messages -- ``send()``. +Each behaves in a slightly different way. + +When a message is sent in Swift Mailer, the Mailer class communicates with +whichever Transport class you have chosen to use. + +Each recipient in the message should either be accepted or rejected by the +Transport. For example, if the domain name on the email address is not +reachable the SMTP Transport may reject the address because it cannot process +it. Whichever method you use -- ``send()`` -- Swift Mailer will return +an integer indicating the number of accepted recipients. + +.. note:: + + It's possible to find out which recipients were rejected -- we'll cover that + later in this chapter. + +Using the ``send()`` Method +........................... + +The ``send()`` method of the ``Swift_Mailer`` class sends a message using +exactly the same logic as your Desktop mail client would use. Just pass it a +Message and get a result. + +To send a Message with ``send()``: + +* Create a Transport from one of the provided Transports -- + ``Swift_SmtpTransport``, ``Swift_SendmailTransport``, + ``Swift_MailTransport`` or one of the aggregate Transports. + +* Create an instance of the ``Swift_Mailer`` class, using the Transport as + it's constructor parameter. + +* Create a Message. + +* Send the message via the ``send()`` method on the Mailer object. + +The message will be sent just like it would be sent if you used your mail +client. An integer is returned which includes the number of successful +recipients. If none of the recipients could be sent to then zero will be +returned, which equates to a boolean ``false``. If you set two +``To:`` recipients and three ``Bcc:`` recipients in the message and all of the +recipients are delivered to successfully then the value 5 will be returned. + +.. code-block:: php + + require_once 'lib/swift_required.php'; + + // Create the Transport + $transport = Swift_SmtpTransport::newInstance('localhost', 25); + + // Create the Mailer using your created Transport + $mailer = Swift_Mailer::newInstance($transport); + + // Create a message + $message = Swift_Message::newInstance('Wonderful Subject') + ->setFrom(array('john@doe.com' => 'John Doe')) + ->setTo(array('receiver@domain.org', 'other@domain.org' => 'A name')) + ->setBody('Here is the message itself') + ; + + // Send the message + $numSent = $mailer->send($message); + + printf("Sent %d messages\n", $numSent); + + /* Note that often that only the boolean equivalent of the + return value is of concern (zero indicates FALSE) + + if ($mailer->send($message)) + { + echo "Sent\n"; + } + else + { + echo "Failed\n"; + } + + */ + +Sending Emails in Batch +....................... + +If you want to send a separate message to each recipient so that only their +own address shows up in the ``To:`` field, follow the following recipe: + +* Create a Transport from one of the provided Transports -- + ``Swift_SmtpTransport``, ``Swift_SendmailTransport``, + ``Swift_MailTransport`` or one of the aggregate Transports. + +* Create an instance of the ``Swift_Mailer`` class, using the Transport as + it's constructor parameter. + +* Create a Message. + +* Iterate over the recipients and send message via the ``send()`` method on + the Mailer object. + +Each recipient of the messages receives a different copy with only their own +email address on the ``To:`` field. + +.. note:: + + In the following example, two emails are sent. One to each of + ``receiver@domain.org`` and ``other@domain.org``. These recipients will + not be aware of each other. + + .. code-block:: php + + require_once 'lib/swift_required.php'; + + // Create the Transport + $transport = Swift_SmtpTransport::newInstance('localhost', 25); + + // Create the Mailer using your created Transport + $mailer = Swift_Mailer::newInstance($transport); + + // Create a message + $message = Swift_Message::newInstance('Wonderful Subject') + ->setFrom(array('john@doe.com' => 'John Doe')) + ->setBody('Here is the message itself') + ; + + // Send the message + $failedRecipients = array(); + $numSent = 0; + $to = array('receiver@domain.org', 'other@domain.org' => 'A name'); + + foreach ($to as $address => $name) + { + if (is_int($address)) { + $message->setTo($name); + } else { + $message->setTo(array($address => $name)); + } + + $numSent += $mailer->send($message, $failedRecipients); + } + + printf("Sent %d messages\n", $numSent); + +Finding out Rejected Addresses +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +It's possible to get a list of addresses that were rejected by the Transport +by using a by-reference parameter to ``send()``. + +As Swift Mailer attempts to send the message to each address given to it, if a +recipient is rejected it will be added to the array. You can pass an existing +array, otherwise one will be created by-reference. + +Collecting the list of recipients that were rejected can be useful in +circumstances where you need to "prune" a mailing list for example when some +addresses cannot be delivered to. + +Getting Failures By-reference +............................. + +Collecting delivery failures by-reference with the ``send()`` method is as +simple as passing a variable name to the method call. + +To get failed recipients by-reference: + +* Pass a by-reference variable name to the ``send()`` method of the Mailer + class. + +If the Transport rejects any of the recipients, the culprit addresses will be +added to the array provided by-reference. + +.. note:: + + If the variable name does not yet exist, it will be initialized as an + empty array and then failures will be added to that array. If the variable + already exists it will be type-cast to an array and failures will be added + to it. + + .. code-block:: php + + $mailer = Swift_Mailer::newInstance( ... ); + + $message = Swift_Message::newInstance( ... ) + ->setFrom( ... ) + ->setTo(array( + 'receiver@bad-domain.org' => 'Receiver Name', + 'other@domain.org' => 'A name', + 'other-receiver@bad-domain.org' => 'Other Name' + )) + ->setBody( ... ) + ; + + // Pass a variable name to the send() method + if (!$mailer->send($message, $failures)) + { + echo "Failures:"; + print_r($failures); + } + + /* + Failures: + Array ( + 0 => receiver@bad-domain.org, + 1 => other-receiver@bad-domain.org + ) + */ diff --git a/vendor/swiftmailer/swiftmailer/doc/uml/Encoders.graffle b/vendor/swiftmailer/swiftmailer/doc/uml/Encoders.graffle new file mode 100644 index 0000000000000000000000000000000000000000..f895752b70947592db74b6a3b8a6bd135a9fd150 GIT binary patch literal 3503 zcmV;g4N&qQiwFP!000030PS6EQ`@)}{tUmumk&GLSx6-LC3cr~Cj@BOOAAXvd$*G> z#!(V4j-A>HA=~MHzmo0vRW^_oh=XTJ?O5mN_0gjv>B!#y<91>RH`w(|$9}T|8(>Gk zw&4s+d-P`KvUj|v?)>p~d;dR&XPw^P=SRZSGCd-kUml#EbcCI~X0tt=TDaLf>>Uc{ zrzhQ>K;vjOk3Q}QJ7Yqouba*JeBRKRRKsv4OwendyUrB5WN}I(+oKAN0U7MjWP;dJ z*`ZGdra|6rZ|z^>#oM+)%o}{FFR*)J5Af}NlRc$@rcLk&yKljMb9uW|p=q0jPH2>$ zf|w&E-F0<#v$gLLmlpXg&0)it*yhM}X4A$Qy?f{C!=Z&~j`y3PP(mIetpVjk$bNGf zXOQ-cIPJkdGmk`R5_g81%kYkF-{@Y)u^cxN2#XsC%$JYjBvYv+>n4co%r!@5T*OfJ z8`u@V_oQm9(KU1nM+z?1EtZIXUCKGuY+|=9b7bc#9Of!KknT=(gC>=ZS5z_)(;uv1 z4t0XFSw;Y~_8_AF1O#6L>9q`n-yj4aR|*zMq5{Lv&e%0Qq2st$3p=ZFXnIpiU!+UE ztYE>I2yX;-$*NH>Ovi_gF`HnUWWlto1vytCzM5%x4DKB4EgL*6jiq~D)ap^LPE8w! z@g#v5=)A}JAfXaP7=)f2#$kzeL#dYAiowKDi?tLfqs2td9r`Gl>8NmV0lp~;YN&E+ zS3oV)kiVx&5ld-+2JQ+X&>BF6X{oq#h3R(5B5uEY!Ktcqjgy6s1>%ZpyRI`&2t|46 z64SU2Lz8(8R9S=c7E_$k zRgnlKRooR+P=vuC96}`v(vyWLhgXIFcpWnyON49dQNL z$~ZsQ3Bj&i6Z0oBv5EQ%;+ zHqGN{xvWvpqS?AUaAx+vSU{X4H#Guccu##o=?0T273 z=CMh7_?GZ=KVg?PrEYQ6EPe}KV9)%QYty9KB-tkvF7fyo=ciy$yJ=)`6UiVuUEP7m z(6p?iL|PaM_U6{!WXeL98r zs9TQpLAug;SwD33xyMiW<5_7c=^uV4%K{^pr>sO=%Dzj6u&>*m>HlX;M|1>5eZw&v zod#)=7TkNYEBX_)!1lNP(6I@*vid{NA9{1s^ZG+$th*j2KzNU>8_eMN`*$j7u%%%t z`g`BS10>7+k&Cg-Zmz5urdKM}pX%<)DU|1zQv=wE-kLyMpr z^zj8{P3#`id&gbmx-qx*&n+4iTUF)u9gsD<6LGA-GnyFj43svHXIeGSRF-E_do1Oh z;6*c&)&FYiWajEtKv6M4jW7xM$8leE{i+bcBK#`67BVFD$n2D}NZ+~U;C+F?RBS1f zbnYOAW>IR?aO*g>O}lvBw)^|2d++sw^ekXatw>rs+OD7|jNPHy+DvvAYj&@#$f{eB z@34(s(>OM7@!+#LAmis^9oOob7x$8qamS zqHb5Vbe!r=**s)A+e_+daYwtrbPj2If<2pDVOMa5!qtLcPauv!+=W0nnR&uCgf_ip zlERHnv&rQC#jYbvFs&kijIlq%^rw}A=`kU5z*E|TMJk5ly0a-^N>hJ3`38q-rafTZ zt2oN!#Bp()O_s$*b{k~PSNp>qL|J7$n>Of1F852IwnS=6_We9Wl_T@;-TegKg|m@D``aT-PHdAsKA@IUm-e(*Vc1&k0OX8^ zl3xEbI{+Ccv^DUGlU8v|5?6Li(ln(Zx9F%MX|Uw@iq@hMGOS&=Q~pS6?BJHg(IcE2 z5P!fK6MzQuSttb^ld4gdN1eL9s9Wvuohbi^TO|h~8K+8ws0={$p@E+XLq5Tj9U9PD zvZ!cs3n`)|DQw60c}@+8(&~d{s~l|`%vcpAmz7V5v>3C9qITDb-mFCJtsOQO&?@Gw zP3L#M1AbtXFlQS{+Q{8xq}3}d^%`!~*Km(bD_$h&5(i|Yb0vzQaE>TO+dzt` zkAu`c058`EfO$W@q7@}r*dCEF+tLr50Q%c=*CaS~0PxrTHZ7XJrioo&YZ~024TtP> zV1IjP&Ac(S!U#p6_bQN&IS!NTdBXm-IhoRm2_7#)gC>areTM^|A790{g5&+VmYxSW zo27(np2qVavzq<<%j?R6_j43kQxy?HNt6{$lezmjWmN!I_F9l-N|Z>E8weFH(90l@ zsdta7^1@8zv0WCFAHrM7W{{7y=iUkeo4W(_=vccaVf`3@poU5TlnY-609DH^L0sQg zxfc8Flt2!x>|+&B5)d0=5#}VxpGcxcOOk8fn4d{}4>hG)atlgGm7oe`O;RQ8xm;tE zA41z*{I-?@IWa&(p(7 zykR7;-qnB>k+O-jDAsQnsadh|tazY%Sdl7DilSHRs}|sH0JIF0>2Dp6J5Wg+ViXC!%g=5dK#j9IIW04jc8@_?5z6jmbJIn3-~-r%W9kNpBqxqg4=3wnR&G3)VyMf*4H>mff31ZPI3Ga}6C=q1>gJ|K>8g#~X+ zv(8?(IgBI;twi?vO)B6KT0Mee3p$PH*7OKt7Z&r+db#G~&#RC`dmHrE-didiGG!qC zYzwGp0qBXh3ZHU(U)dgI%>n&oKPa+W?Wr0=+T6yd=WwO`=tph31@==oY4gf#pE4V! zz(1RBB*fa0{gd=i^_#32h0e?Y_D&t+8b|J8Ty!L)Kbf9+6=Rcc-UPlb=lTdo*yH=G z1O=Q>!4B=xi5W?mxOc8wm=Jt-mj8?KwC8l`1ThvK>XwJ2Dmc{_v}vNisOmF=3#%iJ zDRY(|SU&0#j?v>MBfz})IsJKGYw?qb=XZ)0A%W(A4$#F|pw{|zQRC(-_JcmMF?oo* z$Ifz$F(z5zAShKgS(Urnr){uzcl)(`Vh`{wr^oQV{@tDtr#<**<|UhexHH^L*cG~c zqkA33FvVu!oMRKh0t+S??U`$iOq*lFgIxjeY<6EO1?c63A10mhd|AhuP3+A4x6nU5 z*62=kgC?4dUsSRQ9Gc$L(ihp>EQ>D~6XA`(F2&~8shO(!{ zFQ>K6W`s=yvXjCvQwO@oo1R`c^M@dwir*XVJ{9#$!pjYZ#6qo0+x$Ai{4t!9p-=b2 za}mpba0cd(eYk*D^P!#}A`t-U9zc6g5)gbXNv|bM_zgk;a_s9zlo*f0;Lg~k6St1z zUM=jb4x8EEe@Nf}f)9tKG$qRWN6x`c5pu#$myhrPZSQOE9+r*Y$#O%f-!6VVbPpUt zoXH2>O_F*bX_bZh-zP9F_cWF~09!`UN zpW-2@Uaoo6!pXKzjGRov^4QPm{LM`Ze!j1mYCX6!%_eiDd?@N@VlHIq6{nr&m zYp|t03CXabrN7XgPwm1SjVsvDJ!e{-Ove=M4>VXGoY~gmZtBX8U?nr5{OFY%y9!3G zh|Ya`GH-l$Cv;ZsXM-)n2Q$CG#=ZwV`pVQe^pDFtP&YeVmX!X|!$-7lxtMWxB)_!Y zIiqPwT%S#Q;LM9Dy)$!NS`n!UOwrULT6e*2Prr(#!-9rGQwlV(hW}Z{SjTTg1QG{s zf~`$A#YYLJH}-m0|3ic9Guw(Prx(9Mlg}SSFYqWum{BDD)WcuRWN+_)P(qwYzBtY# dlTFZwk616kA77^y1;pF!{{uPR7LWUs0009F*SY`z literal 0 HcmV?d00001 diff --git a/vendor/swiftmailer/swiftmailer/doc/uml/Mime.graffle b/vendor/swiftmailer/swiftmailer/doc/uml/Mime.graffle new file mode 100644 index 0000000000000000000000000000000000000000..e1e33cbf16ea45d29ad48eb9b2f37959292881b2 GIT binary patch literal 5575 zcmV;&6*%f2iwFP!000030PS6CbK5r7{v7`bzWLBe-gRUE1b9i)?8vgyxa-(%tR&m6 zcXntIlGsqBLQ-+Oo&NU)NL?u2Y*Us5G02P~i97&7;+zK$4h|1q{r%g>Rld?7bbRlp zr?3T{D%9)ww&M+cditUJ=7sU}@2~e>{om1fr~BK*u`+g@Fj6i)9G;$Zl&3Ea4%*|f zOAii?x<|^z>B(hRVRalF9G^W^o(`jE{PN)7=H{klaj90%A92C(;3DwHG>C3bS!FL+ zftDTFPuXRX+LxNcj@nKydcF7L)n|J9y4{PMuk_TqrNN13({Ha1_)&J!@gh2)!E5m9 zVD@!Zgk9U|SrM!9V^Z_HkQD?L|MKKj7zON>U$Yjr{E_Dj0)H}YowIL02UfrDQr6;E z2UDSxJVa&-lGK@32eUepYfmD-ZT~R|qxm(XU_uXO=R217)e1Yl>j!gz>Fp*0H?zZw zODcAG~9ZtcYfti~ulR0Qdqy1)-M^yu_yRHwXd9-36~C^#G@5 zJHx;Um5v`=-+I|1M@~3)t=r{0pFLouH&T95_(!%FQ-<;I$nQ-?)QhspGnoUre&cjgE=_cok3^5pp#MDE0W4Yj;A~CzHAwTY-HQeIpuR|3ir456$2o2;um{ z0Q^H$V-eMiMKF#<2#7^kY5t+XSVYsA$d}&UUeZQ{m8)JKDBU4d{y}d$R*!uNnL5)@ zv8~8bCLwzmilvML=PR=k#j{2*Z(f#JH&+$6u$b%L6qR{TL+8J=s6^Vjmh1~I+gGuLrLWM7 zEN|czUgR>mb(c$}9(N+rcU(6uu`Dw0Lfc{Z)=sXI5}tuLz;hHYDA!?sG{_X3_38`I zLMDdL*jM;h4eLP5c4|r?b3Y33qTn{O65kc3T&Gaw2RHhW|8X4)`V2IF7_bBE?`m%b zHaU|jeBKu>E6hi|LOliKfgv~8GzUMJ8%TGUlJHEWP`(pX_A3D)Jbv#y^ytk-cM9 z)c>3w4sv5Te`4(*C>|O=ygNPdhBR>4@YO3Ey?AeQZ!^PQp%-#tAC}{mUJ+!TN7^!$ zdxcl?@U8}BT`hnbf?8^*)mKBPwE$B?O(iX8;8Inb$q}S&RU0qa`1^T!cIPz_k;l@+ zO?m!eM8YQI%-#fz^a5yD5_{?S+luFJ!D=_pFdvE7Wq6dRIHnRKW?$Hd7wsS<&BQXf ziXpLVJ6QI{aW{iyH7%b&G`D<+n`ilQEkn8|MRZRNXmnvk!)FV}pOD@(t=yZIGp)_I z%rwDVW@;^u8L926fEq?E6g$M!maf4vR|NznVq^}1G69XKEk27?)x5_;dNb;KGYoOv zY6#ZSRZ!clrsAnv4V#s2HG~s3QYa@Ky`s3+MA1mB*G5lMCtS^pQdI;@WfN62THM38 zO;rR9&^|2iG6N*Fv=6VQeb~HP`*Jc;^H$cpsj%1gi^QS0YHHNdQgt;gC0gl%EHrep zRVX8e>UF5>g&#Um>P?QhqX4uBQTacNfKF7bn<>A+nl!jX+rZjJbPff}JykjD+6;$+ zM67UCXyQ821OV2LS0y?JY=p|=38o@YH)J@$BZd<|0}C6}0!_V^9@dXD;6W>Q=wU1Z zr6NAQBI-N#hBq`&!aAXrOez6snPwwh_t2CpopM^a#%blD6;cf!^Q_%8*wr_>v*VSh zxTQf9Q>g^DOwdfkA`-DAVyzFcejV>TT4BMaoup1iCur6WV%Igs-jIq)$$lbWN~Zs) zOy7KH1UuH5QJOk73HxX0y1xDp_F4*T=(QBM{(MzOs9J#yfC~iVi$Ys;lWc5u8h1U4 zGYdlkTL2i1BzlINno6R#_Ngf&ToLP(UFUqpZp=`LsV=Y!na#v4IYE`Uwblu0Q!q=k zc`AQ}_Te<&K($k(03I!@X446$1RyXA1mrw*HO^1KuH_s~^dL#s*UX&5Y+56SO*w3C zB~RzB52TrKOMrp2PG%>l*WXD3nz&`aeZ??9d3qfK7YN9)bhWWm7dXs_sI}B^#ROv& zItUHTY(Z11;p3|z+&M}&gDg#py&-YxlxBKzb?Fh2)NYN`?$Q}})P6_9&>9GqG$l<; znr`Lt4K?`+i>R-#a0}?OhDKEI*I4p{Wrc-p2@|;O?dJwHF;aOd5fDw&W$B++s@)9PwaB+MNV`plxJ*V`zA@* zKGB+I`!cnQ^oxn;7dt)vczpVw?)ioCQen^QYA-p^?snUqx9^V6y35B;&Q4Fxj+c*J zemJ~nzn=<6`T`+iElQui5q@`}s9J&&cA&OM*O6FYI}+qdm7sb#6c$S*v&*m?fh;;Z6> zLgr=9&nPMgM+H=DCJ~mg8|f1Wiq~qn{w3ju$L0No=NhfX;CpLFfQl0 zWGj&}nFT;$-@-;9$$rCzI&7e3GF&J}ImvLh!f-eGdUhSt=PwjD+4NnJxgz&DH&yyh5Jo&S<-Ff#cb^;_S>O1fQ|b*E`xTR~!E(Naw!_ze zU@y+9wIT&Esh^x4L&3bnY_Q=+m~wX*(}1aQpJ%;3eL;a{abXQY={qYn8Z$ps|2+;J8K|nAvu4QsI^vyTQd*~2{wZ@Yb{iv`Uzg4$t(t! zC+vq1>IDLFZn_fFHwZ=Ag*Iuua&VL zkd<@}mqSvlbGh?U=T_D^5!hLYGNH8rSfR4X@oh_3qt^030I(X?Xr(hjji@bBAR(#t zI-sX&i2@s@ZW2RNHDsuU{y1wCn~FD%mtqlUaOj>Xb6?BIy){PeF(nQeG9=-9LZxz= z$5}MkxMf(bOyneJBBv=Z2)>(aZg?!Wt&L<{$^@&4%$qcv>?EtgMnbDh0xfyd8hO*H z6GozvCLZh8V9SPQ2O;o|DQK+$C{Z zBXQ!pPzXt!rlDyKwro{ewj@qs5~r>+qG4o>#S{Br<-dywRk| zkdAywn$}2~n7&ZwE42kAPK%Tg4Q5V2nzv+5VlpQ-pR$&`O=9|+awBB9aczV<89T9M za}ov))Fx9W>CTtbX^qs0!Q!OHz;i?7X?=i2c4x9jlKlXXh8l@j(vKz)YmJE2w(Wq1 zp|Ep3qG@yM#*N!P-oVnj4N!6B}ydGL3+wPlD2?6I*oVgiDzd*$Q(~cP8c&1JYzvmEL^GoYu&kK6qh6qCPV@ zqDvtw3n(c#G4Q^EOoPLTsuiF~737s8NimL8qDTRTR3J$CGtr8+f5>1*HFDf1vup-4 zau9wLST}{}dv;!$;&qy{c4*m4K>C<<-9|t$prOeG=8vs@8`+8UEXgp36L%BTnh0T7zG5sPY&#H^c%L={WOeLbSLb%$JU26z zQH^r(PT*Jh1Yf?(4V&eLwUOmJyb~D^Wfk#|VaAG(QJ8s=UGpl+&1 zaC3V^63R+K8CUHDB?HDgXGE*;z6!UC0~|_Hz${A7F+aTteB50J^RpAjrs1jI`%LF6 zFbgp;B>%Ykjj+kJF*>s8+Rf&femP@0E-reMXP&)4V zmyD+_g!`5o()lAewQgy!Xyp9SXT}%)jPk=v#(H8&P6-ME6ZmBmm>0ibKkqw2est)~ zouXx$z*^u>qHlZDbgDFT^0?k|TN)uvp49#2yE@uUbr?x2#( zI8reV7hp*>niS(nIieI|N`-jU2$jc{d`B@&XOo!twX&j+se;}*pG2#xwDIt9uMZT_-APO#z5aOMUR1FB4ikh8HyG{6IC`7S3 z%%mAm-oNq!-6_+Y#BSJQKV<#=IlKq6iH$5bl*auMKZnahKZ^X(J1a&fNuusuBg00_MP^o!dYbl7kE`~&=b zc>VUH+h*rG$E4duzkK=q(-~-=d^&Dleql0iKD#%apO>k^VmM9OeMVRh{nZ0;5;A#p+7$wy)JAH0ZThJBB#T*mIvimT*aSeQpGYns_YCU*i8*fRCM zs;~Cm84P!@qr3iicN)Eb=y;%^mVNHIw|7HVb_A=K3FSwx+}Kqza?Rm9=978yeK}$? z^0*n?^_a~35{`Wjc#I1(au~-4Kd@|exU9JQ4c(#92 z4(Xjq5U>ZaG=V9bTFiYeH0WB_3+d^NPKTx?rCF5t)RMqpvajeWSay6(DPKH@zNdpFz?@fN7<}%*>M(e8vBv7l*YUgWk20-X%s*zD VzxW)xOdDSB{SO2kTt$6+0RTlqtKk3u literal 0 HcmV?d00001 diff --git a/vendor/swiftmailer/swiftmailer/doc/uml/Transports.graffle b/vendor/swiftmailer/swiftmailer/doc/uml/Transports.graffle new file mode 100644 index 0000000000000000000000000000000000000000..5670e2b65ada6e01406334a4b462f58e8f48f4fd GIT binary patch literal 3061 zcmVFR$!k`4GK0ih`&)N3_0pskCgy+3{0lD+r;eCXT4SBN~zb^h1_1#wG& zj^Ub?)BR)Xy7_Lmy!Gcne*Ztmm(}LS`iU^GEe{Lz>!Y(;RoL1s77qsl8y1Vl&10c{ zR%Kt2=7fl7mw;KqICO?N&#%hc9O;Fe+vbt7yi(}bu z;*KDGk7f;XGz{H_(+mjeHm$_JPUKvB*mn+XtLvmX9HcrtkZufggH#nSSJn~*lP`2& zj&%%^O_oHlyemq(KoKOcCrNv9N%$`SqL{i1T1cb=$EnpGvOJ;cqV}Vc%yMjb16zNL z-}$721*0$gA<#=Q8&QTq@7Ohledyq%GEI6xO?8N$%`!Zy?hM_V40s@XmDO}qo)s`Ic`Zh*EtC3bt{q2YCtXvDb<W8~h!=PoWHn5H?lmh)iHWH@*oz4 zQ)qvMn4tOF??lp|xJg9cwh%NWRc&<_`L;#7>JXurafdKUl<#hw8f|5el@3AkF$!Th z&O{knj&9l9+Qh|;nH2NX@zqMa@qKaC)8u7TPhM8_NESeTd4O*-+}%xpG$02z#oH6#%eVrxl)m(62lY;%bBHj|$vM5ZHXT7+*O2K7XQ zCyNSEnXW1r`Ksg(qD02YpzewVsiFW--Vx|WO(}^<6o?bF#1{tnVccd?;@2QZM!<{O z5oYw8jo;Egs$;058}PR-`GNek@?@#pBO^su>Mlx|6|>XpHYtHF#hALBBC1iE{bakR z#AAc)UdrtLC)j;*5j8_Qe`%!PFQvK=Q(*WDK8{>uZod)sgofWCt-Kxr2HZaJ`gm|O z>~tWaYpVf7LVMWR84C+T52ERp0kKkAP}_BFs5?IyYf>!nJ+jPG4jtjn!+c8(@)vn^ z5mHoj9f#QKg1#L#wT|E5ni8~N1qplySw&kB$zB$C%KW62Mis0-mI=8z3*)YNuR&GY320}8UK@>?Q*=JM1&N7PMFI$Z&>u_ zFMisUF~H0;9ar6cpEPWqgVhMcb_6ompTCf=CiFiU#nJVkLgo z#8TkJmnN#R%+f?!dTCN2I3<-7-qNHZX^iyj9LAa~Po7=+Z* zSHEm!yc*S8$|)oMkW)rdW}iRlsVTPwa5Shprlty_^c&bsByx--7D zhJ1@O_0;w7gi!U!=QsW~Se-O?oAjVS;Uf6y#4*t0fWAdyA`Ts6Eq9wzlPTX2SHrTv zdhIqT(h@#bMP1hC3N*DKN_59buJHV>Kr9#3vVRD;l=)tt(f7*V+Ie}`e`N_ZluFC0 zp+r=y1hkoIC~2hvpgx~W4cAo-SG4AoDHef>Pf8_e6PU+219)Gh#{e?Q18Fi2dxrpZB6k~@@LHnU}_r)m|_N)8DMTOU|tUKMj&Ql zVX>x&SsJg1>C>;Ew26QzmomW20CSTW=6Hj8t@cxVT+vEXT-m(s6ghi4$LqzFY}4jP zH*GA(!j?|{*~DzNFWdhR_5S=t82Aqsy=mo%9`!B9e-?;78Kj%kRp@W#c<_F`&&Q+~ z1K;LXvU8JgTdwo@7_B_rK;J+nnLS3HG09D4l52c4rxKpKQ?-o)mh3Tzj7t8(RMKl; za(gg%41WBg&Q{)|KT`JSVRztPp<`~JL(kK@Q0NC&nuGN5TGB}F)k*yH9a z*u9}|BneJnmQ_G8A3QhGa{w5uco%w=IJWe>ONT>}{MW0})9&R}jfJwgW08^7nPk;3 z+CrRZV#-dvS!h2CwVAL8I6K>k;BFN0Yfi_FMQ)phc6&dxOz54t#vL@1A;x0*5s|*J zJgc3KNEQe5;E-0G%yixY!PshjB3LCh9id*c#J#$1L!6GrmTvN25DuDdJcL?Dx4kgB zogb#pn;Y?r_R+kTGzO9vdY|#yQokAjq{Zvx>!S1HjRi+@MR}S)THp>bUl-0S=Z-hH z>5e_uyAH%pk@v{pHhK`^q;QZF>zibj`QyWjxyUCvD)~%Yn(m!sA9A=^pDa^_4q%ipCT1h1K1MqNasetzm%JIM=mf-47vq z4reszW-)!{q5QdPTAgtu*;xTgC0PJqPcH2#3OitFP!N1l#L^2F!^NirhC;B_VIoa{ za`D0$y2I0)z-~ylACd9C^A=z>zLBM-(rG~4i^h?QvD-h_Q54)Gz!1jrH7WCo>dd5( zhxlLf^n?BJ7KreFNA{=Mse7pWee`#&and{NU0#bSXy1OYjc%2EH!rWjr(XN?#y%wJ z)f2VZls?>ly1ft&Yquwdje8>V?#>=n-^Zy!IGqOVK7$?n`dZC`7DlsuU}Q8J%r3o7 zR&XeW#Ei0o3$yrZ2UE;27pSG-J78zjl6t59H1MRRRSGl^fFh}&P>DZ)k*@8^>h@mY zKsVjN>uGd6@bwkc%}d9AoDW^e8EnQ%C_Q_zLs+M0t|^@Rd@@bG8-21a_nSc-kHN|> z;Mfbmqo0|OL;v}kC+1B~mox7E+Jh&=wh*M)&5m7uv*;4^)^bdD#E10i5FyeLu>}lo zX)*P@K-ARRso?12sVSy3VUAnN#Jw<&KZ=rA3AsqHhl65x6mxzB$H+lN*%3-gV$*3% z`TR-r3U*_FIW2@b&`KaEr9>b_lO;wepIo<}XlEoM`&jqG>%b=ZaFG8$W3gsW&3^y@ D6q4x9 literal 0 HcmV?d00001 diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift.php new file mode 100644 index 0000000..bdb8d99 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift.php @@ -0,0 +1,69 @@ +createDependenciesFor('mime.attachment') + ); + + $this->setBody($data); + $this->setFilename($filename); + if ($contentType) + { + $this->setContentType($contentType); + } + } + + /** + * Create a new Attachment. + * @param string|Swift_OutputByteStream $data + * @param string $filename + * @param string $contentType + * @return Swift_Mime_Attachment + */ + public static function newInstance($data = null, $filename = null, + $contentType = null) + { + return new self($data, $filename, $contentType); + } + + /** + * Create a new Attachment from a filesystem path. + * @param string $path + * @param string $contentType optional + * @return Swift_Mime_Attachment + */ + public static function fromPath($path, $contentType = null) + { + return self::newInstance()->setFile( + new Swift_ByteStream_FileByteStream($path), + $contentType + ); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/AbstractFilterableInputStream.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/AbstractFilterableInputStream.php new file mode 100644 index 0000000..96a4386 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/AbstractFilterableInputStream.php @@ -0,0 +1,175 @@ +_filters[$key] = $filter; + } + + /** + * Remove an already present StreamFilter based on its $key. + * @param string $key + */ + public function removeFilter($key) + { + unset($this->_filters[$key]); + } + + /** + * Writes $bytes to the end of the stream. + * @param string $bytes + * @throws Swift_IoException + */ + public function write($bytes) + { + $this->_writeBuffer .= $bytes; + foreach ($this->_filters as $filter) + { + if ($filter->shouldBuffer($this->_writeBuffer)) + { + return; + } + } + $this->_doWrite($this->_writeBuffer); + return ++$this->_sequence; + } + + /** + * For any bytes that are currently buffered inside the stream, force them + * off the buffer. + * + * @throws Swift_IoException + */ + public function commit() + { + $this->_doWrite($this->_writeBuffer); + } + + /** + * Attach $is to this stream. + * The stream acts as an observer, receiving all data that is written. + * All {@link write()} and {@link flushBuffers()} operations will be mirrored. + * + * @param Swift_InputByteStream $is + */ + public function bind(Swift_InputByteStream $is) + { + $this->_mirrors[] = $is; + } + + /** + * Remove an already bound stream. + * If $is is not bound, no errors will be raised. + * If the stream currently has any buffered data it will be written to $is + * before unbinding occurs. + * + * @param Swift_InputByteStream $is + */ + public function unbind(Swift_InputByteStream $is) + { + foreach ($this->_mirrors as $k => $stream) + { + if ($is === $stream) + { + if ($this->_writeBuffer !== '') + { + $stream->write($this->_filter($this->_writeBuffer)); + } + unset($this->_mirrors[$k]); + } + } + } + + /** + * Flush the contents of the stream (empty it) and set the internal pointer + * to the beginning. + * @throws Swift_IoException + */ + public function flushBuffers() + { + if ($this->_writeBuffer !== '') + { + $this->_doWrite($this->_writeBuffer); + } + $this->_flush(); + + foreach ($this->_mirrors as $stream) + { + $stream->flushBuffers(); + } + } + + // -- Private methods + + /** Run $bytes through all filters */ + private function _filter($bytes) + { + foreach ($this->_filters as $filter) + { + $bytes = $filter->filter($bytes); + } + return $bytes; + } + + /** Just write the bytes to the stream */ + private function _doWrite($bytes) + { + $this->_commit($this->_filter($bytes)); + + foreach ($this->_mirrors as $stream) + { + $stream->write($bytes); + } + + $this->_writeBuffer = ''; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/ArrayByteStream.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/ArrayByteStream.php new file mode 100644 index 0000000..c1cd01a --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/ArrayByteStream.php @@ -0,0 +1,188 @@ +_array = $stack; + $this->_arraySize = count($stack); + } + elseif (is_string($stack)) + { + $this->write($stack); + } + else + { + $this->_array = array(); + } + } + + /** + * Reads $length bytes from the stream into a string and moves the pointer + * through the stream by $length. If less bytes exist than are requested the + * remaining bytes are given instead. If no bytes are remaining at all, boolean + * false is returned. + * @param int $length + * @return string + */ + public function read($length) + { + if ($this->_offset == $this->_arraySize) + { + return false; + } + + // Don't use array slice + $end = $length + $this->_offset; + $end = $this->_arraySize<$end + ?$this->_arraySize + :$end; + $ret = ''; + for (; $this->_offset < $end; ++$this->_offset) + { + $ret .= $this->_array[$this->_offset]; + } + return $ret; + } + + /** + * Writes $bytes to the end of the stream. + * @param string $bytes + */ + public function write($bytes) + { + $to_add = str_split($bytes); + foreach ($to_add as $value) + { + $this->_array[] = $value; + } + $this->_arraySize = count($this->_array); + + foreach ($this->_mirrors as $stream) + { + $stream->write($bytes); + } + } + + /** + * Not used. + */ + public function commit() + { + } + + /** + * Attach $is to this stream. + * The stream acts as an observer, receiving all data that is written. + * All {@link write()} and {@link flushBuffers()} operations will be mirrored. + * + * @param Swift_InputByteStream $is + */ + public function bind(Swift_InputByteStream $is) + { + $this->_mirrors[] = $is; + } + + /** + * Remove an already bound stream. + * If $is is not bound, no errors will be raised. + * If the stream currently has any buffered data it will be written to $is + * before unbinding occurs. + * + * @param Swift_InputByteStream $is + */ + public function unbind(Swift_InputByteStream $is) + { + foreach ($this->_mirrors as $k => $stream) + { + if ($is === $stream) + { + unset($this->_mirrors[$k]); + } + } + } + + /** + * Move the internal read pointer to $byteOffset in the stream. + * @param int $byteOffset + * @return boolean + */ + public function setReadPointer($byteOffset) + { + if ($byteOffset > $this->_arraySize) + { + $byteOffset = $this->_arraySize; + } + elseif ($byteOffset < 0) + { + $byteOffset = 0; + } + + $this->_offset = $byteOffset; + } + + /** + * Flush the contents of the stream (empty it) and set the internal pointer + * to the beginning. + */ + public function flushBuffers() + { + $this->_offset = 0; + $this->_array = array(); + $this->_arraySize = 0; + + foreach ($this->_mirrors as $stream) + { + $stream->flushBuffers(); + } + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/FileByteStream.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/FileByteStream.php new file mode 100644 index 0000000..45be3c2 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/FileByteStream.php @@ -0,0 +1,234 @@ +_path = $path; + $this->_mode = $writable ? 'w+b' : 'rb'; + + if (function_exists('get_magic_quotes_runtime') && @get_magic_quotes_runtime() == 1) + { + $this->_quotes = true; + } + } + + /** + * Get the complete path to the file. + * @return string + */ + public function getPath() + { + return $this->_path; + } + + /** + * Reads $length bytes from the stream into a string and moves the pointer + * through the stream by $length. If less bytes exist than are requested the + * remaining bytes are given instead. If no bytes are remaining at all, boolean + * false is returned. + * @param int $length + * @return string + * @throws Swift_IoException + */ + public function read($length) + { + $fp = $this->_getReadHandle(); + if (!feof($fp)) + { + if ($this->_quotes) + { + ini_set('magic_quotes_runtime', 0); + } + $bytes = fread($fp, $length); + if ($this->_quotes) + { + ini_set('magic_quotes_runtime', 1); + } + $this->_offset = ftell($fp); + return $bytes; + } + else + { + $this->_resetReadHandle(); + return false; + } + } + + /** + * Move the internal read pointer to $byteOffset in the stream. + * @param int $byteOffset + * @return boolean + */ + public function setReadPointer($byteOffset) + { + if (isset($this->_reader)) + { + $this->_seekReadStreamToPosition($byteOffset); + } + $this->_offset = $byteOffset; + } + + // -- Private methods + + /** Just write the bytes to the file */ + protected function _commit($bytes) + { + fwrite($this->_getWriteHandle(), $bytes); + $this->_resetReadHandle(); + } + + /** Not used */ + protected function _flush() + { + } + + /** Get the resource for reading */ + private function _getReadHandle() + { + if (!isset($this->_reader)) + { + if (!$this->_reader = fopen($this->_path, 'rb')) + { + throw new Swift_IoException( + 'Unable to open file for reading [' . $this->_path . ']' + ); + } + if ($this->_offset <> 0) + { + $this->_getReadStreamSeekableStatus(); + $this->_seekReadStreamToPosition($this->_offset); + } + } + return $this->_reader; + } + + /** Get the resource for writing */ + private function _getWriteHandle() + { + if (!isset($this->_writer)) + { + if (!$this->_writer = fopen($this->_path, $this->_mode)) + { + throw new Swift_IoException( + 'Unable to open file for writing [' . $this->_path . ']' + ); + } + } + return $this->_writer; + } + + /** Force a reload of the resource for reading */ + private function _resetReadHandle() + { + if (isset($this->_reader)) + { + fclose($this->_reader); + $this->_reader = null; + } + } + + /** Check if ReadOnly Stream is seekable */ + private function _getReadStreamSeekableStatus() + { + $metas = stream_get_meta_data($this->_reader); + $this->_seekable = $metas['seekable']; + } + + /** Streams in a readOnly stream ensuring copy if needed */ + private function _seekReadStreamToPosition($offset) + { + if ($this->_seekable===null) + { + $this->_getReadStreamSeekableStatus(); + } + if ($this->_seekable === false) + { + $currentPos = ftell($this->_reader); + if ($currentPos<$offset) + { + $toDiscard = $offset-$currentPos; + fread($this->_reader, $toDiscard); + return; + } + $this->_copyReadStream(); + } + fseek($this->_reader, $offset, SEEK_SET); + } + + /** Copy a readOnly Stream to ensure seekability */ + private function _copyReadStream() + { + if ($tmpFile = fopen('php://temp/maxmemory:4096', 'w+b')) + { + /* We have opened a php:// Stream Should work without problem */ + } + elseif (function_exists('sys_get_temp_dir') && is_writable(sys_get_temp_dir()) && ($tmpFile = tmpfile())) + { + /* We have opened a tmpfile */ + } + else + { + throw new Swift_IoException('Unable to copy the file to make it seekable, sys_temp_dir is not writable, php://memory not available'); + } + $currentPos = ftell($this->_reader); + fclose($this->_reader); + $source = fopen($this->_path, 'rb'); + if (!$source) + { + throw new Swift_IoException('Unable to open file for copying [' . $this->_path . ']'); + } + fseek($tmpFile, 0, SEEK_SET); + while (!feof($source)) + { + fwrite($tmpFile, fread($source, 4096)); + } + fseek($tmpFile, $currentPos, SEEK_SET); + fclose($source); + $this->_reader = $tmpFile; + } +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader.php new file mode 100644 index 0000000..c660a88 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader.php @@ -0,0 +1,60 @@ + + */ +interface Swift_CharacterReader +{ + const MAP_TYPE_INVALID = 0x01; + const MAP_TYPE_FIXED_LEN = 0x02; + const MAP_TYPE_POSITIONS = 0x03; + + /** + * Returns the complete charactermap + * + * @param string $string + * @param int $startOffset + * @param array $currentMap + * @param mixed $ignoredChars + * @return int + */ + public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars); + + /** + * Returns mapType + * @return int mapType + */ + public function getMapType(); + + /** + * Returns an integer which specifies how many more bytes to read. + * A positive integer indicates the number of more bytes to fetch before invoking + * this method again. + * A value of zero means this is already a valid character. + * A value of -1 means this cannot possibly be a valid character. + * @param int[] $bytes + * @return int + */ + public function validateByteSequence($bytes, $size); + + /** + * Returns the number of bytes which should be read to start each character. + * For fixed width character sets this should be the number of + * octets-per-character. For multibyte character sets this will probably be 1. + * @return int + */ + public function getInitialByteSize(); + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/GenericFixedWidthReader.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/GenericFixedWidthReader.php new file mode 100644 index 0000000..8345ac5 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/GenericFixedWidthReader.php @@ -0,0 +1,91 @@ + + */ +class Swift_CharacterReader_GenericFixedWidthReader + implements Swift_CharacterReader +{ + /** + * The number of bytes in a single character. + * @var int + * @access private + */ + private $_width; + + /** + * Creates a new GenericFixedWidthReader using $width bytes per character. + * @param int $width + */ + public function __construct($width) + { + $this->_width = $width; + } + + /** + * Returns the complete charactermap + * + * @param string $string + * @param int $startOffset + * @param array $currentMap + * @param mixed $ignoredChars + * @return $int + */ + public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars) + { + $strlen = strlen($string); + // % and / are CPU intensive, so, maybe find a better way + $ignored = $strlen%$this->_width; + $ignoredChars = substr($string, - $ignored); + $currentMap = $this->_width; + + return ($strlen - $ignored)/$this->_width; + } + + /** + * Returns mapType + * @return int mapType + */ + public function getMapType() + { + return self::MAP_TYPE_FIXED_LEN; + } + + /** + * Returns an integer which specifies how many more bytes to read. + * A positive integer indicates the number of more bytes to fetch before invoking + * this method again. + * A value of zero means this is already a valid character. + * A value of -1 means this cannot possibly be a valid character. + * @param string $bytes + * @return int + */ + public function validateByteSequence($bytes, $size) + { + $needed = $this->_width - $size; + + return ($needed > -1) ? $needed : -1; + } + + /** + * Returns the number of bytes which should be read to start each character. + * @return int + */ + public function getInitialByteSize() + { + return $this->_width; + } +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/UsAsciiReader.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/UsAsciiReader.php new file mode 100644 index 0000000..7903949 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/UsAsciiReader.php @@ -0,0 +1,82 @@ +"\x07F") + { // Invalid char + $currentMap[$i+$startOffset]=$string[$i]; + } + } + return $strlen; + } + + /** + * Returns mapType + * @return int mapType + */ + public function getMapType() + { + return self::MAP_TYPE_INVALID; + } + + /** + * Returns an integer which specifies how many more bytes to read. + * A positive integer indicates the number of more bytes to fetch before invoking + * this method again. + * A value of zero means this is already a valid character. + * A value of -1 means this cannot possibly be a valid character. + * @param string $bytes + * @return int + */ + public function validateByteSequence($bytes, $size) + { + $byte = reset($bytes); + if (1 == count($bytes) && $byte >= 0x00 && $byte <= 0x7F) + { + return 0; + } + else + { + return -1; + } + } + + /** + * Returns the number of bytes which should be read to start each character. + * @return int + */ + public function getInitialByteSize() + { + return 1; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/Utf8Reader.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/Utf8Reader.php new file mode 100644 index 0000000..deea4b3 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/Utf8Reader.php @@ -0,0 +1,182 @@ + + */ +class Swift_CharacterReader_Utf8Reader + implements Swift_CharacterReader +{ + + /** Pre-computed for optimization */ + private static $length_map=array( +//N=0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x0N + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x1N + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x2N + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x3N + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x4N + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x5N + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x6N + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x7N + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //0x8N + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //0x9N + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //0xAN + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //0xBN + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, //0xCN + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, //0xDN + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, //0xEN + 4,4,4,4,4,4,4,4,5,5,5,5,6,6,0,0 //0xFN + ); + private static $s_length_map=array( + "\x00"=>1, "\x01"=>1, "\x02"=>1, "\x03"=>1, "\x04"=>1, "\x05"=>1, "\x06"=>1, "\x07"=>1, + "\x08"=>1, "\x09"=>1, "\x0a"=>1, "\x0b"=>1, "\x0c"=>1, "\x0d"=>1, "\x0e"=>1, "\x0f"=>1, + "\x10"=>1, "\x11"=>1, "\x12"=>1, "\x13"=>1, "\x14"=>1, "\x15"=>1, "\x16"=>1, "\x17"=>1, + "\x18"=>1, "\x19"=>1, "\x1a"=>1, "\x1b"=>1, "\x1c"=>1, "\x1d"=>1, "\x1e"=>1, "\x1f"=>1, + "\x20"=>1, "\x21"=>1, "\x22"=>1, "\x23"=>1, "\x24"=>1, "\x25"=>1, "\x26"=>1, "\x27"=>1, + "\x28"=>1, "\x29"=>1, "\x2a"=>1, "\x2b"=>1, "\x2c"=>1, "\x2d"=>1, "\x2e"=>1, "\x2f"=>1, + "\x30"=>1, "\x31"=>1, "\x32"=>1, "\x33"=>1, "\x34"=>1, "\x35"=>1, "\x36"=>1, "\x37"=>1, + "\x38"=>1, "\x39"=>1, "\x3a"=>1, "\x3b"=>1, "\x3c"=>1, "\x3d"=>1, "\x3e"=>1, "\x3f"=>1, + "\x40"=>1, "\x41"=>1, "\x42"=>1, "\x43"=>1, "\x44"=>1, "\x45"=>1, "\x46"=>1, "\x47"=>1, + "\x48"=>1, "\x49"=>1, "\x4a"=>1, "\x4b"=>1, "\x4c"=>1, "\x4d"=>1, "\x4e"=>1, "\x4f"=>1, + "\x50"=>1, "\x51"=>1, "\x52"=>1, "\x53"=>1, "\x54"=>1, "\x55"=>1, "\x56"=>1, "\x57"=>1, + "\x58"=>1, "\x59"=>1, "\x5a"=>1, "\x5b"=>1, "\x5c"=>1, "\x5d"=>1, "\x5e"=>1, "\x5f"=>1, + "\x60"=>1, "\x61"=>1, "\x62"=>1, "\x63"=>1, "\x64"=>1, "\x65"=>1, "\x66"=>1, "\x67"=>1, + "\x68"=>1, "\x69"=>1, "\x6a"=>1, "\x6b"=>1, "\x6c"=>1, "\x6d"=>1, "\x6e"=>1, "\x6f"=>1, + "\x70"=>1, "\x71"=>1, "\x72"=>1, "\x73"=>1, "\x74"=>1, "\x75"=>1, "\x76"=>1, "\x77"=>1, + "\x78"=>1, "\x79"=>1, "\x7a"=>1, "\x7b"=>1, "\x7c"=>1, "\x7d"=>1, "\x7e"=>1, "\x7f"=>1, + "\x80"=>0, "\x81"=>0, "\x82"=>0, "\x83"=>0, "\x84"=>0, "\x85"=>0, "\x86"=>0, "\x87"=>0, + "\x88"=>0, "\x89"=>0, "\x8a"=>0, "\x8b"=>0, "\x8c"=>0, "\x8d"=>0, "\x8e"=>0, "\x8f"=>0, + "\x90"=>0, "\x91"=>0, "\x92"=>0, "\x93"=>0, "\x94"=>0, "\x95"=>0, "\x96"=>0, "\x97"=>0, + "\x98"=>0, "\x99"=>0, "\x9a"=>0, "\x9b"=>0, "\x9c"=>0, "\x9d"=>0, "\x9e"=>0, "\x9f"=>0, + "\xa0"=>0, "\xa1"=>0, "\xa2"=>0, "\xa3"=>0, "\xa4"=>0, "\xa5"=>0, "\xa6"=>0, "\xa7"=>0, + "\xa8"=>0, "\xa9"=>0, "\xaa"=>0, "\xab"=>0, "\xac"=>0, "\xad"=>0, "\xae"=>0, "\xaf"=>0, + "\xb0"=>0, "\xb1"=>0, "\xb2"=>0, "\xb3"=>0, "\xb4"=>0, "\xb5"=>0, "\xb6"=>0, "\xb7"=>0, + "\xb8"=>0, "\xb9"=>0, "\xba"=>0, "\xbb"=>0, "\xbc"=>0, "\xbd"=>0, "\xbe"=>0, "\xbf"=>0, + "\xc0"=>2, "\xc1"=>2, "\xc2"=>2, "\xc3"=>2, "\xc4"=>2, "\xc5"=>2, "\xc6"=>2, "\xc7"=>2, + "\xc8"=>2, "\xc9"=>2, "\xca"=>2, "\xcb"=>2, "\xcc"=>2, "\xcd"=>2, "\xce"=>2, "\xcf"=>2, + "\xd0"=>2, "\xd1"=>2, "\xd2"=>2, "\xd3"=>2, "\xd4"=>2, "\xd5"=>2, "\xd6"=>2, "\xd7"=>2, + "\xd8"=>2, "\xd9"=>2, "\xda"=>2, "\xdb"=>2, "\xdc"=>2, "\xdd"=>2, "\xde"=>2, "\xdf"=>2, + "\xe0"=>3, "\xe1"=>3, "\xe2"=>3, "\xe3"=>3, "\xe4"=>3, "\xe5"=>3, "\xe6"=>3, "\xe7"=>3, + "\xe8"=>3, "\xe9"=>3, "\xea"=>3, "\xeb"=>3, "\xec"=>3, "\xed"=>3, "\xee"=>3, "\xef"=>3, + "\xf0"=>4, "\xf1"=>4, "\xf2"=>4, "\xf3"=>4, "\xf4"=>4, "\xf5"=>4, "\xf6"=>4, "\xf7"=>4, + "\xf8"=>5, "\xf9"=>5, "\xfa"=>5, "\xfb"=>5, "\xfc"=>6, "\xfd"=>6, "\xfe"=>0, "\xff"=>0, + ); + + /** + * Returns the complete charactermap + * + * @param string $string + * @param int $startOffset + * @param array $currentMap + * @param mixed $ignoredChars + */ + public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars) + { + if (!isset($currentMap['i']) || !isset($currentMap['p'])) + { + $currentMap['p'] = $currentMap['i'] = array(); + } + $strlen=strlen($string); + $charPos=count($currentMap['p']); + $foundChars=0; + $invalid=false; + for ($i=0; $i<$strlen; ++$i) + { + $char=$string[$i]; + $size=self::$s_length_map[$char]; + if ($size==0) + { + /* char is invalid, we must wait for a resync */ + $invalid=true; + continue; + } + else + { + if ($invalid==true) + { + /* We mark the chars as invalid and start a new char */ + $currentMap['p'][$charPos+$foundChars]=$startOffset+$i; + $currentMap['i'][$charPos+$foundChars]=true; + ++$foundChars; + $invalid=false; + } + if (($i+$size) > $strlen){ + $ignoredChars=substr($string, $i); + break; + } + for ($j=1; $j<$size; ++$j) + { + $char=$string[$i+$j]; + if ($char>"\x7F" && $char<"\xC0") + { + // Valid - continue parsing + } + else + { + /* char is invalid, we must wait for a resync */ + $invalid=true; + continue 2; + } + } + /* Ok we got a complete char here */ + $currentMap['p'][$charPos+$foundChars]=$startOffset+$i+$size; + $i+=$j-1; + ++$foundChars; + } + } + return $foundChars; + } + + /** + * Returns mapType + * @return int mapType + */ + public function getMapType() + { + return self::MAP_TYPE_POSITIONS; + } + + /** + * Returns an integer which specifies how many more bytes to read. + * A positive integer indicates the number of more bytes to fetch before invoking + * this method again. + * A value of zero means this is already a valid character. + * A value of -1 means this cannot possibly be a valid character. + * @param string $bytes + * @return int + */ + public function validateByteSequence($bytes, $size) + { + if ($size<1){ + return -1; + } + $needed = self::$length_map[$bytes[0]] - $size; + return ($needed > -1) + ? $needed + : -1 + ; + } + + /** + * Returns the number of bytes which should be read to start each character. + * @return int + */ + public function getInitialByteSize() + { + return 1; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReaderFactory.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReaderFactory.php new file mode 100644 index 0000000..55ce880 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReaderFactory.php @@ -0,0 +1,28 @@ +init(); + } + + public function __wakeup() + { + $this->init(); + } + + public function init() + { + if(count(self::$_map) > 0) + { + return; + } + + $prefix = 'Swift_CharacterReader_'; + + $singleByte = array( + 'class' => $prefix . 'GenericFixedWidthReader', + 'constructor' => array(1) + ); + + $doubleByte = array( + 'class' => $prefix . 'GenericFixedWidthReader', + 'constructor' => array(2) + ); + + $fourBytes = array( + 'class' => $prefix . 'GenericFixedWidthReader', + 'constructor' => array(4) + ); + + //Utf-8 + self::$_map['utf-?8'] = array( + 'class' => $prefix . 'Utf8Reader', + 'constructor' => array() + ); + + //7-8 bit charsets + self::$_map['(us-)?ascii'] = $singleByte; + self::$_map['(iso|iec)-?8859-?[0-9]+'] = $singleByte; + self::$_map['windows-?125[0-9]'] = $singleByte; + self::$_map['cp-?[0-9]+'] = $singleByte; + self::$_map['ansi'] = $singleByte; + self::$_map['macintosh'] = $singleByte; + self::$_map['koi-?7'] = $singleByte; + self::$_map['koi-?8-?.+'] = $singleByte; + self::$_map['mik'] = $singleByte; + self::$_map['(cork|t1)'] = $singleByte; + self::$_map['v?iscii'] = $singleByte; + + //16 bits + self::$_map['(ucs-?2|utf-?16)'] = $doubleByte; + + //32 bits + self::$_map['(ucs-?4|utf-?32)'] = $fourBytes; + + //Fallback + self::$_map['.*'] = $singleByte; + } + + /** + * Returns a CharacterReader suitable for the charset applied. + * @param string $charset + * @return Swift_CharacterReader + */ + public function getReaderFor($charset) + { + $charset = trim(strtolower($charset)); + foreach (self::$_map as $pattern => $spec) + { + $re = '/^' . $pattern . '$/D'; + if (preg_match($re, $charset)) + { + if (!array_key_exists($pattern, self::$_loaded)) + { + $reflector = new ReflectionClass($spec['class']); + if ($reflector->getConstructor()) + { + $reader = $reflector->newInstanceArgs($spec['constructor']); + } + else + { + $reader = $reflector->newInstance(); + } + self::$_loaded[$pattern] = $reader; + } + return self::$_loaded[$pattern]; + } + } + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream.php new file mode 100644 index 0000000..bf91528 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream.php @@ -0,0 +1,86 @@ +setCharacterReaderFactory($factory); + $this->setCharacterSet($charset); + } + + /** + * Set the character set used in this CharacterStream. + * @param string $charset + */ + public function setCharacterSet($charset) + { + $this->_charset = $charset; + $this->_charReader = null; + } + + /** + * Set the CharacterReaderFactory for multi charset support. + * @param Swift_CharacterReaderFactory $factory + */ + public function setCharacterReaderFactory( + Swift_CharacterReaderFactory $factory) + { + $this->_charReaderFactory = $factory; + } + + /** + * Overwrite this character stream using the byte sequence in the byte stream. + * @param Swift_OutputByteStream $os output stream to read from + */ + public function importByteStream(Swift_OutputByteStream $os) + { + if (!isset($this->_charReader)) + { + $this->_charReader = $this->_charReaderFactory + ->getReaderFor($this->_charset); + } + + $startLength = $this->_charReader->getInitialByteSize(); + while (false !== $bytes = $os->read($startLength)) + { + $c = array(); + for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) + { + $c[] = self::$_byteMap[$bytes[$i]]; + } + $size = count($c); + $need = $this->_charReader + ->validateByteSequence($c, $size); + if ($need > 0 && + false !== $bytes = $os->read($need)) + { + for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) + { + $c[] = self::$_byteMap[$bytes[$i]]; + } + } + $this->_array[] = $c; + ++$this->_array_size; + } + } + + /** + * Import a string a bytes into this CharacterStream, overwriting any existing + * data in the stream. + * @param string $string + */ + public function importString($string) + { + $this->flushContents(); + $this->write($string); + } + + /** + * Read $length characters from the stream and move the internal pointer + * $length further into the stream. + * @param int $length + * @return string + */ + public function read($length) + { + if ($this->_offset == $this->_array_size) + { + return false; + } + + // Don't use array slice + $arrays = array(); + $end = $length + $this->_offset; + for ($i = $this->_offset; $i < $end; ++$i) + { + if (!isset($this->_array[$i])) + { + break; + } + $arrays[] = $this->_array[$i]; + } + $this->_offset += $i - $this->_offset; // Limit function calls + $chars = false; + foreach ($arrays as $array) + { + $chars .= implode('', array_map('chr', $array)); + } + return $chars; + } + + /** + * Read $length characters from the stream and return a 1-dimensional array + * containing there octet values. + * @param int $length + * @return int[] + */ + public function readBytes($length) + { + if ($this->_offset == $this->_array_size) + { + return false; + } + $arrays = array(); + $end = $length + $this->_offset; + for ($i = $this->_offset; $i < $end; ++$i) + { + if (!isset($this->_array[$i])) + { + break; + } + $arrays[] = $this->_array[$i]; + } + $this->_offset += ($i - $this->_offset); // Limit function calls + return call_user_func_array('array_merge', $arrays); + } + + /** + * Write $chars to the end of the stream. + * @param string $chars + */ + public function write($chars) + { + if (!isset($this->_charReader)) + { + $this->_charReader = $this->_charReaderFactory->getReaderFor( + $this->_charset); + } + + $startLength = $this->_charReader->getInitialByteSize(); + + $fp = fopen('php://memory', 'w+b'); + fwrite($fp, $chars); + unset($chars); + fseek($fp, 0, SEEK_SET); + + $buffer = array(0); + $buf_pos = 1; + $buf_len = 1; + $has_datas = true; + do + { + $bytes = array(); + // Buffer Filing + if ($buf_len - $buf_pos < $startLength) + { + $buf = array_splice($buffer, $buf_pos); + $new = $this->_reloadBuffer($fp, 100); + if ($new) + { + $buffer = array_merge($buf, $new); + $buf_len = count($buffer); + $buf_pos = 0; + } + else + { + $has_datas = false; + } + } + if ($buf_len - $buf_pos > 0) + { + $size = 0; + for ($i = 0; $i < $startLength && isset($buffer[$buf_pos]); ++$i) + { + ++$size; + $bytes[] = $buffer[$buf_pos++]; + } + $need = $this->_charReader->validateByteSequence( + $bytes, $size); + if ($need > 0) + { + if ($buf_len - $buf_pos < $need) + { + $new = $this->_reloadBuffer($fp, $need); + + if ($new) + { + $buffer = array_merge($buffer, $new); + $buf_len = count($buffer); + } + } + for ($i = 0; $i < $need && isset($buffer[$buf_pos]); ++$i) + { + $bytes[] = $buffer[$buf_pos++]; + } + } + $this->_array[] = $bytes; + ++$this->_array_size; + } + } + while ($has_datas); + + fclose($fp); + } + + /** + * Move the internal pointer to $charOffset in the stream. + * @param int $charOffset + */ + public function setPointer($charOffset) + { + if ($charOffset > $this->_array_size) + { + $charOffset = $this->_array_size; + } + elseif ($charOffset < 0) + { + $charOffset = 0; + } + $this->_offset = $charOffset; + } + + /** + * Empty the stream and reset the internal pointer. + */ + public function flushContents() + { + $this->_offset = 0; + $this->_array = array(); + $this->_array_size = 0; + } + + private function _reloadBuffer($fp, $len) + { + if (!feof($fp) && ($bytes = fread($fp, $len)) !== false) + { + $buf = array(); + for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) + { + $buf[] = self::$_byteMap[$bytes[$i]]; + } + return $buf; + } + return false; + } + + private static function _initializeMaps() + { + if (!isset(self::$_charMap)) + { + self::$_charMap = array(); + for ($byte = 0; $byte < 256; ++$byte) + { + self::$_charMap[$byte] = chr($byte); + } + self::$_byteMap = array_flip(self::$_charMap); + } + } +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream/NgCharacterStream.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream/NgCharacterStream.php new file mode 100644 index 0000000..57c3fb7 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream/NgCharacterStream.php @@ -0,0 +1,298 @@ +. + + */ + + + +/** + * A CharacterStream implementation which stores characters in an internal array. + * @package Swift + * @subpackage CharacterStream + * @author Xavier De Cock + */ + +Class Swift_CharacterStream_NgCharacterStream + implements Swift_CharacterStream +{ + + /** + * The char reader (lazy-loaded) for the current charset. + * @var Swift_CharacterReader + * @access private + */ + private $_charReader; + + /** + * A factory for creatiing CharacterReader instances. + * @var Swift_CharacterReaderFactory + * @access private + */ + private $_charReaderFactory; + + /** + * The character set this stream is using. + * @var string + * @access private + */ + private $_charset; + + /** + * The datas stored as is + * + * @var string + */ + private $_datas = ""; + + /** + * Number of bytes in the stream + * + * @var int + */ + private $_datasSize = 0; + + /** + * Map + * + * @var mixed + */ + private $_map; + + /** + * Map Type + * + * @var int + */ + private $_mapType = 0; + + /** + * Number of characters in the stream + * + * @var int + */ + private $_charCount = 0; + + /** + * Position in the stream + * + * @var unknown_type + */ + private $_currentPos = 0; + + /** + * The constructor + * + * @param Swift_CharacterReaderFactory $factory + * @param unknown_type $charset + */ + public function __construct(Swift_CharacterReaderFactory $factory, + $charset) + { + $this->setCharacterReaderFactory($factory); + $this->setCharacterSet($charset); + } + + /* -- Changing parameters of the stream -- */ + + /** + * Set the character set used in this CharacterStream. + * @param string $charset + */ + public function setCharacterSet($charset) + { + $this->_charset = $charset; + $this->_charReader = null; + $this->_mapType = 0; + } + + /** + * Set the CharacterReaderFactory for multi charset support. + * @param Swift_CharacterReaderFactory $factory + */ + public function setCharacterReaderFactory( + Swift_CharacterReaderFactory $factory) + { + $this->_charReaderFactory = $factory; + } + + /** + * @see Swift_CharacterStream::flushContents() + * + */ + public function flushContents() + { + $this->_datas = null; + $this->_map = null; + $this->_charCount = 0; + $this->_currentPos = 0; + $this->_datasSize = 0; + } + + /** + * @see Swift_CharacterStream::importByteStream() + * + * @param Swift_OutputByteStream $os + */ + public function importByteStream(Swift_OutputByteStream $os) + { + $this->flushContents(); + $blocks=512; + $os->setReadPointer(0); + while(false!==($read = $os->read($blocks))) + $this->write($read); + } + + /** + * @see Swift_CharacterStream::importString() + * + * @param string $string + */ + public function importString($string) + { + $this->flushContents(); + $this->write($string); + } + + /** + * @see Swift_CharacterStream::read() + * + * @param int $length + * @return string + */ + public function read($length) + { + if ($this->_currentPos>=$this->_charCount) + { + return false; + } + $ret=false; + $length = ($this->_currentPos+$length > $this->_charCount) + ? $this->_charCount - $this->_currentPos + : $length; + switch ($this->_mapType) + { + case Swift_CharacterReader::MAP_TYPE_FIXED_LEN: + $len = $length*$this->_map; + $ret = substr($this->_datas, + $this->_currentPos * $this->_map, + $len); + $this->_currentPos += $length; + break; + + case Swift_CharacterReader::MAP_TYPE_INVALID: + $end = $this->_currentPos + $length; + $end = $end > $this->_charCount + ?$this->_charCount + :$end; + $ret = ''; + for (; $this->_currentPos < $length; ++$this->_currentPos) + { + if (isset ($this->_map[$this->_currentPos])) + { + $ret .= '?'; + } + else + { + $ret .= $this->_datas[$this->_currentPos]; + } + } + break; + + case Swift_CharacterReader::MAP_TYPE_POSITIONS: + $end = $this->_currentPos + $length; + $end = $end > $this->_charCount + ?$this->_charCount + :$end; + $ret = ''; + $start = 0; + if ($this->_currentPos>0) + { + $start = $this->_map['p'][$this->_currentPos-1]; + } + $to = $start; + for (; $this->_currentPos < $end; ++$this->_currentPos) + { + if (isset($this->_map['i'][$this->_currentPos])) { + $ret .= substr($this->_datas, $start, $to - $start).'?'; + $start = $this->_map['p'][$this->_currentPos]; + } else { + $to = $this->_map['p'][$this->_currentPos]; + } + } + $ret .= substr($this->_datas, $start, $to - $start); + break; + } + return $ret; + } + + /** + * @see Swift_CharacterStream::readBytes() + * + * @param int $length + * @return int[] + */ + public function readBytes($length) + { + $read=$this->read($length); + if ($read!==false) + { + $ret = array_map('ord', str_split($read, 1)); + return $ret; + } + return false; + } + + /** + * @see Swift_CharacterStream::setPointer() + * + * @param int $charOffset + */ + public function setPointer($charOffset) + { + if ($this->_charCount<$charOffset){ + $charOffset=$this->_charCount; + } + $this->_currentPos = $charOffset; + } + + /** + * @see Swift_CharacterStream::write() + * + * @param string $chars + */ + public function write($chars) + { + if (!isset($this->_charReader)) + { + $this->_charReader = $this->_charReaderFactory->getReaderFor( + $this->_charset); + $this->_map = array(); + $this->_mapType = $this->_charReader->getMapType(); + } + $ignored=''; + $this->_datas .= $chars; + $this->_charCount += $this->_charReader->getCharPositions(substr($this->_datas, $this->_datasSize), $this->_datasSize, $this->_map, $ignored); + if ($ignored!==false) { + $this->_datasSize=strlen($this->_datas)-strlen($ignored); + } + else + { + $this->_datasSize=strlen($this->_datas); + } + } +} \ No newline at end of file diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ConfigurableSpool.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ConfigurableSpool.php new file mode 100644 index 0000000..27a9b6c --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ConfigurableSpool.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Base class for Spools (implements time and message limits). + * @package Swift + * @author Fabien Potencier + */ +abstract class Swift_ConfigurableSpool implements Swift_Spool +{ + /** The maximum number of messages to send per flush */ + private $_message_limit; + + /** The time limit per flush */ + private $_time_limit; + + /** + * Sets the maximum number of messages to send per flush. + * @param int $limit The limit + */ + public function setMessageLimit($limit) + { + $this->_message_limit = (int) $limit; + } + + /** + * Gets the maximum number of messages to send per flush. + * @return int The limit + */ + public function getMessageLimit() + { + return $this->_message_limit; + } + + /** + * Sets the time limit (in seconds) per flush. + * @param int $limit The limit + */ + public function setTimeLimit($limit) + { + $this->_time_limit = (int) $limit; + } + + /** + * Gets the time limit (in seconds) per flush. + * @return int The limit + */ + public function getTimeLimit() + { + return $this->_time_limit; + } +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/DependencyContainer.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/DependencyContainer.php new file mode 100644 index 0000000..066811e --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/DependencyContainer.php @@ -0,0 +1,348 @@ +_store); + } + + /** + * Test if an item is registered in this container with the given name. + * @param string $itemName + * @return boolean + * @see register() + */ + public function has($itemName) + { + return array_key_exists($itemName, $this->_store) + && isset($this->_store[$itemName]['lookupType']); + } + + /** + * Lookup the item with the given $itemName. + * @param string $itemName + * @return mixed + * @throws Swift_DependencyException If the dependency is not found + * @see register() + */ + public function lookup($itemName) + { + if (!$this->has($itemName)) + { + throw new Swift_DependencyException( + 'Cannot lookup dependency "' . $itemName . '" since it is not registered.' + ); + } + + switch ($this->_store[$itemName]['lookupType']) + { + case self::TYPE_ALIAS: + return $this->_createAlias($itemName); + case self::TYPE_VALUE: + return $this->_getValue($itemName); + case self::TYPE_INSTANCE: + return $this->_createNewInstance($itemName); + case self::TYPE_SHARED: + return $this->_createSharedInstance($itemName); + } + } + + /** + * Create an array of arguments passed to the constructor of $itemName. + * @param string $itemName + * @return array + */ + public function createDependenciesFor($itemName) + { + $args = array(); + if (isset($this->_store[$itemName]['args'])) + { + $args = $this->_resolveArgs($this->_store[$itemName]['args']); + } + return $args; + } + + /** + * Register a new dependency with $itemName. + * This method returns the current DependencyContainer instance because it + * requires the use of the fluid interface to set the specific details for the + * dependency. + * + * @param string $itemName + * @return Swift_DependencyContainer + * @see asNewInstanceOf(), asSharedInstanceOf(), asValue() + */ + public function register($itemName) + { + $this->_store[$itemName] = array(); + $this->_endPoint =& $this->_store[$itemName]; + return $this; + } + + /** + * Specify the previously registered item as a literal value. + * {@link register()} must be called before this will work. + * + * @param mixed $value + * @return Swift_DependencyContainer + */ + public function asValue($value) + { + $endPoint =& $this->_getEndPoint(); + $endPoint['lookupType'] = self::TYPE_VALUE; + $endPoint['value'] = $value; + return $this; + } + + /** + * Specify the previously registered item as an alias of another item. + * @param string $lookup + * @return Swift_DependencyContainer + */ + public function asAliasOf($lookup) + { + $endPoint =& $this->_getEndPoint(); + $endPoint['lookupType'] = self::TYPE_ALIAS; + $endPoint['ref'] = $lookup; + return $this; + } + + /** + * Specify the previously registered item as a new instance of $className. + * {@link register()} must be called before this will work. + * Any arguments can be set with {@link withDependencies()}, + * {@link addConstructorValue()} or {@link addConstructorLookup()}. + * + * @param string $className + * @return Swift_DependencyContainer + * @see withDependencies(), addConstructorValue(), addConstructorLookup() + */ + public function asNewInstanceOf($className) + { + $endPoint =& $this->_getEndPoint(); + $endPoint['lookupType'] = self::TYPE_INSTANCE; + $endPoint['className'] = $className; + return $this; + } + + /** + * Specify the previously registered item as a shared instance of $className. + * {@link register()} must be called before this will work. + * @param string $className + * @return Swift_DependencyContainer + */ + public function asSharedInstanceOf($className) + { + $endPoint =& $this->_getEndPoint(); + $endPoint['lookupType'] = self::TYPE_SHARED; + $endPoint['className'] = $className; + return $this; + } + + /** + * Specify a list of injected dependencies for the previously registered item. + * This method takes an array of lookup names. + * + * @param array $lookups + * @return Swift_DependencyContainer + * @see addConstructorValue(), addConstructorLookup() + */ + public function withDependencies(array $lookups) + { + $endPoint =& $this->_getEndPoint(); + $endPoint['args'] = array(); + foreach ($lookups as $lookup) + { + $this->addConstructorLookup($lookup); + } + return $this; + } + + /** + * Specify a literal (non looked up) value for the constructor of the + * previously registered item. + * + * @param mixed $value + * @return Swift_DependencyContainer + * @see withDependencies(), addConstructorLookup() + */ + public function addConstructorValue($value) + { + $endPoint =& $this->_getEndPoint(); + if (!isset($endPoint['args'])) + { + $endPoint['args'] = array(); + } + $endPoint['args'][] = array('type' => 'value', 'item' => $value); + return $this; + } + + /** + * Specify a dependency lookup for the constructor of the previously + * registered item. + * + * @param string $lookup + * @return Swift_DependencyContainer + * @see withDependencies(), addConstructorValue() + */ + public function addConstructorLookup($lookup) + { + $endPoint =& $this->_getEndPoint(); + if (!isset($this->_endPoint['args'])) + { + $endPoint['args'] = array(); + } + $endPoint['args'][] = array('type' => 'lookup', 'item' => $lookup); + return $this; + } + + // -- Private methods + + /** Get the literal value with $itemName */ + private function _getValue($itemName) + { + return $this->_store[$itemName]['value']; + } + + /** Resolve an alias to another item */ + private function _createAlias($itemName) + { + return $this->lookup($this->_store[$itemName]['ref']); + } + + /** Create a fresh instance of $itemName */ + private function _createNewInstance($itemName) + { + $reflector = new ReflectionClass($this->_store[$itemName]['className']); + if ($reflector->getConstructor()) + { + return $reflector->newInstanceArgs( + $this->createDependenciesFor($itemName) + ); + } + else + { + return $reflector->newInstance(); + } + } + + /** Create and register a shared instance of $itemName */ + private function _createSharedInstance($itemName) + { + if (!isset($this->_store[$itemName]['instance'])) + { + $this->_store[$itemName]['instance'] = $this->_createNewInstance($itemName); + } + return $this->_store[$itemName]['instance']; + } + + /** Get the current endpoint in the store */ + private function &_getEndPoint() + { + if (!isset($this->_endPoint)) + { + throw new BadMethodCallException( + 'Component must first be registered by calling register()' + ); + } + return $this->_endPoint; + } + + /** Get an argument list with dependencies resolved */ + private function _resolveArgs(array $args) + { + $resolved = array(); + foreach ($args as $argDefinition) + { + switch ($argDefinition['type']) + { + case 'lookup': + $resolved[] = $this->_lookupRecursive($argDefinition['item']); + break; + case 'value': + $resolved[] = $argDefinition['item']; + break; + } + } + return $resolved; + } + + /** Resolve a single dependency with an collections */ + private function _lookupRecursive($item) + { + if (is_array($item)) + { + $collection = array(); + foreach ($item as $k => $v) + { + $collection[$k] = $this->_lookupRecursive($v); + } + return $collection; + } + else + { + return $this->lookup($item); + } + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/DependencyException.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/DependencyException.php new file mode 100644 index 0000000..7622aac --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/DependencyException.php @@ -0,0 +1,29 @@ +createDependenciesFor('mime.embeddedfile') + ); + + $this->setBody($data); + $this->setFilename($filename); + if ($contentType) + { + $this->setContentType($contentType); + } + } + + /** + * Create a new EmbeddedFile. + * @param string|Swift_OutputByteStream $data + * @param string $filename + * @param string $contentType + * @return Swift_Mime_EmbeddedFile + */ + public static function newInstance($data = null, $filename = null, + $contentType = null) + { + return new self($data, $filename, $contentType); + } + + /** + * Create a new EmbeddedFile from a filesystem path. + * @param string $path + * @return Swift_Mime_EmbeddedFile + */ + public static function fromPath($path) + { + return self::newInstance()->setFile( + new Swift_ByteStream_FileByteStream($path) + ); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder.php new file mode 100644 index 0000000..3db403f --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder.php @@ -0,0 +1,31 @@ += $maxLineLength || 76 < $maxLineLength) + { + $maxLineLength = 76; + } + + $encodedString = base64_encode($string); + $firstLine = ''; + + if (0 != $firstLineOffset) + { + $firstLine = substr( + $encodedString, 0, $maxLineLength - $firstLineOffset + ) . "\r\n"; + $encodedString = substr( + $encodedString, $maxLineLength - $firstLineOffset + ); + } + + return $firstLine . trim(chunk_split($encodedString, $maxLineLength, "\r\n")); + } + + /** + * Does nothing. + */ + public function charsetChanged($charset) + { + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/QpEncoder.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/QpEncoder.php new file mode 100644 index 0000000..6efd728 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/QpEncoder.php @@ -0,0 +1,296 @@ + '=00', 1 => '=01', 2 => '=02', 3 => '=03', 4 => '=04', + 5 => '=05', 6 => '=06', 7 => '=07', 8 => '=08', 9 => '=09', + 10 => '=0A', 11 => '=0B', 12 => '=0C', 13 => '=0D', 14 => '=0E', + 15 => '=0F', 16 => '=10', 17 => '=11', 18 => '=12', 19 => '=13', + 20 => '=14', 21 => '=15', 22 => '=16', 23 => '=17', 24 => '=18', + 25 => '=19', 26 => '=1A', 27 => '=1B', 28 => '=1C', 29 => '=1D', + 30 => '=1E', 31 => '=1F', 32 => '=20', 33 => '=21', 34 => '=22', + 35 => '=23', 36 => '=24', 37 => '=25', 38 => '=26', 39 => '=27', + 40 => '=28', 41 => '=29', 42 => '=2A', 43 => '=2B', 44 => '=2C', + 45 => '=2D', 46 => '=2E', 47 => '=2F', 48 => '=30', 49 => '=31', + 50 => '=32', 51 => '=33', 52 => '=34', 53 => '=35', 54 => '=36', + 55 => '=37', 56 => '=38', 57 => '=39', 58 => '=3A', 59 => '=3B', + 60 => '=3C', 61 => '=3D', 62 => '=3E', 63 => '=3F', 64 => '=40', + 65 => '=41', 66 => '=42', 67 => '=43', 68 => '=44', 69 => '=45', + 70 => '=46', 71 => '=47', 72 => '=48', 73 => '=49', 74 => '=4A', + 75 => '=4B', 76 => '=4C', 77 => '=4D', 78 => '=4E', 79 => '=4F', + 80 => '=50', 81 => '=51', 82 => '=52', 83 => '=53', 84 => '=54', + 85 => '=55', 86 => '=56', 87 => '=57', 88 => '=58', 89 => '=59', + 90 => '=5A', 91 => '=5B', 92 => '=5C', 93 => '=5D', 94 => '=5E', + 95 => '=5F', 96 => '=60', 97 => '=61', 98 => '=62', 99 => '=63', + 100 => '=64', 101 => '=65', 102 => '=66', 103 => '=67', 104 => '=68', + 105 => '=69', 106 => '=6A', 107 => '=6B', 108 => '=6C', 109 => '=6D', + 110 => '=6E', 111 => '=6F', 112 => '=70', 113 => '=71', 114 => '=72', + 115 => '=73', 116 => '=74', 117 => '=75', 118 => '=76', 119 => '=77', + 120 => '=78', 121 => '=79', 122 => '=7A', 123 => '=7B', 124 => '=7C', + 125 => '=7D', 126 => '=7E', 127 => '=7F', 128 => '=80', 129 => '=81', + 130 => '=82', 131 => '=83', 132 => '=84', 133 => '=85', 134 => '=86', + 135 => '=87', 136 => '=88', 137 => '=89', 138 => '=8A', 139 => '=8B', + 140 => '=8C', 141 => '=8D', 142 => '=8E', 143 => '=8F', 144 => '=90', + 145 => '=91', 146 => '=92', 147 => '=93', 148 => '=94', 149 => '=95', + 150 => '=96', 151 => '=97', 152 => '=98', 153 => '=99', 154 => '=9A', + 155 => '=9B', 156 => '=9C', 157 => '=9D', 158 => '=9E', 159 => '=9F', + 160 => '=A0', 161 => '=A1', 162 => '=A2', 163 => '=A3', 164 => '=A4', + 165 => '=A5', 166 => '=A6', 167 => '=A7', 168 => '=A8', 169 => '=A9', + 170 => '=AA', 171 => '=AB', 172 => '=AC', 173 => '=AD', 174 => '=AE', + 175 => '=AF', 176 => '=B0', 177 => '=B1', 178 => '=B2', 179 => '=B3', + 180 => '=B4', 181 => '=B5', 182 => '=B6', 183 => '=B7', 184 => '=B8', + 185 => '=B9', 186 => '=BA', 187 => '=BB', 188 => '=BC', 189 => '=BD', + 190 => '=BE', 191 => '=BF', 192 => '=C0', 193 => '=C1', 194 => '=C2', + 195 => '=C3', 196 => '=C4', 197 => '=C5', 198 => '=C6', 199 => '=C7', + 200 => '=C8', 201 => '=C9', 202 => '=CA', 203 => '=CB', 204 => '=CC', + 205 => '=CD', 206 => '=CE', 207 => '=CF', 208 => '=D0', 209 => '=D1', + 210 => '=D2', 211 => '=D3', 212 => '=D4', 213 => '=D5', 214 => '=D6', + 215 => '=D7', 216 => '=D8', 217 => '=D9', 218 => '=DA', 219 => '=DB', + 220 => '=DC', 221 => '=DD', 222 => '=DE', 223 => '=DF', 224 => '=E0', + 225 => '=E1', 226 => '=E2', 227 => '=E3', 228 => '=E4', 229 => '=E5', + 230 => '=E6', 231 => '=E7', 232 => '=E8', 233 => '=E9', 234 => '=EA', + 235 => '=EB', 236 => '=EC', 237 => '=ED', 238 => '=EE', 239 => '=EF', + 240 => '=F0', 241 => '=F1', 242 => '=F2', 243 => '=F3', 244 => '=F4', + 245 => '=F5', 246 => '=F6', 247 => '=F7', 248 => '=F8', 249 => '=F9', + 250 => '=FA', 251 => '=FB', 252 => '=FC', 253 => '=FD', 254 => '=FE', + 255 => '=FF' + ); + + protected static $_safeMapShare = array(); + + /** + * A map of non-encoded ascii characters. + * @var string[] + * @access protected + */ + protected $_safeMap = array(); + + /** + * Creates a new QpEncoder for the given CharacterStream. + * @param Swift_CharacterStream $charStream to use for reading characters + * @param Swift_StreamFilter $filter if input should be canonicalized + */ + public function __construct(Swift_CharacterStream $charStream, + Swift_StreamFilter $filter = null) + { + $this->_charStream = $charStream; + if(!isset(self::$_safeMapShare[$this->getSafeMapShareId()])) + { + $this->initSafeMap(); + self::$_safeMapShare[$this->getSafeMapShareId()] = $this->_safeMap; + } + else + { + $this->_safeMap = self::$_safeMapShare[$this->getSafeMapShareId()]; + } + $this->_filter = $filter; + } + + public function __sleep() + { + return array('_charStream', '_filter'); + } + + public function __wakeup() + { + if(!isset(self::$_safeMapShare[$this->getSafeMapShareId()])) + { + $this->initSafeMap(); + self::$_safeMapShare[$this->getSafeMapShareId()] = $this->_safeMap; + } + else + { + $this->_safeMap = self::$_safeMapShare[$this->getSafeMapShareId()]; + } + } + + protected function getSafeMapShareId() + { + return get_class($this); + } + + protected function initSafeMap() + { + foreach (array_merge( + array(0x09, 0x20), range(0x21, 0x3C), range(0x3E, 0x7E)) as $byte) + { + $this->_safeMap[$byte] = chr($byte); + } + } + + /** + * Takes an unencoded string and produces a QP encoded string from it. + * QP encoded strings have a maximum line length of 76 characters. + * If the first line needs to be shorter, indicate the difference with + * $firstLineOffset. + * @param string $string to encode + * @param int $firstLineOffset, optional + * @param int $maxLineLength, optional, 0 indicates the default of 76 chars + * @return string + */ + public function encodeString($string, $firstLineOffset = 0, + $maxLineLength = 0) + { + if ($maxLineLength > 76 || $maxLineLength <= 0) + { + $maxLineLength = 76; + } + + $thisLineLength = $maxLineLength - $firstLineOffset; + + $lines = array(); + $lNo = 0; + $lines[$lNo] = ''; + $currentLine =& $lines[$lNo++]; + $size=$lineLen=0; + + $this->_charStream->flushContents(); + $this->_charStream->importString($string); + + //Fetching more than 4 chars at one is slower, as is fetching fewer bytes + // Conveniently 4 chars is the UTF-8 safe number since UTF-8 has up to 6 + // bytes per char and (6 * 4 * 3 = 72 chars per line) * =NN is 3 bytes + while (false !== $bytes = $this->_nextSequence()) + { + //If we're filtering the input + if (isset($this->_filter)) + { + //If we can't filter because we need more bytes + while ($this->_filter->shouldBuffer($bytes)) + { + //Then collect bytes into the buffer + if (false === $moreBytes = $this->_nextSequence(1)) + { + break; + } + + foreach ($moreBytes as $b) + { + $bytes[] = $b; + } + } + //And filter them + $bytes = $this->_filter->filter($bytes); + } + + $enc = $this->_encodeByteSequence($bytes, $size); + if ($currentLine && $lineLen+$size >= $thisLineLength) + { + $lines[$lNo] = ''; + $currentLine =& $lines[$lNo++]; + $thisLineLength = $maxLineLength; + $lineLen=0; + } + $lineLen+=$size; + $currentLine .= $enc; + } + + return $this->_standardize(implode("=\r\n", $lines)); + } + + /** + * Updates the charset used. + * @param string $charset + */ + public function charsetChanged($charset) + { + $this->_charStream->setCharacterSet($charset); + } + + // -- Protected methods + + /** + * Encode the given byte array into a verbatim QP form. + * @param int[] $bytes + * @return string + * @access protected + */ + protected function _encodeByteSequence(array $bytes, &$size) + { + $ret = ''; + $size=0; + foreach ($bytes as $b) + { + if (isset($this->_safeMap[$b])) + { + $ret .= $this->_safeMap[$b]; + ++$size; + } + else + { + $ret .= self::$_qpMap[$b]; + $size+=3; + } + } + return $ret; + } + + /** + * Get the next sequence of bytes to read from the char stream. + * @param int $size number of bytes to read + * @return int[] + * @access protected + */ + protected function _nextSequence($size = 4) + { + return $this->_charStream->readBytes($size); + } + + /** + * Make sure CRLF is correct and HT/SPACE are in valid places. + * @param string $string + * @return string + * @access protected + */ + protected function _standardize($string) + { + $string = str_replace(array("\t=0D=0A", " =0D=0A", "=0D=0A"), + array("=09\r\n", "=20\r\n", "\r\n"), $string + ); + switch ($end = ord(substr($string, -1))) + { + case 0x09: + case 0x20: + $string = substr_replace($string, self::$_qpMap[$end], -1); + } + return $string; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/Rfc2231Encoder.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/Rfc2231Encoder.php new file mode 100644 index 0000000..c4c5725 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/Rfc2231Encoder.php @@ -0,0 +1,87 @@ +_charStream = $charStream; + } + + /** + * Takes an unencoded string and produces a string encoded according to + * RFC 2231 from it. + * @param string $string to encode + * @param int $firstLineOffset + * @param int $maxLineLength, optional, 0 indicates the default of 75 bytes + * @return string + */ + public function encodeString($string, $firstLineOffset = 0, + $maxLineLength = 0) + { + $lines = array(); $lineCount = 0; + $lines[] = ''; + $currentLine =& $lines[$lineCount++]; + + if (0 >= $maxLineLength) + { + $maxLineLength = 75; + } + + $this->_charStream->flushContents(); + $this->_charStream->importString($string); + + $thisLineLength = $maxLineLength - $firstLineOffset; + + while (false !== $char = $this->_charStream->read(4)) + { + $encodedChar = rawurlencode($char); + if (0 != strlen($currentLine) + && strlen($currentLine . $encodedChar) > $thisLineLength) + { + $lines[] = ''; + $currentLine =& $lines[$lineCount++]; + $thisLineLength = $maxLineLength; + } + $currentLine .= $encodedChar; + } + + return implode("\r\n", $lines); + } + + /** + * Updates the charset used. + * @param string $charset + */ + public function charsetChanged($charset) + { + $this->_charStream->setCharacterSet($charset); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoding.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoding.php new file mode 100644 index 0000000..369b9a5 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoding.php @@ -0,0 +1,69 @@ +lookup($key); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/CommandEvent.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/CommandEvent.php new file mode 100644 index 0000000..11b808c --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/CommandEvent.php @@ -0,0 +1,65 @@ +_command = $command; + $this->_successCodes = $successCodes; + } + + /** + * Get the command which was sent to the server. + * @return string + */ + public function getCommand() + { + return $this->_command; + } + + /** + * Get the numeric response codes which indicate success for this command. + * @return int[] + */ + public function getSuccessCodes() + { + return $this->_successCodes; + } + +} \ No newline at end of file diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/CommandListener.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/CommandListener.php new file mode 100644 index 0000000..0964577 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/CommandListener.php @@ -0,0 +1,27 @@ +_source = $source; + } + + /** + * Get the source object of this event. + * @return object + */ + public function getSource() + { + return $this->_source; + } + + /** + * Prevent this Event from bubbling any further up the stack. + * @param boolean $cancel, optional + */ + public function cancelBubble($cancel = true) + { + $this->_bubbleCancelled = $cancel; + } + + /** + * Returns true if this Event will not bubble any further up the stack. + * @return boolean + */ + public function bubbleCancelled() + { + return $this->_bubbleCancelled; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/ResponseEvent.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/ResponseEvent.php new file mode 100644 index 0000000..7ce0ad6 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/ResponseEvent.php @@ -0,0 +1,64 @@ +_response = $response; + $this->_valid = $valid; + } + + /** + * Get the response which was received from the server. + * @return string + */ + public function getResponse() + { + return $this->_response; + } + + /** + * Get the success status of this Event. + * @return boolean + */ + public function isValid() + { + return $this->_valid; + } + +} \ No newline at end of file diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/ResponseListener.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/ResponseListener.php new file mode 100644 index 0000000..d2fc8e4 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/ResponseListener.php @@ -0,0 +1,27 @@ +_message = $message; + $this->_result = self::RESULT_PENDING; + } + + /** + * Get the Transport used to send the Message. + * @return Swift_Transport + */ + public function getTransport() + { + return $this->getSource(); + } + + /** + * Get the Message being sent. + * @return Swift_Mime_Message + */ + public function getMessage() + { + return $this->_message; + } + + /** + * Set the array of addresses that failed in sending. + * @param array $recipients + */ + public function setFailedRecipients($recipients) + { + $this->_failedRecipients = $recipients; + } + + /** + * Get an recipient addresses which were not accepted for delivery. + * @return string[] + */ + public function getFailedRecipients() + { + return $this->_failedRecipients; + } + + /** + * Set the result of sending. + * @return int + */ + public function setResult($result) + { + $this->_result = $result; + } + + /** + * Get the result of this Event. + * The return value is a bitmask from + * {@link RESULT_PENDING, RESULT_SUCCESS, RESULT_TENTATIVE, RESULT_FAILED} + * @return int + */ + public function getResult() + { + return $this->_result; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/SendListener.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/SendListener.php new file mode 100644 index 0000000..1ce187c --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/SendListener.php @@ -0,0 +1,33 @@ +_eventMap = array( + 'Swift_Events_CommandEvent' => 'Swift_Events_CommandListener', + 'Swift_Events_ResponseEvent' => 'Swift_Events_ResponseListener', + 'Swift_Events_SendEvent' => 'Swift_Events_SendListener', + 'Swift_Events_TransportChangeEvent' => 'Swift_Events_TransportChangeListener', + 'Swift_Events_TransportExceptionEvent' => 'Swift_Events_TransportExceptionListener' + ); + } + + /** + * Create a new SendEvent for $source and $message. + * + * @param Swift_Transport $source + * @param Swift_Mime_Message + * @return Swift_Events_SendEvent + */ + public function createSendEvent(Swift_Transport $source, + Swift_Mime_Message $message) + { + return new Swift_Events_SendEvent($source, $message); + } + + /** + * Create a new CommandEvent for $source and $command. + * + * @param Swift_Transport $source + * @param string $command That will be executed + * @param array $successCodes That are needed + * @return Swift_Events_CommandEvent + */ + public function createCommandEvent(Swift_Transport $source, + $command, $successCodes = array()) + { + return new Swift_Events_CommandEvent($source, $command, $successCodes); + } + + /** + * Create a new ResponseEvent for $source and $response. + * + * @param Swift_Transport $source + * @param string $response + * @param boolean $valid If the response is valid + * @return Swift_Events_ResponseEvent + */ + public function createResponseEvent(Swift_Transport $source, + $response, $valid) + { + return new Swift_Events_ResponseEvent($source, $response, $valid); + } + + /** + * Create a new TransportChangeEvent for $source. + * + * @param Swift_Transport $source + * @return Swift_Events_TransportChangeEvent + */ + public function createTransportChangeEvent(Swift_Transport $source) + { + return new Swift_Events_TransportChangeEvent($source); + } + + /** + * Create a new TransportExceptionEvent for $source. + * + * @param Swift_Transport $source + * @param Swift_TransportException $ex + * @return Swift_Events_TransportExceptionEvent + */ + public function createTransportExceptionEvent(Swift_Transport $source, + Swift_TransportException $ex) + { + return new Swift_Events_TransportExceptionEvent($source, $ex); + } + + /** + * Bind an event listener to this dispatcher. + * + * @param Swift_Events_EventListener $listener + */ + public function bindEventListener(Swift_Events_EventListener $listener) + { + foreach ($this->_listeners as $l) + { + //Already loaded + if ($l === $listener) + { + return; + } + } + $this->_listeners[] = $listener; + } + + /** + * Dispatch the given Event to all suitable listeners. + * + * @param Swift_Events_EventObject $evt + * @param string $target method + */ + public function dispatchEvent(Swift_Events_EventObject $evt, $target) + { + $this->_prepareBubbleQueue($evt); + $this->_bubble($evt, $target); + } + + // -- Private methods + + /** Queue listeners on a stack ready for $evt to be bubbled up it */ + private function _prepareBubbleQueue(Swift_Events_EventObject $evt) + { + $this->_bubbleQueue = array(); + $evtClass = get_class($evt); + foreach ($this->_listeners as $listener) + { + if (array_key_exists($evtClass, $this->_eventMap) + && ($listener instanceof $this->_eventMap[$evtClass])) + { + $this->_bubbleQueue[] = $listener; + } + } + } + + /** Bubble $evt up the stack calling $target() on each listener */ + private function _bubble(Swift_Events_EventObject $evt, $target) + { + if (!$evt->bubbleCancelled() && $listener = array_shift($this->_bubbleQueue)) + { + $listener->$target($evt); + $this->_bubble($evt, $target); + } + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportChangeEvent.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportChangeEvent.php new file mode 100644 index 0000000..e57176a --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportChangeEvent.php @@ -0,0 +1,30 @@ +getSource(); + } + +} \ No newline at end of file diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportChangeListener.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportChangeListener.php new file mode 100644 index 0000000..9c028f0 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportChangeListener.php @@ -0,0 +1,51 @@ +_exception = $ex; + } + + /** + * Get the TransportException thrown. + * @return Swift_TransportException + */ + public function getException() + { + return $this->_exception; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportExceptionListener.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportExceptionListener.php new file mode 100644 index 0000000..92266af --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportExceptionListener.php @@ -0,0 +1,28 @@ +createDependenciesFor('transport.failover') + ); + + $this->setTransports($transports); + } + + /** + * Create a new FailoverTransport instance. + * @param string $transports + * @return Swift_FailoverTransport + */ + public static function newInstance($transports = array()) + { + return new self($transports); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/FileSpool.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/FileSpool.php new file mode 100644 index 0000000..48b2247 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/FileSpool.php @@ -0,0 +1,210 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Stores Messages on the filesystem. + * @package Swift + * @author Fabien Potencier + * @author Xavier De Cock + */ +class Swift_FileSpool extends Swift_ConfigurableSpool +{ + /** The spool directory */ + private $_path; + + /** + * File WriteRetry Limit + * @var int + */ + private $_retryLimit=10; + + /** + * Create a new FileSpool. + * @param string $path + * @throws Swift_IoException + */ + public function __construct($path) + { + $this->_path = $path; + + if (!file_exists($this->_path)) + { + if (!mkdir($this->_path, 0777, true)) + { + throw new Swift_IoException('Unable to create Path ['.$this->_path.']'); + } + } + } + + /** + * Tests if this Spool mechanism has started. + * + * @return boolean + */ + public function isStarted() + { + return true; + } + + /** + * Starts this Spool mechanism. + */ + public function start() + { + } + + /** + * Stops this Spool mechanism. + */ + public function stop() + { + } + + /** + * Allow to manage the enqueuing retry limit. + * Default, is ten and allows over 64^20 different fileNames + * + * @param integer $limit + */ + public function setRetryLimit($limit) + { + $this->_retryLimit=$limit; + } + + /** + * Queues a message. + * @param Swift_Mime_Message $message The message to store + * @return boolean + * @throws Swift_IoException + */ + public function queueMessage(Swift_Mime_Message $message) + { + $ser = serialize($message); + $fileName=$this->_path.'/'.$this->getRandomString(10); + for ($i = 0; $i < $this->_retryLimit; ++$i) + { + /* We try an exclusive creation of the file + * This is an atomic operation, it avoid locking mechanism + */ + $fp = @fopen($fileName.'.message', 'x'); + if (false !== $fp) + { + if (false === fwrite($fp, $ser)) + { + return false; + } + + return fclose($fp); + } + else + { + /* The file allready exists, we try a longer fileName + */ + $fileName.=$this->getRandomString(1); + } + } + + throw new Swift_IoException('Unable to create a file for enqueuing Message'); + } + + /** + * Execute a recovery if for anyreason a process is sending for too long + * + * @param int $timeout in second Defaults is for very slow smtp responses + */ + public function recover($timeout=900) + { + foreach (new DirectoryIterator($this->_path) as $file) + { + $file = $file->getRealPath(); + + if (substr($file, -16)=='.message.sending') + { + $lockedtime=filectime($file); + if ((time()-$lockedtime)>$timeout) + { + rename($file, substr($file, 0, -8)); + } + } + } + } + + /** + * Sends messages using the given transport instance. + * + * @param Swift_Transport $transport A transport instance + * @param string[] &$failedRecipients An array of failures by-reference + * + * @return int The number of sent emails + */ + public function flushQueue(Swift_Transport $transport, &$failedRecipients = null) + { + if (!$transport->isStarted()) + { + $transport->start(); + } + + $failedRecipients = (array) $failedRecipients; + $count = 0; + $time = time(); + foreach (new DirectoryIterator($this->_path) as $file) + { + $file = $file->getRealPath(); + + if (substr($file, -8) != '.message') + { + continue; + } + + /* We try a rename, it's an atomic operation, and avoid locking the file */ + if (rename($file, $file.'.sending')) + { + $message = unserialize(file_get_contents($file.'.sending')); + + $count += $transport->send($message, $failedRecipients); + + unlink($file.'.sending'); + } + else + { + /* This message has just been catched by another process */ + continue; + } + + if ($this->getMessageLimit() && $count >= $this->getMessageLimit()) + { + break; + } + + if ($this->getTimeLimit() && (time() - $time) >= $this->getTimeLimit()) + { + break; + } + } + + return $count; + } + + /** + * Returns a random string needed to generate a fileName for the queue. + * @param int $count + */ + protected function getRandomString($count) { + // This string MUST stay FS safe, avoid special chars + $base="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-."; + $ret=''; + $strlen=strlen($base); + for ($i=0; $i<$count; ++$i) + { + $ret.=$base[((int)rand(0,$strlen-1))]; + } + return $ret; + } +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/FileStream.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/FileStream.php new file mode 100644 index 0000000..56bf36e --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/FileStream.php @@ -0,0 +1,27 @@ +setFile( + new Swift_ByteStream_FileByteStream($path) + ); + return $image; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/InputByteStream.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/InputByteStream.php new file mode 100644 index 0000000..e8f45f4 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/InputByteStream.php @@ -0,0 +1,72 @@ +_stream = $stream; + } + + /** + * Set a string into the cache under $itemKey for the namespace $nsKey. + * @param string $nsKey + * @param string $itemKey + * @param string $string + * @param int $mode + * @see MODE_WRITE, MODE_APPEND + */ + public function setString($nsKey, $itemKey, $string, $mode) + { + $this->_prepareCache($nsKey); + switch ($mode) + { + case self::MODE_WRITE: + $this->_contents[$nsKey][$itemKey] = $string; + break; + case self::MODE_APPEND: + if (!$this->hasKey($nsKey, $itemKey)) + { + $this->_contents[$nsKey][$itemKey] = ''; + } + $this->_contents[$nsKey][$itemKey] .= $string; + break; + default: + throw new Swift_SwiftException( + 'Invalid mode [' . $mode . '] used to set nsKey='. + $nsKey . ', itemKey=' . $itemKey + ); + } + } + + /** + * Set a ByteStream into the cache under $itemKey for the namespace $nsKey. + * @param string $nsKey + * @param string $itemKey + * @param Swift_OutputByteStream $os + * @param int $mode + * @see MODE_WRITE, MODE_APPEND + */ + public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os, + $mode) + { + $this->_prepareCache($nsKey); + switch ($mode) + { + case self::MODE_WRITE: + $this->clearKey($nsKey, $itemKey); + case self::MODE_APPEND: + if (!$this->hasKey($nsKey, $itemKey)) + { + $this->_contents[$nsKey][$itemKey] = ''; + } + while (false !== $bytes = $os->read(8192)) + { + $this->_contents[$nsKey][$itemKey] .= $bytes; + } + break; + default: + throw new Swift_SwiftException( + 'Invalid mode [' . $mode . '] used to set nsKey='. + $nsKey . ', itemKey=' . $itemKey + ); + } + } + + /** + * Provides a ByteStream which when written to, writes data to $itemKey. + * NOTE: The stream will always write in append mode. + * @param string $nsKey + * @param string $itemKey + * @return Swift_InputByteStream + */ + public function getInputByteStream($nsKey, $itemKey, + Swift_InputByteStream $writeThrough = null) + { + $is = clone $this->_stream; + $is->setKeyCache($this); + $is->setNsKey($nsKey); + $is->setItemKey($itemKey); + if (isset($writeThrough)) + { + $is->setWriteThroughStream($writeThrough); + } + return $is; + } + + /** + * Get data back out of the cache as a string. + * @param string $nsKey + * @param string $itemKey + * @return string + */ + public function getString($nsKey, $itemKey) + { + $this->_prepareCache($nsKey); + if ($this->hasKey($nsKey, $itemKey)) + { + return $this->_contents[$nsKey][$itemKey]; + } + } + + /** + * Get data back out of the cache as a ByteStream. + * @param string $nsKey + * @param string $itemKey + * @param Swift_InputByteStream $is to write the data to + */ + public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is) + { + $this->_prepareCache($nsKey); + $is->write($this->getString($nsKey, $itemKey)); + } + + /** + * Check if the given $itemKey exists in the namespace $nsKey. + * @param string $nsKey + * @param string $itemKey + * @return boolean + */ + public function hasKey($nsKey, $itemKey) + { + $this->_prepareCache($nsKey); + return array_key_exists($itemKey, $this->_contents[$nsKey]); + } + + /** + * Clear data for $itemKey in the namespace $nsKey if it exists. + * @param string $nsKey + * @param string $itemKey + */ + public function clearKey($nsKey, $itemKey) + { + unset($this->_contents[$nsKey][$itemKey]); + } + + /** + * Clear all data in the namespace $nsKey if it exists. + * @param string $nsKey + */ + public function clearAll($nsKey) + { + unset($this->_contents[$nsKey]); + } + + // -- Private methods + + /** + * Initialize the namespace of $nsKey if needed. + * @param string $nsKey + * @access private + */ + private function _prepareCache($nsKey) + { + if (!array_key_exists($nsKey, $this->_contents)) + { + $this->_contents[$nsKey] = array(); + } + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/DiskKeyCache.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/DiskKeyCache.php new file mode 100644 index 0000000..7835079 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/DiskKeyCache.php @@ -0,0 +1,333 @@ +_stream = $stream; + $this->_path = $path; + + if (function_exists('get_magic_quotes_runtime') && @get_magic_quotes_runtime() == 1) + { + $this->_quotes = true; + } + } + + /** + * Set a string into the cache under $itemKey for the namespace $nsKey. + * @param string $nsKey + * @param string $itemKey + * @param string $string + * @param int $mode + * @throws Swift_IoException + * @see MODE_WRITE, MODE_APPEND + */ + public function setString($nsKey, $itemKey, $string, $mode) + { + $this->_prepareCache($nsKey); + switch ($mode) + { + case self::MODE_WRITE: + $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START); + break; + case self::MODE_APPEND: + $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_END); + break; + default: + throw new Swift_SwiftException( + 'Invalid mode [' . $mode . '] used to set nsKey='. + $nsKey . ', itemKey=' . $itemKey + ); + break; + } + fwrite($fp, $string); + $this->_freeHandle($nsKey, $itemKey); + } + + /** + * Set a ByteStream into the cache under $itemKey for the namespace $nsKey. + * @param string $nsKey + * @param string $itemKey + * @param Swift_OutputByteStream $os + * @param int $mode + * @see MODE_WRITE, MODE_APPEND + * @throws Swift_IoException + */ + public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os, + $mode) + { + $this->_prepareCache($nsKey); + switch ($mode) + { + case self::MODE_WRITE: + $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START); + break; + case self::MODE_APPEND: + $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_END); + break; + default: + throw new Swift_SwiftException( + 'Invalid mode [' . $mode . '] used to set nsKey='. + $nsKey . ', itemKey=' . $itemKey + ); + break; + } + while (false !== $bytes = $os->read(8192)) + { + fwrite($fp, $bytes); + } + $this->_freeHandle($nsKey, $itemKey); + } + + /** + * Provides a ByteStream which when written to, writes data to $itemKey. + * NOTE: The stream will always write in append mode. + * @param string $nsKey + * @param string $itemKey + * @return Swift_InputByteStream + */ + public function getInputByteStream($nsKey, $itemKey, + Swift_InputByteStream $writeThrough = null) + { + $is = clone $this->_stream; + $is->setKeyCache($this); + $is->setNsKey($nsKey); + $is->setItemKey($itemKey); + if (isset($writeThrough)) + { + $is->setWriteThroughStream($writeThrough); + } + return $is; + } + + /** + * Get data back out of the cache as a string. + * @param string $nsKey + * @param string $itemKey + * @return string + * @throws Swift_IoException + */ + public function getString($nsKey, $itemKey) + { + $this->_prepareCache($nsKey); + if ($this->hasKey($nsKey, $itemKey)) + { + $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START); + if ($this->_quotes) + { + ini_set('magic_quotes_runtime', 0); + } + $str = ''; + while (!feof($fp) && false !== $bytes = fread($fp, 8192)) + { + $str .= $bytes; + } + if ($this->_quotes) + { + ini_set('magic_quotes_runtime', 1); + } + $this->_freeHandle($nsKey, $itemKey); + return $str; + } + } + + /** + * Get data back out of the cache as a ByteStream. + * @param string $nsKey + * @param string $itemKey + * @param Swift_InputByteStream $is to write the data to + */ + public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is) + { + if ($this->hasKey($nsKey, $itemKey)) + { + $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START); + if ($this->_quotes) + { + ini_set('magic_quotes_runtime', 0); + } + while (!feof($fp) && false !== $bytes = fread($fp, 8192)) + { + $is->write($bytes); + } + if ($this->_quotes) + { + ini_set('magic_quotes_runtime', 1); + } + $this->_freeHandle($nsKey, $itemKey); + } + } + + /** + * Check if the given $itemKey exists in the namespace $nsKey. + * @param string $nsKey + * @param string $itemKey + * @return boolean + */ + public function hasKey($nsKey, $itemKey) + { + return is_file($this->_path . '/' . $nsKey . '/' . $itemKey); + } + + /** + * Clear data for $itemKey in the namespace $nsKey if it exists. + * @param string $nsKey + * @param string $itemKey + */ + public function clearKey($nsKey, $itemKey) + { + if ($this->hasKey($nsKey, $itemKey)) + { + $this->_freeHandle($nsKey, $itemKey); + unlink($this->_path . '/' . $nsKey . '/' . $itemKey); + } + } + + /** + * Clear all data in the namespace $nsKey if it exists. + * @param string $nsKey + */ + public function clearAll($nsKey) + { + if (array_key_exists($nsKey, $this->_keys)) + { + foreach ($this->_keys[$nsKey] as $itemKey=>$null) + { + $this->clearKey($nsKey, $itemKey); + } + if (is_dir($this->_path . '/' . $nsKey)) + { + rmdir($this->_path . '/' . $nsKey); + } + unset($this->_keys[$nsKey]); + } + } + + // -- Private methods + + /** + * Initialize the namespace of $nsKey if needed. + * @param string $nsKey + * @access private + */ + private function _prepareCache($nsKey) + { + $cacheDir = $this->_path . '/' . $nsKey; + if (!is_dir($cacheDir)) + { + if (!mkdir($cacheDir)) + { + throw new Swift_IoException('Failed to create cache directory ' . $cacheDir); + } + $this->_keys[$nsKey] = array(); + } + } + + /** + * Get a file handle on the cache item. + * @param string $nsKey + * @param string $itemKey + * @param int $position + * @return resource + * @access private + */ + private function _getHandle($nsKey, $itemKey, $position) + { + if (!isset($this->_keys[$nsKey][$itemKey])) + { + $openMode = $this->hasKey($nsKey, $itemKey) + ? 'r+b' + : 'w+b' + ; + $fp = fopen($this->_path . '/' . $nsKey . '/' . $itemKey, $openMode); + $this->_keys[$nsKey][$itemKey] = $fp; + } + if (self::POSITION_START == $position) + { + fseek($this->_keys[$nsKey][$itemKey], 0, SEEK_SET); + } + elseif (self::POSITION_END == $position) + { + fseek($this->_keys[$nsKey][$itemKey], 0, SEEK_END); + } + return $this->_keys[$nsKey][$itemKey]; + } + + private function _freeHandle($nsKey, $itemKey) + { + $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_CURRENT); + fclose($fp); + $this->_keys[$nsKey][$itemKey] = null; + } + + /** + * Destructor. + */ + public function __destruct() + { + foreach ($this->_keys as $nsKey=>$null) + { + $this->clearAll($nsKey); + } + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/DummyKeyCache.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/DummyKeyCache.php new file mode 100644 index 0000000..5721c66 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/DummyKeyCache.php @@ -0,0 +1,112 @@ +. + + */ + +/** + * A basic KeyCache backed by an array. + * @package Swift + * @subpackage KeyCache + * @author Xavier De Cock + */ +class Swift_KeyCache_DummyKeyCache implements Swift_KeyCache +{ + /** + * Set a string into the cache under $itemKey for the namespace $nsKey. + * @param string $nsKey + * @param string $itemKey + * @param string $string + * @param int $mode + * @see MODE_WRITE, MODE_APPEND + */ + public function setString($nsKey, $itemKey, $string, $mode) + {} + + /** + * Set a ByteStream into the cache under $itemKey for the namespace $nsKey. + * @param string $nsKey + * @param string $itemKey + * @param Swift_OutputByteStream $os + * @param int $mode + * @see MODE_WRITE, MODE_APPEND + */ + public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os, + $mode) + {} + + /** + * Provides a ByteStream which when written to, writes data to $itemKey. + * NOTE: The stream will always write in append mode. + * @param string $nsKey + * @param string $itemKey + * @return Swift_InputByteStream + */ + public function getInputByteStream($nsKey, $itemKey, + Swift_InputByteStream $writeThrough = null) + { + return false; + } + + /** + * Get data back out of the cache as a string. + * @param string $nsKey + * @param string $itemKey + * @return string + */ + public function getString($nsKey, $itemKey) + { + return false; + } + + /** + * Get data back out of the cache as a ByteStream. + * @param string $nsKey + * @param string $itemKey + * @param Swift_InputByteStream $is to write the data to + */ + public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is) + { + return false; + } + + /** + * Check if the given $itemKey exists in the namespace $nsKey. + * @param string $nsKey + * @param string $itemKey + * @return boolean + */ + public function hasKey($nsKey, $itemKey) + { + return false; + } + + /** + * Clear data for $itemKey in the namespace $nsKey if it exists. + * @param string $nsKey + * @param string $itemKey + */ + public function clearKey($nsKey, $itemKey) + {} + + /** + * Clear all data in the namespace $nsKey if it exists. + * @param string $nsKey + */ + public function clearAll($nsKey) + {} +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/KeyCacheInputStream.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/KeyCacheInputStream.php new file mode 100644 index 0000000..f4a3f47 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/KeyCacheInputStream.php @@ -0,0 +1,51 @@ +_keyCache = $keyCache; + } + + /** + * Specify a stream to write through for each write(). + * @param Swift_InputByteStream $is + */ + public function setWriteThroughStream(Swift_InputByteStream $is) + { + $this->_writeThrough = $is; + } + + /** + * Writes $bytes to the end of the stream. + * @param string $bytes + * @param Swift_InputByteStream $is, optional + */ + public function write($bytes, Swift_InputByteStream $is = null) + { + $this->_keyCache->setString( + $this->_nsKey, $this->_itemKey, $bytes, Swift_KeyCache::MODE_APPEND + ); + if (isset($is)) + { + $is->write($bytes); + } + if (isset($this->_writeThrough)) + { + $this->_writeThrough->write($bytes); + } + } + + /** + * Not used. + */ + public function commit() + { + } + + /** + * Not used. + */ + public function bind(Swift_InputByteStream $is) + { + } + + /** + * Not used. + */ + public function unbind(Swift_InputByteStream $is) + { + } + + /** + * Flush the contents of the stream (empty it) and set the internal pointer + * to the beginning. + */ + public function flushBuffers() + { + $this->_keyCache->clearKey($this->_nsKey, $this->_itemKey); + } + + /** + * Set the nsKey which will be written to. + * @param string $nsKey + */ + public function setNsKey($nsKey) + { + $this->_nsKey = $nsKey; + } + + /** + * Set the itemKey which will be written to. + * @param string $itemKey + */ + public function setItemKey($itemKey) + { + $this->_itemKey = $itemKey; + } + + /** + * Any implementation should be cloneable, allowing the clone to access a + * separate $nsKey and $itemKey. + */ + public function __clone() + { + $this->_writeThrough = null; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/LoadBalancedTransport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/LoadBalancedTransport.php new file mode 100644 index 0000000..de3045a --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/LoadBalancedTransport.php @@ -0,0 +1,46 @@ +createDependenciesFor('transport.loadbalanced') + ); + + $this->setTransports($transports); + } + + /** + * Create a new LoadBalancedTransport instance. + * @param string $transports + * @return Swift_LoadBalancedTransport + */ + public static function newInstance($transports = array()) + { + return new self($transports); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/MailTransport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/MailTransport.php new file mode 100644 index 0000000..dd8ccac --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/MailTransport.php @@ -0,0 +1,46 @@ +createDependenciesFor('transport.mail') + ); + + $this->setExtraParams($extraParams); + } + + /** + * Create a new MailTransport instance. + * @param string $extraParams To be passed to mail() + * @return Swift_MailTransport + */ + public static function newInstance($extraParams = '-f%s') + { + return new self($extraParams); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer.php new file mode 100644 index 0000000..a0561d3 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer.php @@ -0,0 +1,118 @@ +_transport = $transport; + } + + /** + * Create a new Mailer instance. + * + * @param Swift_Transport $transport + * @return Swift_Mailer + */ + public static function newInstance(Swift_Transport $transport) + { + return new self($transport); + } + + /** + * Create a new class instance of one if the message services + * For example 'mimepart' would create a 'message.mimepart' instance + * + * @param string $service + * @return object + */ + public function createMessage($service = 'message') + { + return Swift_DependencyContainer::getInstance() + ->lookup('message.'.$service); + } + + /** + * Send the given Message like it would be sent in a mail client. + * + * All recipients (with the exception of Bcc) will be able to see the other + * recipients this message was sent to. + * + * Recipient/sender data will be retrieved from the Message object. + * + * The return value is the number of recipients who were accepted for + * delivery. + * + * @param Swift_Mime_Message $message + * @param array &$failedRecipients, optional + * @return int + */ + public function send(Swift_Mime_Message $message, &$failedRecipients = null) + { + $failedRecipients = (array) $failedRecipients; + + if (!$this->_transport->isStarted()) + { + $this->_transport->start(); + } + + $sent = 0; + + try + { + $sent = $this->_transport->send($message, $failedRecipients); + } + catch (Swift_RfcComplianceException $e) + { + foreach ($message->getTo() as $address => $name) + { + $failedRecipients[] = $address; + } + } + + return $sent; + } + + /** + * Register a plugin using a known unique key (e.g. myPlugin). + * + * @param Swift_Events_EventListener $plugin + * @param string $key + */ + public function registerPlugin(Swift_Events_EventListener $plugin) + { + $this->_transport->registerPlugin($plugin); + } + + /** + * The Transport used to send messages. + * @return Swift_Transport + */ + public function getTransport() + { + return $this->_transport; + } +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer/ArrayRecipientIterator.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer/ArrayRecipientIterator.php new file mode 100644 index 0000000..c732ebb --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer/ArrayRecipientIterator.php @@ -0,0 +1,58 @@ +_recipients = $recipients; + } + + /** + * Returns true only if there are more recipients to send to. + * @return boolean + */ + public function hasNext() + { + return !empty($this->_recipients); + } + + /** + * Returns an array where the keys are the addresses of recipients and the + * values are the names. + * e.g. ('foo@bar' => 'Foo') or ('foo@bar' => NULL) + * @return array + */ + public function nextRecipient() + { + return array_splice($this->_recipients, 0, 1); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer/RecipientIterator.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer/RecipientIterator.php new file mode 100644 index 0000000..2713841 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer/RecipientIterator.php @@ -0,0 +1,34 @@ + 'Foo') or ('foo@bar' => NULL) + * @return array + */ + public function nextRecipient(); + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/MemorySpool.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/MemorySpool.php new file mode 100644 index 0000000..6a64c52 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/MemorySpool.php @@ -0,0 +1,84 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Stores Messages in memory. + * @package Swift + * @author Fabien Potencier + */ +class Swift_MemorySpool implements Swift_Spool +{ + protected $messages = array(); + + /** + * Tests if this Transport mechanism has started. + * @return boolean + */ + public function isStarted() + { + return true; + } + + /** + * Starts this Transport mechanism. + */ + public function start() + { + } + + /** + * Stops this Transport mechanism. + */ + public function stop() + { + } + + /** + * Stores a message in the queue. + * + * @param Swift_Mime_Message $message The message to store + * + * @return boolean Whether the operation has succeeded + */ + public function queueMessage(Swift_Mime_Message $message) + { + $this->messages[] = $message; + return true; + } + + /** + * Sends messages using the given transport instance. + * + * @param Swift_Transport $transport A transport instance + * @param string[] &$failedRecipients An array of failures by-reference + * + * @return int The number of sent emails + */ + public function flushQueue(Swift_Transport $transport, &$failedRecipients = null) + { + if (!$this->messages) + { + return 0; + } + + if (!$transport->isStarted()) + { + $transport->start(); + } + + $count = 0; + while ($message = array_pop($this->messages)) + { + $count += $transport->send($message, $failedRecipients); + } + + return $count; + } +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Message.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Message.php new file mode 100644 index 0000000..2f12ede --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Message.php @@ -0,0 +1,84 @@ +createDependenciesFor('mime.message') + ); + + if (!isset($charset)) + { + $charset = Swift_DependencyContainer::getInstance() + ->lookup('properties.charset'); + } + $this->setSubject($subject); + $this->setBody($body); + $this->setCharset($charset); + if ($contentType) + { + $this->setContentType($contentType); + } + } + + /** + * Create a new Message. + * @param string $subject + * @param string $body + * @param string $contentType + * @param string $charset + * @return Swift_Mime_Message + */ + public static function newInstance($subject = null, $body = null, + $contentType = null, $charset = null) + { + return new self($subject, $body, $contentType, $charset); + } + + /** + * Add a MimePart to this Message. + * @param string|Swift_OutputByteStream $body + * @param string $contentType + * @param string $charset + */ + public function addPart($body, $contentType = null, $charset = null) + { + return $this->attach(Swift_MimePart::newInstance( + $body, $contentType, $charset + )); + } + + public function __wakeup() + { + Swift_DependencyContainer::getInstance()->createDependenciesFor('mime.message'); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Attachment.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Attachment.php new file mode 100644 index 0000000..e1c28f4 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Attachment.php @@ -0,0 +1,143 @@ +setDisposition('attachment'); + $this->setContentType('application/octet-stream'); + $this->_mimeTypes = $mimeTypes; + } + + /** + * Get the nesting level used for this attachment. + * Always returns {@link LEVEL_MIXED}. + * @return int + */ + public function getNestingLevel() + { + return self::LEVEL_MIXED; + } + + /** + * Get the Content-Disposition of this attachment. + * By default attachments have a disposition of "attachment". + * @return string + */ + public function getDisposition() + { + return $this->_getHeaderFieldModel('Content-Disposition'); + } + + /** + * Set the Content-Disposition of this attachment. + * @param string $disposition + * @return Swift_Mime_Attachment + */ + public function setDisposition($disposition) + { + if (!$this->_setHeaderFieldModel('Content-Disposition', $disposition)) + { + $this->getHeaders()->addParameterizedHeader( + 'Content-Disposition', $disposition + ); + } + return $this; + } + + /** + * Get the filename of this attachment when downloaded. + * @return string + */ + public function getFilename() + { + return $this->_getHeaderParameter('Content-Disposition', 'filename'); + } + + /** + * Set the filename of this attachment. + * @param string $filename + * @return Swift_Mime_Attachment + */ + public function setFilename($filename) + { + $this->_setHeaderParameter('Content-Disposition', 'filename', $filename); + $this->_setHeaderParameter('Content-Type', 'name', $filename); + return $this; + } + + /** + * Get the file size of this attachment. + * @return int + */ + public function getSize() + { + return $this->_getHeaderParameter('Content-Disposition', 'size'); + } + + /** + * Set the file size of this attachment. + * @param int $size + * @return Swift_Mime_Attachment + */ + public function setSize($size) + { + $this->_setHeaderParameter('Content-Disposition', 'size', $size); + return $this; + } + + /** + * Set the file that this attachment is for. + * @param Swift_FileStream $file + * @param string $contentType optional + * @return Swift_Mime_Attachment + */ + public function setFile(Swift_FileStream $file, $contentType = null) + { + $this->setFilename(basename($file->getPath())); + $this->setBody($file, $contentType); + if (!isset($contentType)) + { + $extension = strtolower(substr( + $file->getPath(), strrpos($file->getPath(), '.') + 1 + )); + + if (array_key_exists($extension, $this->_mimeTypes)) + { + $this->setContentType($this->_mimeTypes[$extension]); + } + } + return $this; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/CharsetObserver.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/CharsetObserver.php new file mode 100644 index 0000000..c26009f --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/CharsetObserver.php @@ -0,0 +1,26 @@ += $maxLineLength || 76 < $maxLineLength) + { + $maxLineLength = 76; + } + + $remainder = 0; + + while (false !== $bytes = $os->read(8190)) + { + $encoded = base64_encode($bytes); + $encodedTransformed = ''; + $thisMaxLineLength = $maxLineLength - $remainder - $firstLineOffset; + + while ($thisMaxLineLength < strlen($encoded)) + { + $encodedTransformed .= substr($encoded, 0, $thisMaxLineLength) . "\r\n"; + $firstLineOffset = 0; + $encoded = substr($encoded, $thisMaxLineLength); + $thisMaxLineLength = $maxLineLength; + $remainder = 0; + } + + if (0 < $remainingLength = strlen($encoded)) + { + $remainder += $remainingLength; + $encodedTransformed .= $encoded; + $encoded = null; + } + + $is->write($encodedTransformed); + } + } + + /** + * Get the name of this encoding scheme. + * Returns the string 'base64'. + * @return string + */ + public function getName() + { + return 'base64'; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/PlainContentEncoder.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/PlainContentEncoder.php new file mode 100644 index 0000000..7f5ad08 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/PlainContentEncoder.php @@ -0,0 +1,172 @@ +_name = $name; + $this->_canonical = $canonical; + } + + /** + * Encode a given string to produce an encoded string. + * @param string $string + * @param int $firstLineOffset, ignored + * @param int $maxLineLength - 0 means no wrapping will occur + * @return string + */ + public function encodeString($string, $firstLineOffset = 0, + $maxLineLength = 0) + { + if ($this->_canonical) + { + $string = $this->_canonicalize($string); + } + return $this->_safeWordWrap($string, $maxLineLength, "\r\n"); + } + + /** + * Encode stream $in to stream $out. + * @param Swift_OutputByteStream $in + * @param Swift_InputByteStream $out + * @param int $firstLineOffset, ignored + * @param int $maxLineLength, optional, 0 means no wrapping will occur + */ + public function encodeByteStream( + Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, + $maxLineLength = 0) + { + $leftOver = ''; + while (false !== $bytes = $os->read(8192)) + { + $toencode = $leftOver . $bytes; + if ($this->_canonical) + { + $toencode = $this->_canonicalize($toencode); + } + $wrapped = $this->_safeWordWrap($toencode, $maxLineLength, "\r\n"); + $lastLinePos = strrpos($wrapped, "\r\n"); + $leftOver = substr($wrapped, $lastLinePos); + $wrapped = substr($wrapped, 0, $lastLinePos); + + $is->write($wrapped); + } + if (strlen($leftOver)) + { + $is->write($leftOver); + } + } + + /** + * Get the name of this encoding scheme. + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Not used. + */ + public function charsetChanged($charset) + { + } + + // -- Private methods + + /** + * A safer (but weaker) wordwrap for unicode. + * @param string $string + * @param int $length + * @param string $le + * @return string + * @access private + */ + private function _safeWordwrap($string, $length = 75, $le = "\r\n") + { + if (0 >= $length) + { + return $string; + } + + $originalLines = explode($le, $string); + + $lines = array(); + $lineCount = 0; + + foreach ($originalLines as $originalLine) + { + $lines[] = ''; + $currentLine =& $lines[$lineCount++]; + + //$chunks = preg_split('/(?<=[\ \t,\.!\?\-&\+\/])/', $originalLine); + $chunks = preg_split('/(?<=\s)/', $originalLine); + + foreach ($chunks as $chunk) + { + if (0 != strlen($currentLine) + && strlen($currentLine . $chunk) > $length) + { + $lines[] = ''; + $currentLine =& $lines[$lineCount++]; + } + $currentLine .= $chunk; + } + } + + return implode("\r\n", $lines); + } + + /** + * Canonicalize string input (fix CRLF). + * @param string $string + * @return string + * @access private + */ + private function _canonicalize($string) + { + return str_replace( + array("\r\n", "\r", "\n"), + array("\n", "\n", "\r\n"), + $string + ); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php new file mode 100644 index 0000000..8d49370 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php @@ -0,0 +1,135 @@ +_dotEscape = $dotEscape; + parent::__construct($charStream, $filter); + } + + public function __sleep() + { + return array('_charStream', '_filter', '_dotEscape'); + } + + protected function getSafeMapShareId() + { + return get_class($this).($this->_dotEscape ? '.dotEscape' : ''); + } + + protected function initSafeMap() + { + parent::initSafeMap(); + if ($this->_dotEscape) { + /* Encode . as =2e for buggy remote servers */ + unset($this->_safeMap[0x2e]); + } + } + + /** + * Encode stream $in to stream $out. + * QP encoded strings have a maximum line length of 76 characters. + * If the first line needs to be shorter, indicate the difference with + * $firstLineOffset. + * @param Swift_OutputByteStream $os output stream + * @param Swift_InputByteStream $is input stream + * @param int $firstLineOffset + * @param int $maxLineLength + */ + public function encodeByteStream( + Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, + $maxLineLength = 0) + { + if ($maxLineLength > 76 || $maxLineLength <= 0) + { + $maxLineLength = 76; + } + + $thisLineLength = $maxLineLength - $firstLineOffset; + + $this->_charStream->flushContents(); + $this->_charStream->importByteStream($os); + + $currentLine = ''; + $prepend = ''; + $size=$lineLen=0; + + while (false !== $bytes = $this->_nextSequence()) + { + //If we're filtering the input + if (isset($this->_filter)) + { + //If we can't filter because we need more bytes + while ($this->_filter->shouldBuffer($bytes)) + { + //Then collect bytes into the buffer + if (false === $moreBytes = $this->_nextSequence(1)) + { + break; + } + + foreach ($moreBytes as $b) + { + $bytes[] = $b; + } + } + //And filter them + $bytes = $this->_filter->filter($bytes); + } + + $enc = $this->_encodeByteSequence($bytes, $size); + if ($currentLine && $lineLen+$size >= $thisLineLength) + { + $is->write($prepend . $this->_standardize($currentLine)); + $currentLine = ''; + $prepend = "=\r\n"; + $thisLineLength = $maxLineLength; + $lineLen=0; + } + $lineLen+=$size; + $currentLine .= $enc; + } + if (strlen($currentLine)) + { + $is->write($prepend . $this->_standardize($currentLine)); + } + } + + /** + * Get the name of this encoding scheme. + * Returns the string 'quoted-printable'. + * @return string + */ + public function getName() + { + return 'quoted-printable'; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/EmbeddedFile.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/EmbeddedFile.php new file mode 100644 index 0000000..529de7f --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/EmbeddedFile.php @@ -0,0 +1,48 @@ +setDisposition('inline'); + $this->setId($this->getId()); + } + + /** + * Get the nesting level of this EmbeddedFile. + * Returns {@link LEVEL_RELATED}. + * @return int + */ + public function getNestingLevel() + { + return self::LEVEL_RELATED; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/EncodingObserver.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/EncodingObserver.php new file mode 100644 index 0000000..021cabd --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/EncodingObserver.php @@ -0,0 +1,27 @@ +init(); + } + + public function __wakeup() + { + $this->init(); + } + + protected function init() + { + if(count(self::$_specials) > 0) + { + return; + } + + self::$_specials = array( + '(', ')', '<', '>', '[', ']', + ':', ';', '@', ',', '.', '"' + ); + + /*** Refer to RFC 2822 for ABNF grammar ***/ + + //All basic building blocks + self::$_grammar['NO-WS-CTL'] = '[\x01-\x08\x0B\x0C\x0E-\x19\x7F]'; + self::$_grammar['WSP'] = '[ \t]'; + self::$_grammar['CRLF'] = '(?:\r\n)'; + self::$_grammar['FWS'] = '(?:(?:' . self::$_grammar['WSP'] . '*' . + self::$_grammar['CRLF'] . ')?' . self::$_grammar['WSP'] . ')'; + self::$_grammar['text'] = '[\x00-\x08\x0B\x0C\x0E-\x7F]'; + self::$_grammar['quoted-pair'] = '(?:\\\\' . self::$_grammar['text'] . ')'; + self::$_grammar['ctext'] = '(?:' . self::$_grammar['NO-WS-CTL'] . + '|[\x21-\x27\x2A-\x5B\x5D-\x7E])'; + //Uses recursive PCRE (?1) -- could be a weak point?? + self::$_grammar['ccontent'] = '(?:' . self::$_grammar['ctext'] . '|' . + self::$_grammar['quoted-pair'] . '|(?1))'; + self::$_grammar['comment'] = '(\((?:' . self::$_grammar['FWS'] . '|' . + self::$_grammar['ccontent']. ')*' . self::$_grammar['FWS'] . '?\))'; + self::$_grammar['CFWS'] = '(?:(?:' . self::$_grammar['FWS'] . '?' . + self::$_grammar['comment'] . ')*(?:(?:' . self::$_grammar['FWS'] . '?' . + self::$_grammar['comment'] . ')|' . self::$_grammar['FWS'] . '))'; + self::$_grammar['qtext'] = '(?:' . self::$_grammar['NO-WS-CTL'] . + '|[\x21\x23-\x5B\x5D-\x7E])'; + self::$_grammar['qcontent'] = '(?:' . self::$_grammar['qtext'] . '|' . + self::$_grammar['quoted-pair'] . ')'; + self::$_grammar['quoted-string'] = '(?:' . self::$_grammar['CFWS'] . '?"' . + '(' . self::$_grammar['FWS'] . '?' . self::$_grammar['qcontent'] . ')*' . + self::$_grammar['FWS'] . '?"' . self::$_grammar['CFWS'] . '?)'; + self::$_grammar['atext'] = '[a-zA-Z0-9!#\$%&\'\*\+\-\/=\?\^_`\{\}\|~]'; + self::$_grammar['atom'] = '(?:' . self::$_grammar['CFWS'] . '?' . + self::$_grammar['atext'] . '+' . self::$_grammar['CFWS'] . '?)'; + self::$_grammar['dot-atom-text'] = '(?:' . self::$_grammar['atext'] . '+' . + '(\.' . self::$_grammar['atext'] . '+)*)'; + self::$_grammar['dot-atom'] = '(?:' . self::$_grammar['CFWS'] . '?' . + self::$_grammar['dot-atom-text'] . '+' . self::$_grammar['CFWS'] . '?)'; + self::$_grammar['word'] = '(?:' . self::$_grammar['atom'] . '|' . + self::$_grammar['quoted-string'] . ')'; + self::$_grammar['phrase'] = '(?:' . self::$_grammar['word'] . '+?)'; + self::$_grammar['no-fold-quote'] = '(?:"(?:' . self::$_grammar['qtext'] . + '|' . self::$_grammar['quoted-pair'] . ')*")'; + self::$_grammar['dtext'] = '(?:' . self::$_grammar['NO-WS-CTL'] . + '|[\x21-\x5A\x5E-\x7E])'; + self::$_grammar['no-fold-literal'] = '(?:\[(?:' . self::$_grammar['dtext'] . + '|' . self::$_grammar['quoted-pair'] . ')*\])'; + + //Message IDs + self::$_grammar['id-left'] = '(?:' . self::$_grammar['dot-atom-text'] . '|' . + self::$_grammar['no-fold-quote'] . ')'; + self::$_grammar['id-right'] = '(?:' . self::$_grammar['dot-atom-text'] . '|' . + self::$_grammar['no-fold-literal'] . ')'; + + //Addresses, mailboxes and paths + self::$_grammar['local-part'] = '(?:' . self::$_grammar['dot-atom'] . '|' . + self::$_grammar['quoted-string'] . ')'; + self::$_grammar['dcontent'] = '(?:' . self::$_grammar['dtext'] . '|' . + self::$_grammar['quoted-pair'] . ')'; + self::$_grammar['domain-literal'] = '(?:' . self::$_grammar['CFWS'] . '?\[(' . + self::$_grammar['FWS'] . '?' . self::$_grammar['dcontent'] . ')*?' . + self::$_grammar['FWS'] . '?\]' . self::$_grammar['CFWS'] . '?)'; + self::$_grammar['domain'] = '(?:' . self::$_grammar['dot-atom'] . '|' . + self::$_grammar['domain-literal'] . ')'; + self::$_grammar['addr-spec'] = '(?:' . self::$_grammar['local-part'] . '@' . + self::$_grammar['domain'] . ')'; + } + + /** + * Get the grammar defined for $name token. + * @param string $name execatly as written in the RFC + * @return string + */ + public function getDefinition($name) + { + if (array_key_exists($name, self::$_grammar)) + { + return self::$_grammar[$name]; + } + else + { + throw new Swift_RfcComplianceException( + "No such grammar '" . $name . "' defined." + ); + } + } + + /** + * Returns the tokens defined in RFC 2822 (and some related RFCs). + * @return array + */ + public function getGrammarDefinitions() + { + return self::$_grammar; + } + + /** + * Returns the current special characters used in the syntax which need to be escaped. + * @return array + */ + public function getSpecials() + { + return self::$_specials; + } + + /** + * Escape special characters in a string (convert to quoted-pairs). + * @param string $token + * @param string[] $include additonal chars to escape + * @param string[] $exclude chars from escaping + * @return string + */ + public function escapeSpecials($token, $include = array(), + $exclude = array()) + { + foreach ( + array_merge(array('\\'), array_diff(self::$_specials, $exclude), $include) as $char) + { + $token = str_replace($char, '\\' . $char, $token); + } + return $token; + } +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Header.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Header.php new file mode 100644 index 0000000..38fc40c --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Header.php @@ -0,0 +1,85 @@ +getName(), "\r\n"); + mb_internal_encoding($old); + return $newstring; + } + return parent::encodeString($string, $firstLineOffset, $maxLineLength); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php new file mode 100644 index 0000000..9dbb713 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php @@ -0,0 +1,70 @@ +_safeMap[$byte] = chr($byte); + } + } + + /** + * Get the name of this encoding scheme. + * Returns the string 'Q'. + * @return string + */ + public function getName() + { + return 'Q'; + } + + /** + * Takes an unencoded string and produces a Q encoded string from it. + * @param string $string to encode + * @param int $firstLineOffset, optional + * @param int $maxLineLength, optional, 0 indicates the default of 76 chars + * @return string + */ + public function encodeString($string, $firstLineOffset = 0, + $maxLineLength = 0, $charst = 'utf-8') + { + return str_replace(array(' ', '=20', "=\r\n"), array('_', '_', "\r\n"), + parent::encodeString($string, $firstLineOffset, $maxLineLength) + ); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderFactory.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderFactory.php new file mode 100644 index 0000000..13083bb --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderFactory.php @@ -0,0 +1,71 @@ +setGrammar($grammar); + } + + /** + * Set the character set used in this Header. + * @param string $charset + */ + public function setCharset($charset) + { + $this->clearCachedValueIf($charset != $this->_charset); + $this->_charset = $charset; + if (isset($this->_encoder)) + { + $this->_encoder->charsetChanged($charset); + } + } + + /** + * Get the character set used in this Header. + * @return string + */ + public function getCharset() + { + return $this->_charset; + } + + /** + * Set the language used in this Header. + * For example, for US English, 'en-us'. + * This can be unspecified. + * @param string $lang + */ + public function setLanguage($lang) + { + $this->clearCachedValueIf($this->_lang != $lang); + $this->_lang = $lang; + } + + /** + * Get the language used in this Header. + * @return string + */ + public function getLanguage() + { + return $this->_lang; + } + + /** + * Set the encoder used for encoding the header. + * @param Swift_Mime_HeaderEncoder $encoder + */ + public function setEncoder(Swift_Mime_HeaderEncoder $encoder) + { + $this->_encoder = $encoder; + $this->setCachedValue(null); + } + + /** + * Get the encoder used for encoding this Header. + * @return Swift_Mime_HeaderEncoder + */ + public function getEncoder() + { + return $this->_encoder; + } + + /** + * Set the grammar used for the header. + * @param Swift_Mime_Grammar $grammar + */ + public function setGrammar(Swift_Mime_Grammar $grammar) + { + $this->_grammar = $grammar; + $this->setCachedValue(null); + } + + /** + * Get the grammar used for this Header. + * @return Swift_Mime_Grammar + */ + public function getGrammar() + { + return $this->_grammar; + } + + /** + * Get the name of this header (e.g. charset). + * @return string + */ + public function getFieldName() + { + return $this->_name; + } + + /** + * Set the maximum length of lines in the header (excluding EOL). + * @param int $lineLength + */ + public function setMaxLineLength($lineLength) + { + $this->clearCachedValueIf($this->_lineLength != $lineLength); + $this->_lineLength = $lineLength; + } + + /** + * Get the maximum permitted length of lines in this Header. + * @return int + */ + public function getMaxLineLength() + { + return $this->_lineLength; + } + + /** + * Get this Header rendered as a RFC 2822 compliant string. + * @return string + * @throws Swift_RfcComplianceException + */ + public function toString() + { + return $this->_tokensToString($this->toTokens()); + } + + /** + * Returns a string representation of this object. + * + * @return string + * + * @see toString() + */ + public function __toString() + { + return $this->toString(); + } + + // -- Points of extension + + /** + * Set the name of this Header field. + * @param string $name + * @access protected + */ + protected function setFieldName($name) + { + $this->_name = $name; + } + + /** + * Produces a compliant, formatted RFC 2822 'phrase' based on the string given. + * @param Swift_Mime_Header $header + * @param string $string as displayed + * @param string $charset of the text + * @param Swift_Mime_HeaderEncoder $encoder + * @param boolean $shorten the first line to make remove for header name + * @return string + */ + protected function createPhrase(Swift_Mime_Header $header, $string, $charset, + Swift_Mime_HeaderEncoder $encoder = null, $shorten = false) + { + //Treat token as exactly what was given + $phraseStr = $string; + //If it's not valid + if (!preg_match('/^' . $this->getGrammar()->getDefinition('phrase') . '$/D', $phraseStr)) + { + // .. but it is just ascii text, try escaping some characters + // and make it a quoted-string + if (preg_match('/^' . $this->getGrammar()->getDefinition('text') . '*$/D', $phraseStr)) + { + $phraseStr = $this->getGrammar()->escapeSpecials( + $phraseStr, array('"'), $this->getGrammar()->getSpecials() + ); + $phraseStr = '"' . $phraseStr . '"'; + } + else // ... otherwise it needs encoding + { + //Determine space remaining on line if first line + if ($shorten) + { + $usedLength = strlen($header->getFieldName() . ': '); + } + else + { + $usedLength = 0; + } + $phraseStr = $this->encodeWords($header, $string, $usedLength); + } + } + + return $phraseStr; + } + + /** + * Encode needed word tokens within a string of input. + * @param string $input + * @param string $usedLength, optional + * @return string + */ + protected function encodeWords(Swift_Mime_Header $header, $input, + $usedLength = -1) + { + $value = ''; + + $tokens = $this->getEncodableWordTokens($input); + + foreach ($tokens as $token) + { + //See RFC 2822, Sect 2.2 (really 2.2 ??) + if ($this->tokenNeedsEncoding($token)) + { + //Don't encode starting WSP + $firstChar = substr($token, 0, 1); + switch($firstChar) + { + case ' ': + case "\t": + $value .= $firstChar; + $token = substr($token, 1); + } + + if (-1 == $usedLength) + { + $usedLength = strlen($header->getFieldName() . ': ') + strlen($value); + } + $value .= $this->getTokenAsEncodedWord($token, $usedLength); + + $header->setMaxLineLength(76); //Forefully override + } + else + { + $value .= $token; + } + } + + return $value; + } + + /** + * Test if a token needs to be encoded or not. + * @param string $token + * @return boolean + */ + protected function tokenNeedsEncoding($token) + { + return preg_match('~[\x00-\x08\x10-\x19\x7F-\xFF\r\n]~', $token); + } + + /** + * Splits a string into tokens in blocks of words which can be encoded quickly. + * @param string $string + * @return string[] + */ + protected function getEncodableWordTokens($string) + { + $tokens = array(); + + $encodedToken = ''; + //Split at all whitespace boundaries + foreach (preg_split('~(?=[\t ])~', $string) as $token) + { + if ($this->tokenNeedsEncoding($token)) + { + $encodedToken .= $token; + } + else + { + if (strlen($encodedToken) > 0) + { + $tokens[] = $encodedToken; + $encodedToken = ''; + } + $tokens[] = $token; + } + } + if (strlen($encodedToken)) + { + $tokens[] = $encodedToken; + } + + return $tokens; + } + + /** + * Get a token as an encoded word for safe insertion into headers. + * @param string $token to encode + * @param int $firstLineOffset, optional + * @return string + */ + protected function getTokenAsEncodedWord($token, $firstLineOffset = 0) + { + //Adjust $firstLineOffset to account for space needed for syntax + $charsetDecl = $this->_charset; + if (isset($this->_lang)) + { + $charsetDecl .= '*' . $this->_lang; + } + $encodingWrapperLength = strlen( + '=?' . $charsetDecl . '?' . $this->_encoder->getName() . '??=' + ); + + if ($firstLineOffset >= 75) //Does this logic need to be here? + { + $firstLineOffset = 0; + } + + $encodedTextLines = explode("\r\n", + $this->_encoder->encodeString( + $token, $firstLineOffset, 75 - $encodingWrapperLength, $this->_charset + ) + ); + + if (strtolower($this->_charset) !== 'iso-2022-jp') // special encoding for iso-2022-jp using mb_encode_mimeheader + { + foreach ($encodedTextLines as $lineNum => $line) + { + $encodedTextLines[$lineNum] = '=?' . $charsetDecl . + '?' . $this->_encoder->getName() . + '?' . $line . '?='; + } + } + + return implode("\r\n ", $encodedTextLines); + } + + /** + * Generates tokens from the given string which include CRLF as individual tokens. + * @param string $token + * @return string[] + * @access protected + */ + protected function generateTokenLines($token) + { + return preg_split('~(\r\n)~', $token, -1, PREG_SPLIT_DELIM_CAPTURE); + } + + /** + * Set a value into the cache. + * @param string $value + * @access protected + */ + protected function setCachedValue($value) + { + $this->_cachedValue = $value; + } + + /** + * Get the value in the cache. + * @return string + * @access protected + */ + protected function getCachedValue() + { + return $this->_cachedValue; + } + + /** + * Clear the cached value if $condition is met. + * @param boolean $condition + * @access protected + */ + protected function clearCachedValueIf($condition) + { + if ($condition) + { + $this->setCachedValue(null); + } + } + + // -- Private methods + + /** + * Generate a list of all tokens in the final header. + * @param string $string The string to tokenize + * @return array An array of tokens as strings + * @access protected + */ + protected function toTokens($string = null) + { + if (is_null($string)) + { + $string = $this->getFieldBody(); + } + + $tokens = array(); + + //Generate atoms; split at all invisible boundaries followed by WSP + foreach (preg_split('~(?=[ \t])~', $string) as $token) + { + $tokens = array_merge($tokens, $this->generateTokenLines($token)); + } + + return $tokens; + } + + /** + * Takes an array of tokens which appear in the header and turns them into + * an RFC 2822 compliant string, adding FWSP where needed. + * @param string[] $tokens + * @return string + * @access private + */ + private function _tokensToString(array $tokens) + { + $lineCount = 0; + $headerLines = array(); + $headerLines[] = $this->_name . ': '; + $currentLine =& $headerLines[$lineCount++]; + + //Build all tokens back into compliant header + foreach ($tokens as $i => $token) + { + //Line longer than specified maximum or token was just a new line + if (("\r\n" == $token) || + ($i > 0 && strlen($currentLine . $token) > $this->_lineLength) + && 0 < strlen($currentLine)) + { + $headerLines[] = ''; + $currentLine =& $headerLines[$lineCount++]; + } + + //Append token to the line + if ("\r\n" != $token) + { + $currentLine .= $token; + } + } + + //Implode with FWS (RFC 2822, 2.2.3) + return implode("\r\n", $headerLines) . "\r\n"; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/DateHeader.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/DateHeader.php new file mode 100644 index 0000000..bb345fd --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/DateHeader.php @@ -0,0 +1,119 @@ + + * + *
    + * @param string $name of Header + * @param Swift_Mime_Grammar $grammar + */ + public function __construct($name, Swift_Mime_Grammar $grammar) + { + $this->setFieldName($name); + parent::__construct($grammar); + } + + /** + * Get the type of Header that this instance represents. + * @return int + * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX + * @see TYPE_DATE, TYPE_ID, TYPE_PATH + */ + public function getFieldType() + { + return self::TYPE_DATE; + } + + /** + * Set the model for the field body. + * This method takes a UNIX timestamp. + * @param int $model + */ + public function setFieldBodyModel($model) + { + $this->setTimestamp($model); + } + + /** + * Get the model for the field body. + * This method returns a UNIX timestamp. + * @return mixed + */ + public function getFieldBodyModel() + { + return $this->getTimestamp(); + } + + /** + * Get the UNIX timestamp of the Date in this Header. + * @return int + */ + public function getTimestamp() + { + return $this->_timestamp; + } + + /** + * Set the UNIX timestamp of the Date in this Header. + * @param int $timestamp + */ + public function setTimestamp($timestamp) + { + if (!is_null($timestamp)) + { + $timestamp = (int) $timestamp; + } + $this->clearCachedValueIf($this->_timestamp != $timestamp); + $this->_timestamp = $timestamp; + } + + /** + * Get the string value of the body in this Header. + * This is not necessarily RFC 2822 compliant since folding white space will + * not be added at this stage (see {@link toString()} for that). + * @return string + * @see toString() + */ + public function getFieldBody() + { + if (!$this->getCachedValue()) + { + if (isset($this->_timestamp)) + { + $this->setCachedValue(date('r', $this->_timestamp)); + } + } + return $this->getCachedValue(); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/IdentificationHeader.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/IdentificationHeader.php new file mode 100644 index 0000000..0304175 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/IdentificationHeader.php @@ -0,0 +1,166 @@ +setFieldName($name); + parent::__construct($grammar); + } + + /** + * Get the type of Header that this instance represents. + * @return int + * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX + * @see TYPE_DATE, TYPE_ID, TYPE_PATH + */ + public function getFieldType() + { + return self::TYPE_ID; + } + + /** + * Set the model for the field body. + * This method takes a string ID, or an array of IDs + * @param mixed $model + * @throws Swift_RfcComplianceException + */ + public function setFieldBodyModel($model) + { + $this->setId($model); + } + + /** + * Get the model for the field body. + * This method returns an array of IDs + * @return array + */ + public function getFieldBodyModel() + { + return $this->getIds(); + } + + /** + * Set the ID used in the value of this header. + * @param string|array $id + * @throws Swift_RfcComplianceException + */ + public function setId($id) + { + $this->setIds(is_array($id) ? $id : array($id)); + } + + /** + * Get the ID used in the value of this Header. + * If multiple IDs are set only the first is returned. + * @return string + */ + public function getId() + { + if (count($this->_ids) > 0) + { + return $this->_ids[0]; + } + } + + /** + * Set a collection of IDs to use in the value of this Header. + * @param string[] $ids + * @throws Swift_RfcComplianceException + */ + public function setIds(array $ids) + { + $actualIds = array(); + + foreach ($ids as $id) + { + $this->_assertValidId($id); + $actualIds[] = $id; + } + + $this->clearCachedValueIf($this->_ids != $actualIds); + $this->_ids = $actualIds; + } + + /** + * Get the list of IDs used in this Header. + * @return string[] + */ + public function getIds() + { + return $this->_ids; + } + + /** + * Get the string value of the body in this Header. + * This is not necessarily RFC 2822 compliant since folding white space will + * not be added at this stage (see {@link toString()} for that). + * @return string + * @see toString() + * @throws Swift_RfcComplianceException + */ + public function getFieldBody() + { + if (!$this->getCachedValue()) + { + $angleAddrs = array(); + + foreach ($this->_ids as $id) + { + $angleAddrs[] = '<' . $id . '>'; + } + + $this->setCachedValue(implode(' ', $angleAddrs)); + } + return $this->getCachedValue(); + } + + /** + * Throws an Exception if the id passed does not comply with RFC 2822. + * @param string $id + * @throws Swift_RfcComplianceException + */ + private function _assertValidId($id) + { + if (!preg_match( + '/^' . $this->getGrammar()->getDefinition('id-left') . '@' . + $this->getGrammar()->getDefinition('id-right') . '$/D', + $id + )) + { + throw new Swift_RfcComplianceException( + 'Invalid ID given <' . $id . '>' + ); + } + } +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/MailboxHeader.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/MailboxHeader.php new file mode 100644 index 0000000..0664560 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/MailboxHeader.php @@ -0,0 +1,326 @@ +setFieldName($name); + $this->setEncoder($encoder); + parent::__construct($grammar); + } + + /** + * Get the type of Header that this instance represents. + * @return int + * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX + * @see TYPE_DATE, TYPE_ID, TYPE_PATH + */ + public function getFieldType() + { + return self::TYPE_MAILBOX; + } + + /** + * Set the model for the field body. + * This method takes a string, or an array of addresses. + * @param mixed $model + * @throws Swift_RfcComplianceException + */ + public function setFieldBodyModel($model) + { + $this->setNameAddresses($model); + } + + /** + * Get the model for the field body. + * This method returns an associative array like {@link getNameAddresses()} + * @return array + * @throws Swift_RfcComplianceException + */ + public function getFieldBodyModel() + { + return $this->getNameAddresses(); + } + + /** + * Set a list of mailboxes to be shown in this Header. + * The mailboxes can be a simple array of addresses, or an array of + * key=>value pairs where (email => personalName). + * Example: + * + * setNameAddresses(array( + * 'chris@swiftmailer.org' => 'Chris Corbyn', + * 'mark@swiftmailer.org' //No associated personal name + * )); + * ?> + * + * @param string|string[] $mailboxes + * @throws Swift_RfcComplianceException + * @see __construct() + * @see setAddresses() + * @see setValue() + */ + public function setNameAddresses($mailboxes) + { + $this->_mailboxes = $this->normalizeMailboxes((array) $mailboxes); + $this->setCachedValue(null); //Clear any cached value + } + + /** + * Get the full mailbox list of this Header as an array of valid RFC 2822 strings. + * Example: + * + * 'Chris Corbyn', + * 'mark@swiftmailer.org' => 'Mark Corbyn') + * ); + * print_r($header->getNameAddressStrings()); + * // array ( + * // 0 => Chris Corbyn , + * // 1 => Mark Corbyn + * // ) + * ?> + * + * @return string[] + * @throws Swift_RfcComplianceException + * @see getNameAddresses() + * @see toString() + */ + public function getNameAddressStrings() + { + return $this->_createNameAddressStrings($this->getNameAddresses()); + } + + /** + * Get all mailboxes in this Header as key=>value pairs. + * The key is the address and the value is the name (or null if none set). + * Example: + * + * 'Chris Corbyn', + * 'mark@swiftmailer.org' => 'Mark Corbyn') + * ); + * print_r($header->getNameAddresses()); + * // array ( + * // chris@swiftmailer.org => Chris Corbyn, + * // mark@swiftmailer.org => Mark Corbyn + * // ) + * ?> + * + * @return string[] + * @see getAddresses() + * @see getNameAddressStrings() + */ + public function getNameAddresses() + { + return $this->_mailboxes; + } + + /** + * Makes this Header represent a list of plain email addresses with no names. + * Example: + * + * setAddresses( + * array('one@domain.tld', 'two@domain.tld', 'three@domain.tld') + * ); + * ?> + * + * @param string[] $addresses + * @throws Swift_RfcComplianceException + * @see setNameAddresses() + * @see setValue() + */ + public function setAddresses($addresses) + { + $this->setNameAddresses(array_values((array) $addresses)); + } + + /** + * Get all email addresses in this Header. + * @return string[] + * @see getNameAddresses() + */ + public function getAddresses() + { + return array_keys($this->_mailboxes); + } + + /** + * Remove one or more addresses from this Header. + * @param string|string[] $addresses + */ + public function removeAddresses($addresses) + { + $this->setCachedValue(null); + foreach ((array) $addresses as $address) + { + unset($this->_mailboxes[$address]); + } + } + + /** + * Get the string value of the body in this Header. + * This is not necessarily RFC 2822 compliant since folding white space will + * not be added at this stage (see {@link toString()} for that). + * @return string + * @throws Swift_RfcComplianceException + * @see toString() + */ + public function getFieldBody() + { + //Compute the string value of the header only if needed + if (is_null($this->getCachedValue())) + { + $this->setCachedValue($this->createMailboxListString($this->_mailboxes)); + } + return $this->getCachedValue(); + } + + // -- Points of extension + + /** + * Normalizes a user-input list of mailboxes into consistent key=>value pairs. + * @param string[] $mailboxes + * @return string[] + * @access protected + */ + protected function normalizeMailboxes(array $mailboxes) + { + $actualMailboxes = array(); + + foreach ($mailboxes as $key => $value) + { + if (is_string($key)) //key is email addr + { + $address = $key; + $name = $value; + } + else + { + $address = $value; + $name = null; + } + $this->_assertValidAddress($address); + $actualMailboxes[$address] = $name; + } + + return $actualMailboxes; + } + + /** + * Produces a compliant, formatted display-name based on the string given. + * @param string $displayName as displayed + * @param boolean $shorten the first line to make remove for header name + * @return string + * @access protected + */ + protected function createDisplayNameString($displayName, $shorten = false) + { + return $this->createPhrase($this, $displayName, + $this->getCharset(), $this->getEncoder(), $shorten + ); + } + + /** + * Creates a string form of all the mailboxes in the passed array. + * @param string[] $mailboxes + * @return string + * @throws Swift_RfcComplianceException + * @access protected + */ + protected function createMailboxListString(array $mailboxes) + { + return implode(', ', $this->_createNameAddressStrings($mailboxes)); + } + + /** + * Redefine the encoding requirements for mailboxes. Commas and semicolons are used to separate + * multiple addresses, and should therefore be encoded + * @param string $token + * @return boolean + */ + protected function tokenNeedsEncoding($token) + { + return preg_match('/[,;]/', $token) || parent::tokenNeedsEncoding($token); + } + + // -- Private methods + + /** + * Return an array of strings conforming the the name-addr spec of RFC 2822. + * @param string[] $mailboxes + * @return string[] + * @access private + */ + private function _createNameAddressStrings(array $mailboxes) + { + $strings = array(); + + foreach ($mailboxes as $email => $name) + { + $mailboxStr = $email; + if (!is_null($name)) + { + $nameStr = $this->createDisplayNameString($name, empty($strings)); + $mailboxStr = $nameStr . ' <' . $mailboxStr . '>'; + } + $strings[] = $mailboxStr; + } + + return $strings; + } + + /** + * Throws an Exception if the address passed does not comply with RFC 2822. + * @param string $address + * @throws Swift_RfcComplianceException If invalid. + * @access private + */ + private function _assertValidAddress($address) + { + if (!preg_match('/^' . $this->getGrammar()->getDefinition('addr-spec') . '$/D', + $address)) + { + throw new Swift_RfcComplianceException( + 'Address in mailbox given [' . $address . + '] does not comply with RFC 2822, 3.6.2.' + ); + } + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/ParameterizedHeader.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/ParameterizedHeader.php new file mode 100644 index 0000000..0a31b2d --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/ParameterizedHeader.php @@ -0,0 +1,268 @@ +_paramEncoder = $paramEncoder; + } + + /** + * Get the type of Header that this instance represents. + * @return int + * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX + * @see TYPE_DATE, TYPE_ID, TYPE_PATH + */ + public function getFieldType() + { + return self::TYPE_PARAMETERIZED; + } + + /** + * Set the character set used in this Header. + * @param string $charset + */ + public function setCharset($charset) + { + parent::setCharset($charset); + if (isset($this->_paramEncoder)) + { + $this->_paramEncoder->charsetChanged($charset); + } + } + + /** + * Set the value of $parameter. + * @param string $parameter + * @param string $value + */ + public function setParameter($parameter, $value) + { + $this->setParameters(array_merge($this->getParameters(), array($parameter => $value))); + } + + /** + * Get the value of $parameter. + * @return string + */ + public function getParameter($parameter) + { + $params = $this->getParameters(); + return array_key_exists($parameter, $params) + ? $params[$parameter] + : null; + } + + /** + * Set an associative array of parameter names mapped to values. + * @param string[] + */ + public function setParameters(array $parameters) + { + $this->clearCachedValueIf($this->_params != $parameters); + $this->_params = $parameters; + } + + /** + * Returns an associative array of parameter names mapped to values. + * @return string[] + */ + public function getParameters() + { + return $this->_params; + } + + /** + * Get the value of this header prepared for rendering. + * @return string + */ + public function getFieldBody() //TODO: Check caching here + { + $body = parent::getFieldBody(); + foreach ($this->_params as $name => $value) + { + if (!is_null($value)) + { + //Add the parameter + $body .= '; ' . $this->_createParameter($name, $value); + } + } + return $body; + } + + // -- Protected methods + + /** + * Generate a list of all tokens in the final header. + * This doesn't need to be overridden in theory, but it is for implementation + * reasons to prevent potential breakage of attributes. + * @param string $string The string to tokenize + * @return array An array of tokens as strings + * @access protected + */ + protected function toTokens($string = null) + { + $tokens = parent::toTokens(parent::getFieldBody()); + + //Try creating any parameters + foreach ($this->_params as $name => $value) + { + if (!is_null($value)) + { + //Add the semi-colon separator + $tokens[count($tokens)-1] .= ';'; + $tokens = array_merge($tokens, $this->generateTokenLines( + ' ' . $this->_createParameter($name, $value) + )); + } + } + + return $tokens; + } + + // -- Private methods + + /** + * Render a RFC 2047 compliant header parameter from the $name and $value. + * @param string $name + * @param string $value + * @return string + * @access private + */ + private function _createParameter($name, $value) + { + $origValue = $value; + + $encoded = false; + //Allow room for parameter name, indices, "=" and DQUOTEs + $maxValueLength = $this->getMaxLineLength() - strlen($name . '=*N"";') - 1; + $firstLineOffset = 0; + + //If it's not already a valid parameter value... + if (!preg_match('/^' . self::TOKEN_REGEX . '$/D', $value)) + { + //TODO: text, or something else?? + //... and it's not ascii + if (!preg_match('/^' . $this->getGrammar()->getDefinition('text') . '*$/D', $value)) + { + $encoded = true; + //Allow space for the indices, charset and language + $maxValueLength = $this->getMaxLineLength() - strlen($name . '*N*="";') - 1; + $firstLineOffset = strlen( + $this->getCharset() . "'" . $this->getLanguage() . "'" + ); + } + } + + //Encode if we need to + if ($encoded || strlen($value) > $maxValueLength) + { + if (isset($this->_paramEncoder)) + { + $value = $this->_paramEncoder->encodeString( + $origValue, $firstLineOffset, $maxValueLength, $this->getCharset() + ); + } + else //We have to go against RFC 2183/2231 in some areas for interoperability + { + $value = $this->getTokenAsEncodedWord($origValue); + $encoded = false; + } + } + + $valueLines = isset($this->_paramEncoder) ? explode("\r\n", $value) : array($value); + + //Need to add indices + if (count($valueLines) > 1) + { + $paramLines = array(); + foreach ($valueLines as $i => $line) + { + $paramLines[] = $name . '*' . $i . + $this->_getEndOfParameterValue($line, true, $i == 0); + } + return implode(";\r\n ", $paramLines); + } + else + { + return $name . $this->_getEndOfParameterValue( + $valueLines[0], $encoded, true + ); + } + } + + /** + * Returns the parameter value from the "=" and beyond. + * @param string $value to append + * @param boolean $encoded + * @param boolean $firstLine + * @return string + * @access private + */ + private function _getEndOfParameterValue($value, $encoded = false, $firstLine = false) + { + if (!preg_match('/^' . self::TOKEN_REGEX . '$/D', $value)) + { + $value = '"' . $value . '"'; + } + $prepend = '='; + if ($encoded) + { + $prepend = '*='; + if ($firstLine) + { + $prepend = '*=' . $this->getCharset() . "'" . $this->getLanguage() . + "'"; + } + } + return $prepend . $value; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/PathHeader.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/PathHeader.php new file mode 100644 index 0000000..7f1252d --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/PathHeader.php @@ -0,0 +1,140 @@ +setFieldName($name); + parent::__construct($grammar); + } + + /** + * Get the type of Header that this instance represents. + * @return int + * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX + * @see TYPE_DATE, TYPE_ID, TYPE_PATH + */ + public function getFieldType() + { + return self::TYPE_PATH; + } + + /** + * Set the model for the field body. + * This method takes a string for an address. + * @param string $model + * @throws Swift_RfcComplianceException + */ + public function setFieldBodyModel($model) + { + $this->setAddress($model); + } + + /** + * Get the model for the field body. + * This method returns a string email address. + * @return mixed + */ + public function getFieldBodyModel() + { + return $this->getAddress(); + } + + /** + * Set the Address which should appear in this Header. + * @param string $address + * @throws Swift_RfcComplianceException + */ + public function setAddress($address) + { + if (is_null($address)) + { + $this->_address = null; + } + elseif ('' == $address) + { + $this->_address = ''; + } + else + { + $this->_assertValidAddress($address); + $this->_address = $address; + } + $this->setCachedValue(null); + } + + /** + * Get the address which is used in this Header (if any). + * Null is returned if no address is set. + * @return string + */ + public function getAddress() + { + return $this->_address; + } + + /** + * Get the string value of the body in this Header. + * This is not necessarily RFC 2822 compliant since folding white space will + * not be added at this stage (see {@link toString()} for that). + * @return string + * @see toString() + */ + public function getFieldBody() + { + if (!$this->getCachedValue()) + { + if (isset($this->_address)) + { + $this->setCachedValue('<' . $this->_address . '>'); + } + } + return $this->getCachedValue(); + } + + /** + * Throws an Exception if the address passed does not comply with RFC 2822. + * @param string $address + * @throws Swift_RfcComplianceException If invalid. + * @access private + */ + private function _assertValidAddress($address) + { + if (!preg_match('/^' . $this->getGrammar()->getDefinition('addr-spec') . '$/D', + $address)) + { + throw new Swift_RfcComplianceException( + 'Address set in PathHeader does not comply with addr-spec of RFC 2822.' + ); + } + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/UnstructuredHeader.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/UnstructuredHeader.php new file mode 100644 index 0000000..491d7eb --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/UnstructuredHeader.php @@ -0,0 +1,107 @@ +setFieldName($name); + $this->setEncoder($encoder); + parent::__construct($grammar); + } + + /** + * Get the type of Header that this instance represents. + * @return int + * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX + * @see TYPE_DATE, TYPE_ID, TYPE_PATH + */ + public function getFieldType() + { + return self::TYPE_TEXT; + } + + /** + * Set the model for the field body. + * This method takes a string for the field value. + * @param string $model + */ + public function setFieldBodyModel($model) + { + $this->setValue($model); + } + + /** + * Get the model for the field body. + * This method returns a string. + * @return string + */ + public function getFieldBodyModel() + { + return $this->getValue(); + } + + /** + * Get the (unencoded) value of this header. + * @return string + */ + public function getValue() + { + return $this->_value; + } + + /** + * Set the (unencoded) value of this header. + * @param string $value + */ + public function setValue($value) + { + $this->clearCachedValueIf($this->_value != $value); + $this->_value = $value; + } + + /** + * Get the value of this header prepared for rendering. + * @return string + */ + public function getFieldBody() + { + if (!$this->getCachedValue()) + { + $this->setCachedValue( + $this->encodeWords($this, $this->_value) + ); + } + return $this->getCachedValue(); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Message.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Message.php new file mode 100644 index 0000000..497f36e --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Message.php @@ -0,0 +1,229 @@ + 'Real Name'). + * + * If the second parameter is provided and the first is a string, then $name + * is associated with the address. + * + * @param mixed $address + * @param string $name optional + */ + public function setSender($address, $name = null); + + /** + * Get the sender address for this message. + * + * This has a higher significance than the From address. + * + * @return string + */ + public function getSender(); + + /** + * Set the From address of this message. + * + * It is permissible for multiple From addresses to be set using an array. + * + * If multiple From addresses are used, you SHOULD set the Sender address and + * according to RFC 2822, MUST set the sender address. + * + * An array can be used if display names are to be provided: i.e. + * array('email@address.com' => 'Real Name'). + * + * If the second parameter is provided and the first is a string, then $name + * is associated with the address. + * + * @param mixed $addresses + * @param string $name optional + */ + public function setFrom($addresses, $name = null); + + /** + * Get the From address(es) of this message. + * + * This method always returns an associative array where the keys are the + * addresses. + * + * @return string[] + */ + public function getFrom(); + + /** + * Set the Reply-To address(es). + * + * Any replies from the receiver will be sent to this address. + * + * It is permissible for multiple reply-to addresses to be set using an array. + * + * This method has the same synopsis as {@link setFrom()} and {@link setTo()}. + * + * If the second parameter is provided and the first is a string, then $name + * is associated with the address. + * + * @param mixed $addresses + * @param string $name optional + */ + public function setReplyTo($addresses, $name = null); + + /** + * Get the Reply-To addresses for this message. + * + * This method always returns an associative array where the keys provide the + * email addresses. + * + * @return string[] + */ + public function getReplyTo(); + + /** + * Set the To address(es). + * + * Recipients set in this field will receive a copy of this message. + * + * This method has the same synopsis as {@link setFrom()} and {@link setCc()}. + * + * If the second parameter is provided and the first is a string, then $name + * is associated with the address. + * + * @param mixed $addresses + * @param string $name optional + */ + public function setTo($addresses, $name = null); + + /** + * Get the To addresses for this message. + * + * This method always returns an associative array, whereby the keys provide + * the actual email addresses. + * + * @return string[] + */ + public function getTo(); + + /** + * Set the Cc address(es). + * + * Recipients set in this field will receive a 'carbon-copy' of this message. + * + * This method has the same synopsis as {@link setFrom()} and {@link setTo()}. + * + * @param mixed $addresses + * @param string $name optional + */ + public function setCc($addresses, $name = null); + + /** + * Get the Cc addresses for this message. + * + * This method always returns an associative array, whereby the keys provide + * the actual email addresses. + * + * @return string[] + */ + public function getCc(); + + /** + * Set the Bcc address(es). + * + * Recipients set in this field will receive a 'blind-carbon-copy' of this + * message. + * + * In other words, they will get the message, but any other recipients of the + * message will have no such knowledge of their receipt of it. + * + * This method has the same synopsis as {@link setFrom()} and {@link setTo()}. + * + * @param mixed $addresses + * @param string $name optional + */ + public function setBcc($addresses, $name = null); + + /** + * Get the Bcc addresses for this message. + * + * This method always returns an associative array, whereby the keys provide + * the actual email addresses. + * + * @return string[] + */ + public function getBcc(); + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/MimeEntity.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/MimeEntity.php new file mode 100644 index 0000000..b46c296 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/MimeEntity.php @@ -0,0 +1,105 @@ +setContentType('text/plain'); + if (!is_null($charset)) + { + $this->setCharset($charset); + } + } + + /** + * Set the body of this entity, either as a string, or as an instance of + * {@link Swift_OutputByteStream}. + * + * @param mixed $body + * @param string $contentType optional + * @param string $charset optional + * @param Swift_Mime_MimePart + */ + public function setBody($body, $contentType = null, $charset = null) + { + if (isset($charset)) + { + $this->setCharset($charset); + } + $body = $this->_convertString($body); + + parent::setBody($body, $contentType); + + return $this; + } + + /** + * Get the character set of this entity. + * + * @return string + */ + public function getCharset() + { + return $this->_getHeaderParameter('Content-Type', 'charset'); + } + + /** + * Set the character set of this entity. + * + * @param string $charset + * @param Swift_Mime_MimePart + */ + public function setCharset($charset) + { + $this->_setHeaderParameter('Content-Type', 'charset', $charset); + if ($charset !== $this->_userCharset) + { + $this->_clearCache(); + } + $this->_userCharset = $charset; + parent::charsetChanged($charset); + return $this; + } + + /** + * Get the format of this entity (i.e. flowed or fixed). + * + * @return string + */ + public function getFormat() + { + return $this->_getHeaderParameter('Content-Type', 'format'); + } + + /** + * Set the format of this entity (flowed or fixed). + * + * @param string $format + * @param Swift_Mime_MimePart + */ + public function setFormat($format) + { + $this->_setHeaderParameter('Content-Type', 'format', $format); + $this->_userFormat = $format; + return $this; + } + + /** + * Test if delsp is being used for this entity. + * + * @return boolean + */ + public function getDelSp() + { + return ($this->_getHeaderParameter('Content-Type', 'delsp') == 'yes') + ? true + : false; + } + + /** + * Turn delsp on or off for this entity. + * + * @param boolean $delsp + * @param Swift_Mime_MimePart + */ + public function setDelSp($delsp = true) + { + $this->_setHeaderParameter('Content-Type', 'delsp', $delsp ? 'yes' : null); + $this->_userDelSp = $delsp; + return $this; + } + + /** + * Get the nesting level of this entity. + * + * @return int + * @see LEVEL_TOP, LEVEL_ALTERNATIVE, LEVEL_MIXED, LEVEL_RELATED + */ + public function getNestingLevel() + { + return $this->_nestingLevel; + } + + /** + * Receive notification that the charset has changed on this document, or a + * parent document. + * + * @param string $charset + */ + public function charsetChanged($charset) + { + $this->setCharset($charset); + } + + // -- Protected methods + + /** Fix the content-type and encoding of this entity */ + protected function _fixHeaders() + { + parent::_fixHeaders(); + if (count($this->getChildren())) + { + $this->_setHeaderParameter('Content-Type', 'charset', null); + $this->_setHeaderParameter('Content-Type', 'format', null); + $this->_setHeaderParameter('Content-Type', 'delsp', null); + } + else + { + $this->setCharset($this->_userCharset); + $this->setFormat($this->_userFormat); + $this->setDelSp($this->_userDelSp); + } + } + + /** Set the nesting level of this entity */ + protected function _setNestingLevel($level) + { + $this->_nestingLevel = $level; + } + + /** Encode charset when charset is not utf-8 */ + protected function _convertString($string) + { + $charset = strtolower($this->getCharset()); + if (!in_array($charset, array('utf-8', 'iso-8859-1', ""))) + { + // mb_convert_encoding must be the first one to check, since iconv cannot convert some words. + if (function_exists('mb_convert_encoding')) + { + $string = mb_convert_encoding($string, $charset, 'utf-8'); + } + else if (function_exists('iconv')) + { + $string = iconv($charset, 'utf-8//TRANSLIT//IGNORE', $string); + } + else + { + throw new Swift_SwiftException('No suitable convert encoding function (use UTF-8 as your harset or install the mbstring or iconv extension).'); + } + return $string; + } + return $string; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ParameterizedHeader.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ParameterizedHeader.php new file mode 100644 index 0000000..12e3586 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ParameterizedHeader.php @@ -0,0 +1,34 @@ +_encoder = $encoder; + $this->_paramEncoder = $paramEncoder; + $this->_grammar = $grammar; + $this->_charset = $charset; + } + + /** + * Create a new Mailbox Header with a list of $addresses. + * @param string $name + * @param array|string $addresses + * @return Swift_Mime_Header + */ + public function createMailboxHeader($name, $addresses = null) + { + $header = new Swift_Mime_Headers_MailboxHeader($name, $this->_encoder, $this->_grammar); + if (isset($addresses)) + { + $header->setFieldBodyModel($addresses); + } + $this->_setHeaderCharset($header); + return $header; + } + + /** + * Create a new Date header using $timestamp (UNIX time). + * @param string $name + * @param int $timestamp + * @return Swift_Mime_Header + */ + public function createDateHeader($name, $timestamp = null) + { + $header = new Swift_Mime_Headers_DateHeader($name, $this->_grammar); + if (isset($timestamp)) + { + $header->setFieldBodyModel($timestamp); + } + $this->_setHeaderCharset($header); + return $header; + } + + /** + * Create a new basic text header with $name and $value. + * @param string $name + * @param string $value + * @return Swift_Mime_Header + */ + public function createTextHeader($name, $value = null) + { + $header = new Swift_Mime_Headers_UnstructuredHeader($name, $this->_encoder, $this->_grammar); + if (isset($value)) + { + $header->setFieldBodyModel($value); + } + $this->_setHeaderCharset($header); + return $header; + } + + /** + * Create a new ParameterizedHeader with $name, $value and $params. + * @param string $name + * @param string $value + * @param array $params + * @return Swift_Mime_ParameterizedHeader + */ + public function createParameterizedHeader($name, $value = null, + $params = array()) + { + $header = new Swift_Mime_Headers_ParameterizedHeader($name, + $this->_encoder, (strtolower($name) == 'content-disposition') + ? $this->_paramEncoder + : null, + $this->_grammar + ); + if (isset($value)) + { + $header->setFieldBodyModel($value); + } + foreach ($params as $k => $v) + { + $header->setParameter($k, $v); + } + $this->_setHeaderCharset($header); + return $header; + } + + /** + * Create a new ID header for Message-ID or Content-ID. + * @param string $name + * @param string|array $ids + * @return Swift_Mime_Header + */ + public function createIdHeader($name, $ids = null) + { + $header = new Swift_Mime_Headers_IdentificationHeader($name, $this->_grammar); + if (isset($ids)) + { + $header->setFieldBodyModel($ids); + } + $this->_setHeaderCharset($header); + return $header; + } + + /** + * Create a new Path header with an address (path) in it. + * @param string $name + * @param string $path + * @return Swift_Mime_Header + */ + public function createPathHeader($name, $path = null) + { + $header = new Swift_Mime_Headers_PathHeader($name, $this->_grammar); + if (isset($path)) + { + $header->setFieldBodyModel($path); + } + $this->_setHeaderCharset($header); + return $header; + } + + /** + * Notify this observer that the entity's charset has changed. + * @param string $charset + */ + public function charsetChanged($charset) + { + $this->_charset = $charset; + $this->_encoder->charsetChanged($charset); + $this->_paramEncoder->charsetChanged($charset); + } + + // -- Private methods + + /** Apply the charset to the Header */ + private function _setHeaderCharset(Swift_Mime_Header $header) + { + if (isset($this->_charset)) + { + $header->setCharset($this->_charset); + } + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderSet.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderSet.php new file mode 100644 index 0000000..e3435ad --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderSet.php @@ -0,0 +1,394 @@ +_factory = $factory; + if (isset($charset)) + { + $this->setCharset($charset); + } + } + + /** + * Set the charset used by these headers. + * + * @param string $charset + */ + public function setCharset($charset) + { + $this->_charset = $charset; + $this->_factory->charsetChanged($charset); + $this->_notifyHeadersOfCharset($charset); + } + + /** + * Add a new Mailbox Header with a list of $addresses. + * + * @param string $name + * @param array|string $addresses + */ + public function addMailboxHeader($name, $addresses = null) + { + $this->_storeHeader($name, + $this->_factory->createMailboxHeader($name, $addresses)); + } + + /** + * Add a new Date header using $timestamp (UNIX time). + * + * @param string $name + * @param int $timestamp + */ + public function addDateHeader($name, $timestamp = null) + { + $this->_storeHeader($name, + $this->_factory->createDateHeader($name, $timestamp)); + } + + /** + * Add a new basic text header with $name and $value. + * + * @param string $name + * @param string $value + */ + public function addTextHeader($name, $value = null) + { + $this->_storeHeader($name, + $this->_factory->createTextHeader($name, $value)); + } + + /** + * Add a new ParameterizedHeader with $name, $value and $params. + * + * @param string $name + * @param string $value + * @param array $params + */ + public function addParameterizedHeader($name, $value = null, + $params = array()) + { + $this->_storeHeader($name, + $this->_factory->createParameterizedHeader($name, $value, + $params)); + } + + /** + * Add a new ID header for Message-ID or Content-ID. + * + * @param string $name + * @param string|array $ids + */ + public function addIdHeader($name, $ids = null) + { + $this->_storeHeader($name, $this->_factory->createIdHeader($name, $ids)); + } + + /** + * Add a new Path header with an address (path) in it. + * + * @param string $name + * @param string $path + */ + public function addPathHeader($name, $path = null) + { + $this->_storeHeader($name, $this->_factory->createPathHeader($name, $path)); + } + + /** + * Returns true if at least one header with the given $name exists. + * + * If multiple headers match, the actual one may be specified by $index. + * + * @param string $name + * @param int $index + * + * @return boolean + */ + public function has($name, $index = 0) + { + $lowerName = strtolower($name); + return array_key_exists($lowerName, $this->_headers) + && array_key_exists($index, $this->_headers[$lowerName]); + } + + /** + * Set a header in the HeaderSet. + * + * The header may be a previously fetched header via {@link get()} or it may + * be one that has been created separately. + * + * If $index is specified, the header will be inserted into the set at this + * offset. + * + * @param Swift_Mime_Header $header + * @param int $index + */ + public function set(Swift_Mime_Header $header, $index = 0) + { + $this->_storeHeader($header->getFieldName(), $header, $index); + } + + /** + * Get the header with the given $name. + * + * If multiple headers match, the actual one may be specified by $index. + * Returns NULL if none present. + * + * @param string $name + * @param int $index + * + * @return Swift_Mime_Header + */ + public function get($name, $index = 0) + { + if ($this->has($name, $index)) + { + $lowerName = strtolower($name); + return $this->_headers[$lowerName][$index]; + } + } + + /** + * Get all headers with the given $name. + * + * @param string $name + * + * @return array + */ + public function getAll($name = null) + { + if (!isset($name)) + { + $headers = array(); + foreach ($this->_headers as $collection) + { + $headers = array_merge($headers, $collection); + } + return $headers; + } + + $lowerName = strtolower($name); + if (!array_key_exists($lowerName, $this->_headers)) + { + return array(); + } + return $this->_headers[$lowerName]; + } + + /** + * Remove the header with the given $name if it's set. + * + * If multiple headers match, the actual one may be specified by $index. + * + * @param string $name + * @param int $index + */ + public function remove($name, $index = 0) + { + $lowerName = strtolower($name); + unset($this->_headers[$lowerName][$index]); + } + + /** + * Remove all headers with the given $name. + * + * @param string $name + */ + public function removeAll($name) + { + $lowerName = strtolower($name); + unset($this->_headers[$lowerName]); + } + + /** + * Create a new instance of this HeaderSet. + * + * @return Swift_Mime_HeaderSet + */ + public function newInstance() + { + return new self($this->_factory); + } + + /** + * Define a list of Header names as an array in the correct order. + * + * These Headers will be output in the given order where present. + * + * @param array $sequence + */ + public function defineOrdering(array $sequence) + { + $this->_order = array_flip(array_map('strtolower', $sequence)); + } + + /** + * Set a list of header names which must always be displayed when set. + * + * Usually headers without a field value won't be output unless set here. + * + * @param array $names + */ + public function setAlwaysDisplayed(array $names) + { + $this->_required = array_flip(array_map('strtolower', $names)); + } + + /** + * Notify this observer that the entity's charset has changed. + * + * @param string $charset + */ + public function charsetChanged($charset) + { + $this->setCharset($charset); + } + + /** + * Returns a string with a representation of all headers. + * + * @return string + */ + public function toString() + { + $string = ''; + $headers = $this->_headers; + if ($this->_canSort()) + { + uksort($headers, array($this, '_sortHeaders')); + } + foreach ($headers as $collection) + { + foreach ($collection as $header) + { + if ($this->_isDisplayed($header) || $header->getFieldBody() != '') + { + $string .= $header->toString(); + } + } + } + return $string; + } + + /** + * Returns a string representation of this object. + * + * @return string + * + * @see toString() + */ + public function __toString() + { + return $this->toString(); + } + + // -- Private methods + + /** Save a Header to the internal collection */ + private function _storeHeader($name, Swift_Mime_Header $header, $offset = null) + { + if (!isset($this->_headers[strtolower($name)])) + { + $this->_headers[strtolower($name)] = array(); + } + if (!isset($offset)) + { + $this->_headers[strtolower($name)][] = $header; + } + else + { + $this->_headers[strtolower($name)][$offset] = $header; + } + } + + /** Test if the headers can be sorted */ + private function _canSort() + { + return count($this->_order) > 0; + } + + /** uksort() algorithm for Header ordering */ + private function _sortHeaders($a, $b) + { + $lowerA = strtolower($a); + $lowerB = strtolower($b); + $aPos = array_key_exists($lowerA, $this->_order) + ? $this->_order[$lowerA] + : -1; + $bPos = array_key_exists($lowerB, $this->_order) + ? $this->_order[$lowerB] + : -1; + + if ($aPos == -1) + { + return 1; + } + elseif ($bPos == -1) + { + return -1; + } + + return ($aPos < $bPos) ? -1 : 1; + } + + /** Test if the given Header is always displayed */ + private function _isDisplayed(Swift_Mime_Header $header) + { + return array_key_exists(strtolower($header->getFieldName()), $this->_required); + } + + /** Notify all Headers of the new charset */ + private function _notifyHeadersOfCharset($charset) + { + foreach ($this->_headers as $headerGroup) + { + foreach ($headerGroup as $header) + { + $header->setCharset($charset); + } + } + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleMessage.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleMessage.php new file mode 100644 index 0000000..c8fdb34 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleMessage.php @@ -0,0 +1,622 @@ +getHeaders()->defineOrdering(array( + 'Return-Path', + 'Sender', + 'Message-ID', + 'Date', + 'Subject', + 'From', + 'Reply-To', + 'To', + 'Cc', + 'Bcc', + 'MIME-Version', + 'Content-Type', + 'Content-Transfer-Encoding' + )); + $this->getHeaders()->setAlwaysDisplayed( + array('Date', 'Message-ID', 'From') + ); + $this->getHeaders()->addTextHeader('MIME-Version', '1.0'); + $this->setDate(time()); + $this->setId($this->getId()); + $this->getHeaders()->addMailboxHeader('From'); + } + + /** + * Always returns {@link LEVEL_TOP} for a message instance. + * @return int + */ + public function getNestingLevel() + { + return self::LEVEL_TOP; + } + + /** + * Set the subject of this message. + * @param string $subject + * @return Swift_Mime_SimpleMessage + */ + public function setSubject($subject) + { + if (!$this->_setHeaderFieldModel('Subject', $subject)) + { + $this->getHeaders()->addTextHeader('Subject', $subject); + } + return $this; + } + + /** + * Get the subject of this message. + * @return string + */ + public function getSubject() + { + return $this->_getHeaderFieldModel('Subject'); + } + + /** + * Set the date at which this message was created. + * @param int $date + * @return Swift_Mime_SimpleMessage + */ + public function setDate($date) + { + if (!$this->_setHeaderFieldModel('Date', $date)) + { + $this->getHeaders()->addDateHeader('Date', $date); + } + return $this; + } + + /** + * Get the date at which this message was created. + * @return int + */ + public function getDate() + { + return $this->_getHeaderFieldModel('Date'); + } + + /** + * Set the return-path (the bounce address) of this message. + * @param string $address + * @return Swift_Mime_SimpleMessage + */ + public function setReturnPath($address) + { + if (!$this->_setHeaderFieldModel('Return-Path', $address)) + { + $this->getHeaders()->addPathHeader('Return-Path', $address); + } + return $this; + } + + /** + * Get the return-path (bounce address) of this message. + * @return string + */ + public function getReturnPath() + { + return $this->_getHeaderFieldModel('Return-Path'); + } + + /** + * Set the sender of this message. + * This does not override the From field, but it has a higher significance. + * @param string $sender + * @param string $name optional + * @return Swift_Mime_SimpleMessage + */ + public function setSender($address, $name = null) + { + if (!is_array($address) && isset($name)) + { + $address = array($address => $name); + } + + if (!$this->_setHeaderFieldModel('Sender', (array) $address)) + { + $this->getHeaders()->addMailboxHeader('Sender', (array) $address); + } + return $this; + } + + /** + * Get the sender of this message. + * @return string + */ + public function getSender() + { + return $this->_getHeaderFieldModel('Sender'); + } + + /** + * Add a From: address to this message. + * + * If $name is passed this name will be associated with the address. + * + * @param string $address + * @param string $name optional + */ + public function addFrom($address, $name = null) + { + $current = $this->getFrom(); + $current[$address] = $name; + return $this->setFrom($current); + } + + /** + * Set the from address of this message. + * + * You may pass an array of addresses if this message is from multiple people. + * + * If $name is passed and the first parameter is a string, this name will be + * associated with the address. + * + * @param string $addresses + * @param string $name optional + * @return Swift_Mime_SimpleMessage + */ + public function setFrom($addresses, $name = null) + { + if (!is_array($addresses) && isset($name)) + { + $addresses = array($addresses => $name); + } + + if (!$this->_setHeaderFieldModel('From', (array) $addresses)) + { + $this->getHeaders()->addMailboxHeader('From', (array) $addresses); + } + return $this; + } + + /** + * Get the from address of this message. + * + * @return string + */ + public function getFrom() + { + return $this->_getHeaderFieldModel('From'); + } + + /** + * Add a Reply-To: address to this message. + * + * If $name is passed this name will be associated with the address. + * + * @param string $address + * @param string $name optional + * @return Swift_Mime_SimpleMessage + */ + public function addReplyTo($address, $name = null) + { + $current = $this->getReplyTo(); + $current[$address] = $name; + return $this->setReplyTo($current); + } + + /** + * Set the reply-to address of this message. + * + * You may pass an array of addresses if replies will go to multiple people. + * + * If $name is passed and the first parameter is a string, this name will be + * associated with the address. + * + * @param string $addresses + * @param string $name optional + * @return Swift_Mime_SimpleMessage + */ + public function setReplyTo($addresses, $name = null) + { + if (!is_array($addresses) && isset($name)) + { + $addresses = array($addresses => $name); + } + + if (!$this->_setHeaderFieldModel('Reply-To', (array) $addresses)) + { + $this->getHeaders()->addMailboxHeader('Reply-To', (array) $addresses); + } + return $this; + } + + /** + * Get the reply-to address of this message. + * + * @return string + */ + public function getReplyTo() + { + return $this->_getHeaderFieldModel('Reply-To'); + } + + /** + * Add a To: address to this message. + * + * If $name is passed this name will be associated with the address. + * + * @param string $address + * @param string $name optional + * @return Swift_Mime_SimpleMessage + */ + public function addTo($address, $name = null) + { + $current = $this->getTo(); + $current[$address] = $name; + return $this->setTo($current); + } + + /** + * Set the to addresses of this message. + * + * If multiple recipients will receive the message and array should be used. + * + * If $name is passed and the first parameter is a string, this name will be + * associated with the address. + * + * @param array $addresses + * @param string $name optional + * @return Swift_Mime_SimpleMessage + */ + public function setTo($addresses, $name = null) + { + if (!is_array($addresses) && isset($name)) + { + $addresses = array($addresses => $name); + } + + if (!$this->_setHeaderFieldModel('To', (array) $addresses)) + { + $this->getHeaders()->addMailboxHeader('To', (array) $addresses); + } + return $this; + } + + /** + * Get the To addresses of this message. + * + * @return array + */ + public function getTo() + { + return $this->_getHeaderFieldModel('To'); + } + + /** + * Add a Cc: address to this message. + * + * If $name is passed this name will be associated with the address. + * + * @param string $address + * @param string $name optional + * @return Swift_Mime_SimpleMessage + */ + public function addCc($address, $name = null) + { + $current = $this->getCc(); + $current[$address] = $name; + return $this->setCc($current); + } + + /** + * Set the Cc addresses of this message. + * + * If $name is passed and the first parameter is a string, this name will be + * associated with the address. + * + * @param array $addresses + * @param string $name optional + * @return Swift_Mime_SimpleMessage + */ + public function setCc($addresses, $name = null) + { + if (!is_array($addresses) && isset($name)) + { + $addresses = array($addresses => $name); + } + + if (!$this->_setHeaderFieldModel('Cc', (array) $addresses)) + { + $this->getHeaders()->addMailboxHeader('Cc', (array) $addresses); + } + return $this; + } + + /** + * Get the Cc address of this message. + * + * @return array + */ + public function getCc() + { + return $this->_getHeaderFieldModel('Cc'); + } + + /** + * Add a Bcc: address to this message. + * + * If $name is passed this name will be associated with the address. + * + * @param string $address + * @param string $name optional + * @return Swift_Mime_SimpleMessage + */ + public function addBcc($address, $name = null) + { + $current = $this->getBcc(); + $current[$address] = $name; + return $this->setBcc($current); + } + + /** + * Set the Bcc addresses of this message. + * + * If $name is passed and the first parameter is a string, this name will be + * associated with the address. + * + * @param array $addresses + * @param string $name optional + * @return Swift_Mime_SimpleMessage + */ + public function setBcc($addresses, $name = null) + { + if (!is_array($addresses) && isset($name)) + { + $addresses = array($addresses => $name); + } + + if (!$this->_setHeaderFieldModel('Bcc', (array) $addresses)) + { + $this->getHeaders()->addMailboxHeader('Bcc', (array) $addresses); + } + return $this; + } + + /** + * Get the Bcc addresses of this message. + * + * @return array + */ + public function getBcc() + { + return $this->_getHeaderFieldModel('Bcc'); + } + + /** + * Set the priority of this message. + * The value is an integer where 1 is the highest priority and 5 is the lowest. + * @param int $priority + * @return Swift_Mime_SimpleMessage + */ + public function setPriority($priority) + { + $priorityMap = array( + 1 => 'Highest', + 2 => 'High', + 3 => 'Normal', + 4 => 'Low', + 5 => 'Lowest' + ); + $pMapKeys = array_keys($priorityMap); + if ($priority > max($pMapKeys)) + { + $priority = max($pMapKeys); + } + elseif ($priority < min($pMapKeys)) + { + $priority = min($pMapKeys); + } + if (!$this->_setHeaderFieldModel('X-Priority', + sprintf('%d (%s)', $priority, $priorityMap[$priority]))) + { + $this->getHeaders()->addTextHeader('X-Priority', + sprintf('%d (%s)', $priority, $priorityMap[$priority])); + } + return $this; + } + + /** + * Get the priority of this message. + * The returned value is an integer where 1 is the highest priority and 5 + * is the lowest. + * @return int + */ + public function getPriority() + { + list($priority) = sscanf($this->_getHeaderFieldModel('X-Priority'), + '%[1-5]' + ); + return isset($priority) ? $priority : 3; + } + + /** + * Ask for a delivery receipt from the recipient to be sent to $addresses + * @param array $addresses + * @return Swift_Mime_SimpleMessage + */ + public function setReadReceiptTo($addresses) + { + if (!$this->_setHeaderFieldModel('Disposition-Notification-To', $addresses)) + { + $this->getHeaders() + ->addMailboxHeader('Disposition-Notification-To', $addresses); + } + return $this; + } + + /** + * Get the addresses to which a read-receipt will be sent. + * @return string + */ + public function getReadReceiptTo() + { + return $this->_getHeaderFieldModel('Disposition-Notification-To'); + } + + /** + * Attach a {@link Swift_Mime_MimeEntity} such as an Attachment or MimePart. + * @param Swift_Mime_MimeEntity $entity + * @return Swift_Mime_SimpleMessage + */ + public function attach(Swift_Mime_MimeEntity $entity) + { + $this->setChildren(array_merge($this->getChildren(), array($entity))); + return $this; + } + + /** + * Remove an already attached entity. + * @param Swift_Mime_MimeEntity $entity + * @return Swift_Mime_SimpleMessage + */ + public function detach(Swift_Mime_MimeEntity $entity) + { + $newChildren = array(); + foreach ($this->getChildren() as $child) + { + if ($entity !== $child) + { + $newChildren[] = $child; + } + } + $this->setChildren($newChildren); + return $this; + } + + /** + * Attach a {@link Swift_Mime_MimeEntity} and return it's CID source. + * This method should be used when embedding images or other data in a message. + * @param Swift_Mime_MimeEntity $entity + * @return string + */ + public function embed(Swift_Mime_MimeEntity $entity) + { + $this->attach($entity); + return 'cid:' . $entity->getId(); + } + + /** + * Get this message as a complete string. + * @return string + */ + public function toString() + { + if (count($children = $this->getChildren()) > 0 && $this->getBody() != '') + { + $this->setChildren(array_merge(array($this->_becomeMimePart()), $children)); + $string = parent::toString(); + $this->setChildren($children); + } + else + { + $string = parent::toString(); + } + return $string; + } + + /** + * Returns a string representation of this object. + * + * @return string + * + * @see toString() + */ + public function __toString() + { + return $this->toString(); + } + + /** + * Write this message to a {@link Swift_InputByteStream}. + * @param Swift_InputByteStream $is + */ + public function toByteStream(Swift_InputByteStream $is) + { + if (count($children = $this->getChildren()) > 0 && $this->getBody() != '') + { + $this->setChildren(array_merge(array($this->_becomeMimePart()), $children)); + parent::toByteStream($is); + $this->setChildren($children); + } + else + { + parent::toByteStream($is); + } + } + + // -- Protected methods + + /** @see Swift_Mime_SimpleMimeEntity::_getIdField() */ + protected function _getIdField() + { + return 'Message-ID'; + } + + // -- Private methods + + /** Turn the body of this message into a child of itself if needed */ + private function _becomeMimePart() + { + $part = new parent($this->getHeaders()->newInstance(), $this->getEncoder(), + $this->_getCache(), $this->_getGrammar(), $this->_userCharset + ); + $part->setContentType($this->_userContentType); + $part->setBody($this->getBody()); + $part->setFormat($this->_userFormat); + $part->setDelSp($this->_userDelSp); + $part->_setNestingLevel($this->_getTopNestingLevel()); + return $part; + } + + /** Get the highest nesting level nested inside this message */ + private function _getTopNestingLevel() + { + $highestLevel = $this->getNestingLevel(); + foreach ($this->getChildren() as $child) + { + $childLevel = $child->getNestingLevel(); + if ($highestLevel < $childLevel) + { + $highestLevel = $childLevel; + } + } + return $highestLevel; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleMimeEntity.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleMimeEntity.php new file mode 100644 index 0000000..6c5766d --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleMimeEntity.php @@ -0,0 +1,852 @@ + array(self::LEVEL_TOP, self::LEVEL_MIXED), + 'multipart/alternative' => array(self::LEVEL_MIXED, self::LEVEL_ALTERNATIVE), + 'multipart/related' => array(self::LEVEL_ALTERNATIVE, self::LEVEL_RELATED) + ); + + /** A set of filter rules to define what level an entity should be nested at */ + private $_compoundLevelFilters = array(); + + /** The nesting level of this entity */ + private $_nestingLevel = self::LEVEL_ALTERNATIVE; + + /** A KeyCache instance used during encoding and streaming */ + private $_cache; + + /** Direct descendants of this entity */ + private $_immediateChildren = array(); + + /** All descendants of this entity */ + private $_children = array(); + + /** The maximum line length of the body of this entity */ + private $_maxLineLength = 78; + + /** The order in which alternative mime types should appear */ + private $_alternativePartOrder = array( + 'text/plain' => 1, + 'text/html' => 2, + 'multipart/related' => 3 + ); + + /** The CID of this entity */ + private $_id; + + /** The key used for accessing the cache */ + private $_cacheKey; + + protected $_userContentType; + + /** + * Create a new SimpleMimeEntity with $headers, $encoder and $cache. + * @param Swift_Mime_HeaderSet $headers + * @param Swift_Mime_ContentEncoder $encoder + * @param Swift_KeyCache $cache + * @param Swift_Mime_Grammar $grammar + */ + public function __construct(Swift_Mime_HeaderSet $headers, + Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, + Swift_Mime_Grammar $grammar) + { + $this->_cacheKey = uniqid(); + $this->_cache = $cache; + $this->_headers = $headers; + $this->_grammar = $grammar; + $this->setEncoder($encoder); + $this->_headers->defineOrdering( + array('Content-Type', 'Content-Transfer-Encoding') + ); + + // This array specifies that, when the entire MIME document contains + // $compoundLevel, then for each child within $level, if its Content-Type + // is $contentType then it should be treated as if it's level is + // $neededLevel instead. I tried to write that unambiguously! :-\ + // Data Structure: + // array ( + // $compoundLevel => array( + // $level => array( + // $contentType => $neededLevel + // ) + // ) + // ) + + $this->_compoundLevelFilters = array( + (self::LEVEL_ALTERNATIVE + self::LEVEL_RELATED) => array( + self::LEVEL_ALTERNATIVE => array( + 'text/plain' => self::LEVEL_ALTERNATIVE, + 'text/html' => self::LEVEL_RELATED + ) + ) + ); + + $this->_id = $this->getRandomId(); + } + + /** + * Generate a new Content-ID or Message-ID for this MIME entity. + * @return string + */ + public function generateId() + { + $this->setId($this->getRandomId()); + return $this->_id; + } + + /** + * Get the {@link Swift_Mime_HeaderSet} for this entity. + * @return Swift_Mime_HeaderSet + */ + public function getHeaders() + { + return $this->_headers; + } + + /** + * Get the nesting level of this entity. + * @return int + * @see LEVEL_TOP, LEVEL_MIXED, LEVEL_RELATED, LEVEL_ALTERNATIVE + */ + public function getNestingLevel() + { + return $this->_nestingLevel; + } + + /** + * Get the Content-type of this entity. + * @return string + */ + public function getContentType() + { + return $this->_getHeaderFieldModel('Content-Type'); + } + + /** + * Set the Content-type of this entity. + * @param string $type + * @return Swift_Mime_SimpleMimeEntity + */ + public function setContentType($type) + { + $this->_setContentTypeInHeaders($type); + // Keep track of the value so that if the content-type changes automatically + // due to added child entities, it can be restored if they are later removed + $this->_userContentType = $type; + return $this; + } + + /** + * Get the CID of this entity. + * The CID will only be present in headers if a Content-ID header is present. + * @return string + */ + public function getId() + { + return $this->_headers->has($this->_getIdField()) + ? current((array) $this->_getHeaderFieldModel($this->_getIdField())) + : $this->_id; + } + + /** + * Set the CID of this entity. + * @param string $id + * @return Swift_Mime_SimpleMimeEntity + */ + public function setId($id) + { + if (!$this->_setHeaderFieldModel($this->_getIdField(), $id)) + { + $this->_headers->addIdHeader($this->_getIdField(), $id); + } + $this->_id = $id; + return $this; + } + + /** + * Get the description of this entity. + * This value comes from the Content-Description header if set. + * @return string + */ + public function getDescription() + { + return $this->_getHeaderFieldModel('Content-Description'); + } + + /** + * Set the description of this entity. + * This method sets a value in the Content-ID header. + * @param string $description + * @return Swift_Mime_SimpleMimeEntity + */ + public function setDescription($description) + { + if (!$this->_setHeaderFieldModel('Content-Description', $description)) + { + $this->_headers->addTextHeader('Content-Description', $description); + } + return $this; + } + + /** + * Get the maximum line length of the body of this entity. + * @return int + */ + public function getMaxLineLength() + { + return $this->_maxLineLength; + } + + /** + * Set the maximum line length of lines in this body. + * Though not enforced by the library, lines should not exceed 1000 chars. + * @param int $length + * @return Swift_Mime_SimpleMimeEntity + */ + public function setMaxLineLength($length) + { + $this->_maxLineLength = $length; + return $this; + } + + /** + * Get all children added to this entity. + * @return array of Swift_Mime_Entity + */ + public function getChildren() + { + return $this->_children; + } + + /** + * Set all children of this entity. + * @param array $children Swiift_Mime_Entity instances + * @param int $compoundLevel For internal use only + * @return Swift_Mime_SimpleMimeEntity + */ + public function setChildren(array $children, $compoundLevel = null) + { + //TODO: Try to refactor this logic + + $compoundLevel = isset($compoundLevel) + ? $compoundLevel + : $this->_getCompoundLevel($children) + ; + + $immediateChildren = array(); + $grandchildren = array(); + $newContentType = $this->_userContentType; + + foreach ($children as $child) + { + $level = $this->_getNeededChildLevel($child, $compoundLevel); + if (empty($immediateChildren)) //first iteration + { + $immediateChildren = array($child); + } + else + { + $nextLevel = $this->_getNeededChildLevel($immediateChildren[0], $compoundLevel); + if ($nextLevel == $level) + { + $immediateChildren[] = $child; + } + elseif ($level < $nextLevel) + { + //Re-assign immediateChildren to grandchilden + $grandchildren = array_merge($grandchildren, $immediateChildren); + //Set new children + $immediateChildren = array($child); + } + else + { + $grandchildren[] = $child; + } + } + } + + if (!empty($immediateChildren)) + { + $lowestLevel = $this->_getNeededChildLevel($immediateChildren[0], $compoundLevel); + + //Determine which composite media type is needed to accomodate the + // immediate children + foreach ($this->_compositeRanges as $mediaType => $range) + { + if ($lowestLevel > $range[0] + && $lowestLevel <= $range[1]) + { + $newContentType = $mediaType; + break; + } + } + + //Put any grandchildren in a subpart + if (!empty($grandchildren)) + { + $subentity = $this->_createChild(); + $subentity->_setNestingLevel($lowestLevel); + $subentity->setChildren($grandchildren, $compoundLevel); + array_unshift($immediateChildren, $subentity); + } + } + + $this->_immediateChildren = $immediateChildren; + $this->_children = $children; + $this->_setContentTypeInHeaders($newContentType); + $this->_fixHeaders(); + $this->_sortChildren(); + + return $this; + } + + /** + * Get the body of this entity as a string. + * @return string + */ + public function getBody() + { + return ($this->_body instanceof Swift_OutputByteStream) + ? $this->_readStream($this->_body) + : $this->_body; + } + + /** + * Set the body of this entity, either as a string, or as an instance of + * {@link Swift_OutputByteStream}. + * @param mixed $body + * @param string $contentType optional + * @return Swift_Mime_SimpleMimeEntity + */ + public function setBody($body, $contentType = null) + { + if ($body !== $this->_body) + { + $this->_clearCache(); + } + + $this->_body = $body; + if (isset($contentType)) + { + $this->setContentType($contentType); + } + return $this; + } + + /** + * Get the encoder used for the body of this entity. + * @return Swift_Mime_ContentEncoder + */ + public function getEncoder() + { + return $this->_encoder; + } + + /** + * Set the encoder used for the body of this entity. + * @param Swift_Mime_ContentEncoder $encoder + * @return Swift_Mime_SimpleMimeEntity + */ + public function setEncoder(Swift_Mime_ContentEncoder $encoder) + { + if ($encoder !== $this->_encoder) + { + $this->_clearCache(); + } + + $this->_encoder = $encoder; + $this->_setEncoding($encoder->getName()); + $this->_notifyEncoderChanged($encoder); + return $this; + } + + /** + * Get the boundary used to separate children in this entity. + * @return string + */ + public function getBoundary() + { + if (!isset($this->_boundary)) + { + $this->_boundary = '_=_swift_v4_' . time() . uniqid() . '_=_'; + } + return $this->_boundary; + } + + /** + * Set the boundary used to separate children in this entity. + * @param string $boundary + * @throws Swift_RfcComplianceException + * @return Swift_Mime_SimpleMimeEntity + */ + public function setBoundary($boundary) + { + $this->_assertValidBoundary($boundary); + $this->_boundary = $boundary; + return $this; + } + + /** + * Receive notification that the charset of this entity, or a parent entity + * has changed. + * @param string $charset + */ + public function charsetChanged($charset) + { + $this->_notifyCharsetChanged($charset); + } + + /** + * Receive notification that the encoder of this entity or a parent entity + * has changed. + * @param Swift_Mime_ContentEncoder $encoder + */ + public function encoderChanged(Swift_Mime_ContentEncoder $encoder) + { + $this->_notifyEncoderChanged($encoder); + } + + /** + * Get this entire entity as a string. + * @return string + */ + public function toString() + { + $string = $this->_headers->toString(); + if (isset($this->_body) && empty($this->_immediateChildren)) + { + if ($this->_cache->hasKey($this->_cacheKey, 'body')) + { + $body = $this->_cache->getString($this->_cacheKey, 'body'); + } + else + { + $body = "\r\n" . $this->_encoder->encodeString($this->getBody(), 0, + $this->getMaxLineLength() + ); + $this->_cache->setString($this->_cacheKey, 'body', $body, + Swift_KeyCache::MODE_WRITE + ); + } + $string .= $body; + } + + if (!empty($this->_immediateChildren)) + { + foreach ($this->_immediateChildren as $child) + { + $string .= "\r\n\r\n--" . $this->getBoundary() . "\r\n"; + $string .= $child->toString(); + } + $string .= "\r\n\r\n--" . $this->getBoundary() . "--\r\n"; + } + + return $string; + } + + /** + * Returns a string representation of this object. + * + * @return string + * + * @see toString() + */ + public function __toString() + { + return $this->toString(); + } + + /** + * Write this entire entity to a {@link Swift_InputByteStream}. + * @param Swift_InputByteStream + */ + public function toByteStream(Swift_InputByteStream $is) + { + $is->write($this->_headers->toString()); + $is->commit(); + + if (empty($this->_immediateChildren)) + { + if (isset($this->_body)) + { + if ($this->_cache->hasKey($this->_cacheKey, 'body')) + { + $this->_cache->exportToByteStream($this->_cacheKey, 'body', $is); + } + else + { + $cacheIs = $this->_cache->getInputByteStream($this->_cacheKey, 'body'); + if ($cacheIs) + { + $is->bind($cacheIs); + } + + $is->write("\r\n"); + + if ($this->_body instanceof Swift_OutputByteStream) + { + $this->_body->setReadPointer(0); + + $this->_encoder->encodeByteStream($this->_body, $is, 0, + $this->getMaxLineLength() + ); + } + else + { + $is->write($this->_encoder->encodeString( + $this->getBody(), 0, $this->getMaxLineLength() + )); + } + + if ($cacheIs) + { + $is->unbind($cacheIs); + } + } + } + } + + if (!empty($this->_immediateChildren)) + { + foreach ($this->_immediateChildren as $child) + { + $is->write("\r\n\r\n--" . $this->getBoundary() . "\r\n"); + $child->toByteStream($is); + } + $is->write("\r\n\r\n--" . $this->getBoundary() . "--\r\n"); + } + } + + // -- Protected methods + + /** + * Get the name of the header that provides the ID of this entity */ + protected function _getIdField() + { + return 'Content-ID'; + } + + /** + * Get the model data (usually an array or a string) for $field. + */ + protected function _getHeaderFieldModel($field) + { + if ($this->_headers->has($field)) + { + return $this->_headers->get($field)->getFieldBodyModel(); + } + } + + /** + * Set the model data for $field. + */ + protected function _setHeaderFieldModel($field, $model) + { + if ($this->_headers->has($field)) + { + $this->_headers->get($field)->setFieldBodyModel($model); + return true; + } + else + { + return false; + } + } + + /** + * Get the parameter value of $parameter on $field header. + */ + protected function _getHeaderParameter($field, $parameter) + { + if ($this->_headers->has($field)) + { + return $this->_headers->get($field)->getParameter($parameter); + } + } + + /** + * Set the parameter value of $parameter on $field header. + */ + protected function _setHeaderParameter($field, $parameter, $value) + { + if ($this->_headers->has($field)) + { + $this->_headers->get($field)->setParameter($parameter, $value); + return true; + } + else + { + return false; + } + } + + /** + * Re-evaluate what content type and encoding should be used on this entity. + */ + protected function _fixHeaders() + { + if (count($this->_immediateChildren)) + { + $this->_setHeaderParameter('Content-Type', 'boundary', + $this->getBoundary() + ); + $this->_headers->remove('Content-Transfer-Encoding'); + } + else + { + $this->_setHeaderParameter('Content-Type', 'boundary', null); + $this->_setEncoding($this->_encoder->getName()); + } + } + + /** + * Get the KeyCache used in this entity. + */ + protected function _getCache() + { + return $this->_cache; + } + + /** + * Get the grammar used for validation. + * @return Swift_Mime_Grammar + */ + protected function _getGrammar() + { + return $this->_grammar; + } + + /** + * Empty the KeyCache for this entity. + */ + protected function _clearCache() + { + $this->_cache->clearKey($this->_cacheKey, 'body'); + } + + /** + * Returns a random Content-ID or Message-ID. + * @return string + */ + protected function getRandomId() + { + $idLeft = time() . '.' . uniqid(); + $idRight = !empty($_SERVER['SERVER_NAME']) + ? $_SERVER['SERVER_NAME'] + : 'swift.generated'; + $id = $idLeft . '@' . $idRight; + + try + { + $this->_assertValidId($id); + } + catch (Swift_RfcComplianceException $e) + { + $id = $idLeft . '@swift.generated'; + } + + return $id; + } + + // -- Private methods + + private function _readStream(Swift_OutputByteStream $os) + { + $string = ''; + while (false !== $bytes = $os->read(8192)) + { + $string .= $bytes; + } + return $string; + } + + private function _setEncoding($encoding) + { + if (!$this->_setHeaderFieldModel('Content-Transfer-Encoding', $encoding)) + { + $this->_headers->addTextHeader('Content-Transfer-Encoding', $encoding); + } + } + + private function _assertValidBoundary($boundary) + { + if (!preg_match( + '/^[a-z0-9\'\(\)\+_\-,\.\/:=\?\ ]{0,69}[a-z0-9\'\(\)\+_\-,\.\/:=\?]$/Di', + $boundary)) + { + throw new Swift_RfcComplianceException('Mime boundary set is not RFC 2046 compliant.'); + } + } + + private function _setContentTypeInHeaders($type) + { + if (!$this->_setHeaderFieldModel('Content-Type', $type)) + { + $this->_headers->addParameterizedHeader('Content-Type', $type); + } + } + + private function _setNestingLevel($level) + { + $this->_nestingLevel = $level; + } + + private function _getCompoundLevel($children) + { + $level = 0; + foreach ($children as $child) + { + $level |= $child->getNestingLevel(); + } + return $level; + } + + private function _getNeededChildLevel($child, $compoundLevel) + { + $filter = array(); + foreach ($this->_compoundLevelFilters as $bitmask => $rules) + { + if (($compoundLevel & $bitmask) === $bitmask) + { + $filter = $rules + $filter; + } + } + + $realLevel = $child->getNestingLevel(); + $lowercaseType = strtolower($child->getContentType()); + + if (isset($filter[$realLevel]) + && isset($filter[$realLevel][$lowercaseType])) + { + return $filter[$realLevel][$lowercaseType]; + } + else + { + return $realLevel; + } + } + + private function _createChild() + { + return new self($this->_headers->newInstance(), + $this->_encoder, $this->_cache, $this->_grammar); + } + + private function _notifyEncoderChanged(Swift_Mime_ContentEncoder $encoder) + { + foreach ($this->_immediateChildren as $child) + { + $child->encoderChanged($encoder); + } + } + + private function _notifyCharsetChanged($charset) + { + $this->_encoder->charsetChanged($charset); + $this->_headers->charsetChanged($charset); + foreach ($this->_immediateChildren as $child) + { + $child->charsetChanged($charset); + } + } + + private function _sortChildren() + { + $shouldSort = false; + foreach ($this->_immediateChildren as $child) + { + //NOTE: This include alternative parts moved into a related part + if ($child->getNestingLevel() == self::LEVEL_ALTERNATIVE) + { + $shouldSort = true; + break; + } + } + + //Sort in order of preference, if there is one + if ($shouldSort) + { + usort($this->_immediateChildren, array($this, '_childSortAlgorithm')); + } + } + + private function _childSortAlgorithm($a, $b) + { + $typePrefs = array(); + $types = array( + strtolower($a->getContentType()), + strtolower($b->getContentType()) + ); + foreach ($types as $type) + { + $typePrefs[] = (array_key_exists($type, $this->_alternativePartOrder)) + ? $this->_alternativePartOrder[$type] + : (max($this->_alternativePartOrder) + 1); + } + return ($typePrefs[0] >= $typePrefs[1]) ? 1 : -1; + } + + // -- Destructor + + /** + * Empties it's own contents from the cache. + */ + public function __destruct() + { + $this->_cache->clearAll($this->_cacheKey); + } + + /** + * Throws an Exception if the id passed does not comply with RFC 2822. + * @param string $id + * @throws Swift_RfcComplianceException + */ + private function _assertValidId($id) + { + if (!preg_match( + '/^' . $this->_grammar->getDefinition('id-left') . '@' . + $this->_grammar->getDefinition('id-right') . '$/D', + $id + )) + { + throw new Swift_RfcComplianceException( + 'Invalid ID given <' . $id . '>' + ); + } + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/MimePart.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/MimePart.php new file mode 100644 index 0000000..e22f15e --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/MimePart.php @@ -0,0 +1,63 @@ +createDependenciesFor('mime.part') + ); + + if (!isset($charset)) + { + $charset = Swift_DependencyContainer::getInstance() + ->lookup('properties.charset'); + } + $this->setBody($body); + $this->setCharset($charset); + if ($contentType) + { + $this->setContentType($contentType); + } + } + + /** + * Create a new MimePart. + * @param string $body + * @param string $contentType + * @param string $charset + * @return Swift_Mime_MimePart + */ + public static function newInstance($body = null, $contentType = null, + $charset = null) + { + return new self($body, $contentType, $charset); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/NullTransport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/NullTransport.php new file mode 100644 index 0000000..8c82ee2 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/NullTransport.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Pretends messages have been sent, but just ignores them. + * @package Swift + * @author Fabien Potencier + */ +class Swift_NullTransport extends Swift_Transport_NullTransport +{ + /** + * Create a new NullTransport. + */ + public function __construct() + { + call_user_func_array( + array($this, 'Swift_Transport_NullTransport::__construct'), + Swift_DependencyContainer::getInstance() + ->createDependenciesFor('transport.null') + ); + } + + /** + * Create a new NullTransport instance. + * @return Swift_NullTransport + */ + public static function newInstance() + { + return new self(); + } +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/OutputByteStream.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/OutputByteStream.php new file mode 100644 index 0000000..951b838 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/OutputByteStream.php @@ -0,0 +1,41 @@ +setThreshold($threshold); + $this->setSleepTime($sleep); + $this->_sleeper = $sleeper; + } + + /** + * Set the number of emails to send before restarting. + * @param int $threshold + */ + public function setThreshold($threshold) + { + $this->_threshold = $threshold; + } + + /** + * Get the number of emails to send before restarting. + * @return int + */ + public function getThreshold() + { + return $this->_threshold; + } + + /** + * Set the number of seconds to sleep for during a restart. + * @param int $sleep time + */ + public function setSleepTime($sleep) + { + $this->_sleep = $sleep; + } + + /** + * Get the number of seconds to sleep for during a restart. + * @return int + */ + public function getSleepTime() + { + return $this->_sleep; + } + + /** + * Invoked immediately before the Message is sent. + * @param Swift_Events_SendEvent $evt + */ + public function beforeSendPerformed(Swift_Events_SendEvent $evt) + { + } + + /** + * Invoked immediately after the Message is sent. + * @param Swift_Events_SendEvent $evt + */ + public function sendPerformed(Swift_Events_SendEvent $evt) + { + ++$this->_counter; + if ($this->_counter >= $this->_threshold) + { + $transport = $evt->getTransport(); + $transport->stop(); + if ($this->_sleep) + { + $this->sleep($this->_sleep); + } + $transport->start(); + $this->_counter = 0; + } + } + + /** + * Sleep for $seconds. + * @param int $seconds + */ + public function sleep($seconds) + { + if (isset($this->_sleeper)) + { + $this->_sleeper->sleep($seconds); + } + else + { + sleep($seconds); + } + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/BandwidthMonitorPlugin.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/BandwidthMonitorPlugin.php new file mode 100644 index 0000000..f56d337 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/BandwidthMonitorPlugin.php @@ -0,0 +1,166 @@ +getMessage(); + $message->toByteStream($this); + } + + /** + * Invoked immediately following a command being sent. + * @param Swift_Events_ResponseEvent $evt + */ + public function commandSent(Swift_Events_CommandEvent $evt) + { + $command = $evt->getCommand(); + $this->_out += strlen($command); + } + + /** + * Invoked immediately following a response coming back. + * @param Swift_Events_ResponseEvent $evt + */ + public function responseReceived(Swift_Events_ResponseEvent $evt) + { + $response = $evt->getResponse(); + $this->_in += strlen($response); + } + + /** + * Called when a message is sent so that the outgoing counter can be increased. + * @param string $bytes + */ + public function write($bytes) + { + $this->_out += strlen($bytes); + foreach ($this->_mirrors as $stream) + { + $stream->write($bytes); + } + } + + /** + * Not used. + */ + public function commit() + { + } + + /** + * Attach $is to this stream. + * The stream acts as an observer, receiving all data that is written. + * All {@link write()} and {@link flushBuffers()} operations will be mirrored. + * + * @param Swift_InputByteStream $is + */ + public function bind(Swift_InputByteStream $is) + { + $this->_mirrors[] = $is; + } + + /** + * Remove an already bound stream. + * If $is is not bound, no errors will be raised. + * If the stream currently has any buffered data it will be written to $is + * before unbinding occurs. + * + * @param Swift_InputByteStream $is + */ + public function unbind(Swift_InputByteStream $is) + { + foreach ($this->_mirrors as $k => $stream) + { + if ($is === $stream) + { + unset($this->_mirrors[$k]); + } + } + } + + /** + * Not used. + */ + public function flushBuffers() + { + foreach ($this->_mirrors as $stream) + { + $stream->flushBuffers(); + } + } + + /** + * Get the total number of bytes sent to the server. + * @return int + */ + public function getBytesOut() + { + return $this->_out; + } + + /** + * Get the total number of bytes received from the server. + * @return int + */ + public function getBytesIn() + { + return $this->_in; + } + + /** + * Reset the internal counters to zero. + */ + public function reset() + { + $this->_out = 0; + $this->_in = 0; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Decorator/Replacements.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Decorator/Replacements.php new file mode 100644 index 0000000..9735d0a --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Decorator/Replacements.php @@ -0,0 +1,36 @@ + + * $replacements = array( + * "address1@domain.tld" => array("{a}" => "b", "{c}" => "d"), + * "address2@domain.tld" => array("{a}" => "x", "{c}" => "y") + * ) + *
    + * + * When using an instance of {@link Swift_Plugins_Decorator_Replacements}, + * the object should return just the array of replacements for the address + * given to {@link Swift_Plugins_Decorator_Replacements::getReplacementsFor()}. + * + * @param mixed $replacements Array or Swift_Plugins_Decorator_Replacements + */ + public function __construct($replacements) + { + $this->setReplacements($replacements); + } + + /** + * Sets replacements. + * + * @param mixed $replacements Array or Swift_Plugins_Decorator_Replacements + * + * @see __construct() + */ + public function setReplacements($replacements) + { + if (!($replacements instanceof \Swift_Plugins_Decorator_Replacements)) + { + $this->_replacements = (array) $replacements; + } + else + { + $this->_replacements = $replacements; + } + } + + /** + * Invoked immediately before the Message is sent. + * + * @param Swift_Events_SendEvent $evt + */ + public function beforeSendPerformed(Swift_Events_SendEvent $evt) + { + $message = $evt->getMessage(); + $this->_restoreMessage($message); + $to = array_keys($message->getTo()); + $address = array_shift($to); + if ($replacements = $this->getReplacementsFor($address)) + { + $body = $message->getBody(); + $search = array_keys($replacements); + $replace = array_values($replacements); + $bodyReplaced = str_replace( + $search, $replace, $body + ); + if ($body != $bodyReplaced) + { + $this->_originalBody = $body; + $message->setBody($bodyReplaced); + } + + foreach ($message->getHeaders()->getAll() as $header) + { + $body = $header->getFieldBodyModel(); + $count = 0; + if (is_array($body)) + { + $bodyReplaced = array(); + foreach ($body as $key => $value) + { + $count1 = 0; + $count2 = 0; + $key = is_string($key) ? str_replace($search, $replace, $key, $count1) : $key; + $value = is_string($value) ? str_replace($search, $replace, $value, $count2) : $value; + $bodyReplaced[$key] = $value; + + if (!$count && ($count1 || $count2)) + { + $count = 1; + } + } + } + else + { + $bodyReplaced = str_replace($search, $replace, $body, $count); + } + + if ($count) + { + $this->_originalHeaders[$header->getFieldName()] = $body; + $header->setFieldBodyModel($bodyReplaced); + } + } + + $children = (array) $message->getChildren(); + foreach ($children as $child) + { + list($type, ) = sscanf($child->getContentType(), '%[^/]/%s'); + if ('text' == $type) + { + $body = $child->getBody(); + $bodyReplaced = str_replace( + $search, $replace, $body + ); + if ($body != $bodyReplaced) + { + $child->setBody($bodyReplaced); + $this->_originalChildBodies[$child->getId()] = $body; + } + } + } + $this->_lastMessage = $message; + } + } + + /** + * Find a map of replacements for the address. + * + * If this plugin was provided with a delegate instance of + * {@link Swift_Plugins_Decorator_Replacements} then the call will be + * delegated to it. Otherwise, it will attempt to find the replacements + * from the array provided in the constructor. + * + * If no replacements can be found, an empty value (NULL) is returned. + * + * @param string $address + * + * @return array + */ + public function getReplacementsFor($address) + { + if ($this->_replacements instanceof Swift_Plugins_Decorator_Replacements) + { + return $this->_replacements->getReplacementsFor($address); + } + else + { + return isset($this->_replacements[$address]) + ? $this->_replacements[$address] + : null + ; + } + } + + /** + * Invoked immediately after the Message is sent. + * + * @param Swift_Events_SendEvent $evt + */ + public function sendPerformed(Swift_Events_SendEvent $evt) + { + $this->_restoreMessage($evt->getMessage()); + } + + // -- Private methods + + /** Restore a changed message back to its original state */ + private function _restoreMessage(Swift_Mime_Message $message) + { + if ($this->_lastMessage === $message) + { + if (isset($this->_originalBody)) + { + $message->setBody($this->_originalBody); + $this->_originalBody = null; + } + if (!empty($this->_originalHeaders)) + { + foreach ($message->getHeaders()->getAll() as $header) + { + if (array_key_exists($header->getFieldName(), $this->_originalHeaders)) + { + $header->setFieldBodyModel($this->_originalHeaders[$header->getFieldName()]); + } + } + $this->_originalHeaders = array(); + } + if (!empty($this->_originalChildBodies)) + { + $children = (array) $message->getChildren(); + foreach ($children as $child) + { + $id = $child->getId(); + if (array_key_exists($id, $this->_originalChildBodies)) + { + $child->setBody($this->_originalChildBodies[$id]); + } + } + $this->_originalChildBodies = array(); + } + $this->_lastMessage = null; + } + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/ImpersonatePlugin.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/ImpersonatePlugin.php new file mode 100644 index 0000000..3b0a425 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/ImpersonatePlugin.php @@ -0,0 +1,68 @@ +_sender = $sender; + } + + /** + * Invoked immediately before the Message is sent. + * + * @param Swift_Events_SendEvent $evt + */ + public function beforeSendPerformed(Swift_Events_SendEvent $evt) { + $message = $evt->getMessage(); + $headers = $message->getHeaders(); + + // save current recipients + $headers->addPathHeader('X-Swift-Return-Path', $message->getReturnPath()); + + // replace them with the one to send to + $message->setReturnPath($this->_sender); + } + + /** + * Invoked immediately after the Message is sent. + * + * @param Swift_Events_SendEvent $evt + */ + public function sendPerformed(Swift_Events_SendEvent $evt) { + $message = $evt->getMessage(); + + // restore original headers + $headers = $message->getHeaders(); + + if ($headers->has('X-Swift-Return-Path')) { + $message->setReturnPath($headers->get('X-Swift-Return-Path')->getAddress()); + $headers->removeAll('X-Swift-Return-Path'); + } + } +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Logger.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Logger.php new file mode 100644 index 0000000..9864da0 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Logger.php @@ -0,0 +1,37 @@ +_logger = $logger; + } + + /** + * Add a log entry. + * + * @param string $entry + */ + public function add($entry) + { + $this->_logger->add($entry); + } + + /** + * Clear the log contents. + */ + public function clear() + { + $this->_logger->clear(); + } + + /** + * Get this log as a string. + * + * @return string + */ + public function dump() + { + return $this->_logger->dump(); + } + + /** + * Invoked immediately following a command being sent. + * + * @param Swift_Events_ResponseEvent $evt + */ + public function commandSent(Swift_Events_CommandEvent $evt) + { + $command = $evt->getCommand(); + $this->_logger->add(sprintf(">> %s", $command)); + } + + /** + * Invoked immediately following a response coming back. + * + * @param Swift_Events_ResponseEvent $evt + */ + public function responseReceived(Swift_Events_ResponseEvent $evt) + { + $response = $evt->getResponse(); + $this->_logger->add(sprintf("<< %s", $response)); + } + + /** + * Invoked just before a Transport is started. + * + * @param Swift_Events_TransportChangeEvent $evt + */ + public function beforeTransportStarted(Swift_Events_TransportChangeEvent $evt) + { + $transportName = get_class($evt->getSource()); + $this->_logger->add(sprintf("++ Starting %s", $transportName)); + } + + /** + * Invoked immediately after the Transport is started. + * + * @param Swift_Events_TransportChangeEvent $evt + */ + public function transportStarted(Swift_Events_TransportChangeEvent $evt) + { + $transportName = get_class($evt->getSource()); + $this->_logger->add(sprintf("++ %s started", $transportName)); + } + + /** + * Invoked just before a Transport is stopped. + * + * @param Swift_Events_TransportChangeEvent $evt + */ + public function beforeTransportStopped(Swift_Events_TransportChangeEvent $evt) + { + $transportName = get_class($evt->getSource()); + $this->_logger->add(sprintf("++ Stopping %s", $transportName)); + } + + /** + * Invoked immediately after the Transport is stopped. + * + * @param Swift_Events_TransportChangeEvent $evt + */ + public function transportStopped(Swift_Events_TransportChangeEvent $evt) + { + $transportName = get_class($evt->getSource()); + $this->_logger->add(sprintf("++ %s stopped", $transportName)); + } + + /** + * Invoked as a TransportException is thrown in the Transport system. + * + * @param Swift_Events_TransportExceptionEvent $evt + */ + public function exceptionThrown(Swift_Events_TransportExceptionEvent $evt) + { + $e = $evt->getException(); + $message = $e->getMessage(); + $this->_logger->add(sprintf("!! %s", $message)); + $message .= PHP_EOL; + $message .= 'Log data:' . PHP_EOL; + $message .= $this->_logger->dump(); + $evt->cancelBubble(); + throw new Swift_TransportException($message); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Loggers/ArrayLogger.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Loggers/ArrayLogger.php new file mode 100644 index 0000000..930eca2 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Loggers/ArrayLogger.php @@ -0,0 +1,73 @@ +_size = $size; + } + + /** + * Add a log entry. + * @param string $entry + */ + public function add($entry) + { + $this->_log[] = $entry; + while (count($this->_log) > $this->_size) + { + array_shift($this->_log); + } + } + + /** + * Clear the log contents. + */ + public function clear() + { + $this->_log = array(); + } + + /** + * Get this log as a string. + * @return string + */ + public function dump() + { + return implode(PHP_EOL, $this->_log); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Loggers/EchoLogger.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Loggers/EchoLogger.php new file mode 100644 index 0000000..83dd54b --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Loggers/EchoLogger.php @@ -0,0 +1,64 @@ +_isHtml = $isHtml; + } + + /** + * Add a log entry. + * @param string $entry + */ + public function add($entry) + { + if ($this->_isHtml) + { + printf('%s%s%s', htmlspecialchars($entry, ENT_QUOTES), '
    ', PHP_EOL); + } + else + { + printf('%s%s', $entry, PHP_EOL); + } + } + + /** + * Not implemented. + */ + public function clear() + { + } + + /** + * Not implemented. + */ + public function dump() + { + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/MessageLogger.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/MessageLogger.php new file mode 100644 index 0000000..b6a9422 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/MessageLogger.php @@ -0,0 +1,77 @@ +messages = array(); + } + + /** + * Get the message list + * + * @return array + */ + public function getMessages() + { + return $this->messages; + } + + /** + * Get the message count + * + * @return int count + */ + public function countMessages() + { + return count($this->messages); + } + + /** + * Empty the message list + * + */ + public function clear() + { + $this->messages = array(); + } + + /** + * Invoked immediately before the Message is sent. + * + * @param Swift_Events_SendEvent $evt + */ + public function beforeSendPerformed(Swift_Events_SendEvent $evt) + { + $this->messages[] = clone $evt->getMessage(); + } + + /** + * Invoked immediately after the Message is sent. + * + * @param Swift_Events_SendEvent $evt + */ + public function sendPerformed(Swift_Events_SendEvent $evt) + { + } +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Connection.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Connection.php new file mode 100644 index 0000000..1c96dcf --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Connection.php @@ -0,0 +1,36 @@ +_host = $host; + $this->_port = $port; + $this->_crypto = $crypto; + } + + /** + * Create a new PopBeforeSmtpPlugin for $host and $port. + * + * @param string $host + * @param int $port + * @param string $cypto as "tls" or "ssl" + * + * @return Swift_Plugins_PopBeforeSmtpPlugin + */ + public static function newInstance($host, $port = 110, $crypto = null) + { + return new self($host, $port, $crypto); + } + + /** + * Set a Pop3Connection to delegate to instead of connecting directly. + * + * @param Swift_Plugins_Pop_Pop3Connection $connection + */ + public function setConnection(Swift_Plugins_Pop_Pop3Connection $connection) + { + $this->_connection = $connection; + return $this; + } + + /** + * Bind this plugin to a specific SMTP transport instance. + * + * @param Swift_Transport + */ + public function bindSmtp(Swift_Transport $smtp) + { + $this->_transport = $smtp; + } + + /** + * Set the connection timeout in seconds (default 10). + * + * @param int $timeout + */ + public function setTimeout($timeout) + { + $this->_timeout = (int) $timeout; + return $this; + } + + /** + * Set the username to use when connecting (if needed). + * + * @param string $username + */ + public function setUsername($username) + { + $this->_username = $username; + return $this; + } + + /** + * Set the password to use when connecting (if needed). + * + * @param string $password + */ + public function setPassword($password) + { + $this->_password = $password; + return $this; + } + + /** + * Connect to the POP3 host and authenticate. + * + * @throws Swift_Plugins_Pop_Pop3Exception if connection fails + */ + public function connect() + { + if (isset($this->_connection)) + { + $this->_connection->connect(); + } + else + { + if (!isset($this->_socket)) + { + if (!$socket = fsockopen( + $this->_getHostString(), $this->_port, $errno, $errstr, $this->_timeout)) + { + throw new Swift_Plugins_Pop_Pop3Exception( + sprintf('Failed to connect to POP3 host [%s]: %s', $this->_host, $errstr) + ); + } + $this->_socket = $socket; + + if (false === $greeting = fgets($this->_socket)) + { + throw new Swift_Plugins_Pop_Pop3Exception( + sprintf('Failed to connect to POP3 host [%s]', trim($greeting)) + ); + } + + $this->_assertOk($greeting); + + if ($this->_username) + { + $this->_command(sprintf("USER %s\r\n", $this->_username)); + $this->_command(sprintf("PASS %s\r\n", $this->_password)); + } + } + } + } + + /** + * Disconnect from the POP3 host. + */ + public function disconnect() + { + if (isset($this->_connection)) + { + $this->_connection->disconnect(); + } + else + { + $this->_command("QUIT\r\n"); + if (!fclose($this->_socket)) + { + throw new Swift_Plugins_Pop_Pop3Exception( + sprintf('POP3 host [%s] connection could not be stopped', $this->_host) + ); + } + $this->_socket = null; + } + } + + /** + * Invoked just before a Transport is started. + * + * @param Swift_Events_TransportChangeEvent $evt + */ + public function beforeTransportStarted(Swift_Events_TransportChangeEvent $evt) + { + if (isset($this->_transport)) + { + if ($this->_transport !== $evt->getTransport()) + { + return; + } + } + + $this->connect(); + $this->disconnect(); + } + + /** + * Not used. + */ + public function transportStarted(Swift_Events_TransportChangeEvent $evt) + { + } + + /** + * Not used. + */ + public function beforeTransportStopped(Swift_Events_TransportChangeEvent $evt) + { + } + + /** + * Not used. + */ + public function transportStopped(Swift_Events_TransportChangeEvent $evt) + { + } + + // -- Private Methods + + private function _command($command) + { + if (!fwrite($this->_socket, $command)) + { + throw new Swift_Plugins_Pop_Pop3Exception( + sprintf('Failed to write command [%s] to POP3 host', trim($command)) + ); + } + + if (false === $response = fgets($this->_socket)) + { + throw new Swift_Plugins_Pop_Pop3Exception( + sprintf('Failed to read from POP3 host after command [%s]', trim($command)) + ); + } + + $this->_assertOk($response); + + return $response; + } + + private function _assertOk($response) + { + if (substr($response, 0, 3) != '+OK') + { + throw new Swift_Plugins_Pop_Pop3Exception( + sprintf('POP3 command failed [%s]', trim($response)) + ); + } + } + + private function _getHostString() + { + $host = $this->_host; + switch (strtolower($this->_crypto)) + { + case 'ssl': + $host = 'ssl://' . $host; + break; + + case 'tls': + $host = 'tls://' . $host; + break; + } + return $host; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/RedirectingPlugin.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/RedirectingPlugin.php new file mode 100644 index 0000000..71a3e60 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/RedirectingPlugin.php @@ -0,0 +1,109 @@ +_recipient = $recipient; + } + + /** + * Set the recipient of all messages. + * @param int $threshold + */ + public function setRecipient($recipient) + { + $this->_recipient = $recipient; + } + + /** + * Get the recipient of all messages. + * @return int + */ + public function getRecipient() + { + return $this->_recipient; + } + + /** + * Invoked immediately before the Message is sent. + * @param Swift_Events_SendEvent $evt + */ + public function beforeSendPerformed(Swift_Events_SendEvent $evt) + { + $message = $evt->getMessage(); + $headers = $message->getHeaders(); + + // save current recipients + $headers->addMailboxHeader('X-Swift-To', $message->getTo()); + $headers->addMailboxHeader('X-Swift-Cc', $message->getCc()); + $headers->addMailboxHeader('X-Swift-Bcc', $message->getBcc()); + + // replace them with the one to send to + $message->setTo($this->_recipient); + $headers->removeAll('Cc'); + $headers->removeAll('Bcc'); + } + + /** + * Invoked immediately after the Message is sent. + * + * @param Swift_Events_SendEvent $evt + */ + public function sendPerformed(Swift_Events_SendEvent $evt) + { + $this->_restoreMessage($evt->getMessage()); + } + + // -- Private methods + + private function _restoreMessage(Swift_Mime_Message $message) + { + // restore original headers + $headers = $message->getHeaders(); + + if ($headers->has('X-Swift-To')) + { + $message->setTo($headers->get('X-Swift-To')->getNameAddresses()); + $headers->removeAll('X-Swift-To'); + } + + if ($headers->has('X-Swift-Cc')) + { + $message->setCc($headers->get('X-Swift-Cc')->getNameAddresses()); + $headers->removeAll('X-Swift-Cc'); + } + + if ($headers->has('X-Swift-Bcc')) + { + $message->setBcc($headers->get('X-Swift-Bcc')->getNameAddresses()); + $headers->removeAll('X-Swift-Bcc'); + } + } +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Reporter.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Reporter.php new file mode 100644 index 0000000..d87fdc3 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Reporter.php @@ -0,0 +1,35 @@ +_reporter = $reporter; + } + + /** + * Not used. + */ + public function beforeSendPerformed(Swift_Events_SendEvent $evt) + { + } + + /** + * Invoked immediately after the Message is sent. + * @param Swift_Events_SendEvent $evt + */ + public function sendPerformed(Swift_Events_SendEvent $evt) + { + $message = $evt->getMessage(); + $failures = array_flip($evt->getFailedRecipients()); + foreach ((array) $message->getTo() as $address => $null) + { + $this->_reporter->notify( + $message, $address, (array_key_exists($address, $failures) + ? Swift_Plugins_Reporter::RESULT_FAIL + : Swift_Plugins_Reporter::RESULT_PASS) + ); + } + foreach ((array) $message->getCc() as $address => $null) + { + $this->_reporter->notify( + $message, $address, (array_key_exists($address, $failures) + ? Swift_Plugins_Reporter::RESULT_FAIL + : Swift_Plugins_Reporter::RESULT_PASS) + ); + } + foreach ((array) $message->getBcc() as $address => $null) + { + $this->_reporter->notify( + $message, $address, (array_key_exists($address, $failures) + ? Swift_Plugins_Reporter::RESULT_FAIL + : Swift_Plugins_Reporter::RESULT_PASS) + ); + } + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Reporters/HitReporter.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Reporters/HitReporter.php new file mode 100644 index 0000000..af5d7e3 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Reporters/HitReporter.php @@ -0,0 +1,61 @@ +_failures_cache[$address])) + { + $this->_failures[] = $address; + $this->_failures_cache[$address] = true; + } + } + + /** + * Get an array of addresses for which delivery failed. + * @return array + */ + public function getFailedRecipients() + { + return $this->_failures; + } + + /** + * Clear the buffer (empty the list). + */ + public function clear() + { + $this->_failures = $this->_failures_cache = array(); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Reporters/HtmlReporter.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Reporters/HtmlReporter.php new file mode 100644 index 0000000..119c4b2 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Reporters/HtmlReporter.php @@ -0,0 +1,45 @@ +" . PHP_EOL; + echo "PASS " . $address . PHP_EOL; + echo "" . PHP_EOL; + flush(); + } + else + { + echo "
    " . PHP_EOL; + echo "FAIL " . $address . PHP_EOL; + echo "
    " . PHP_EOL; + flush(); + } + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Sleeper.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Sleeper.php new file mode 100644 index 0000000..148cbd3 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Sleeper.php @@ -0,0 +1,26 @@ +_rate = $rate; + $this->_mode = $mode; + $this->_sleeper = $sleeper; + $this->_timer = $timer; + } + + /** + * Invoked immediately before the Message is sent. + * @param Swift_Events_SendEvent $evt + */ + public function beforeSendPerformed(Swift_Events_SendEvent $evt) + { + $time = $this->getTimestamp(); + if (!isset($this->_start)) + { + $this->_start = $time; + } + $duration = $time - $this->_start; + + if (self::BYTES_PER_MINUTE == $this->_mode) + { + $sleep = $this->_throttleBytesPerMinute($duration); + } + else + { + $sleep = $this->_throttleMessagesPerMinute($duration); + } + + if ($sleep > 0) + { + $this->sleep($sleep); + } + } + + /** + * Invoked when a Message is sent. + * @param Swift_Events_SendEvent $evt + */ + public function sendPerformed(Swift_Events_SendEvent $evt) + { + parent::sendPerformed($evt); + ++$this->_messages; + } + + /** + * Sleep for $seconds. + * @param int $seconds + */ + public function sleep($seconds) + { + if (isset($this->_sleeper)) + { + $this->_sleeper->sleep($seconds); + } + else + { + sleep($seconds); + } + } + + /** + * Get the current UNIX timestamp + * @return int + */ + public function getTimestamp() + { + if (isset($this->_timer)) + { + return $this->_timer->getTimestamp(); + } + else + { + return time(); + } + } + + // -- Private methods + + /** + * Get a number of seconds to sleep for. + * @param int $timePassed + * @return int + * @access private + */ + private function _throttleBytesPerMinute($timePassed) + { + $expectedDuration = $this->getBytesOut() / ($this->_rate / 60); + return (int) ceil($expectedDuration - $timePassed); + } + + /** + * Get a number of seconds to sleep for. + * @param int $timePassed + * @return int + * @access private + */ + private function _throttleMessagesPerMinute($timePassed) + { + $expectedDuration = $this->_messages / ($this->_rate / 60); + return (int) ceil($expectedDuration - $timePassed); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Timer.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Timer.php new file mode 100644 index 0000000..92207bf --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Timer.php @@ -0,0 +1,26 @@ +register('properties.charset')->asValue($charset); + return $this; + } + + /** + * Set the directory where temporary files can be saved. + * @param string $dir + * @return Swift_Preferences + */ + public function setTempDir($dir) + { + Swift_DependencyContainer::getInstance() + ->register('tempdir')->asValue($dir); + return $this; + } + + /** + * Set the type of cache to use (i.e. "disk" or "array"). + * @param string $type + * @return Swift_Preferences + */ + public function setCacheType($type) + { + Swift_DependencyContainer::getInstance() + ->register('cache')->asAliasOf(sprintf('cache.%s', $type)); + return $this; + } + + /** + * Add the + * @param boolean $dotEscape + * @return Swift_Preferences + */ + public function setQPDotEscape($dotEscape) + { + $dotEscape=!empty($dotEscape); + Swift_DependencyContainer::getInstance() + -> register('mime.qpcontentencoder') + -> asNewInstanceOf('Swift_Mime_ContentEncoder_QpContentEncoder') + -> withDependencies(array('mime.charstream', 'mime.bytecanonicalizer')) + -> addConstructorValue($dotEscape); + return $this; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ReplacementFilterFactory.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ReplacementFilterFactory.php new file mode 100644 index 0000000..db29e6d --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ReplacementFilterFactory.php @@ -0,0 +1,27 @@ +createDependenciesFor('transport.sendmail') + ); + + $this->setCommand($command); + } + + /** + * Create a new SendmailTransport instance. + * @param string $command + * @return Swift_SendmailTransport + */ + public static function newInstance($command = '/usr/sbin/sendmail -bs') + { + return new self($command); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SmtpTransport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SmtpTransport.php new file mode 100644 index 0000000..0e69b37 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SmtpTransport.php @@ -0,0 +1,54 @@ +createDependenciesFor('transport.smtp') + ); + + $this->setHost($host); + $this->setPort($port); + $this->setEncryption($security); + } + + /** + * Create a new SmtpTransport instance. + * @param string $host + * @param int $port + * @param int $security + * @return Swift_SmtpTransport + */ + public static function newInstance($host = 'localhost', $port = 25, + $security = null) + { + return new self($host, $port, $security); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Spool.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Spool.php new file mode 100644 index 0000000..daeeefb --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Spool.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Interface for spools. + * @package Swift + * @author Fabien Potencier + */ +interface Swift_Spool +{ + /** + * Starts this Spool mechanism. + */ + public function start(); + + /** + * Stops this Spool mechanism. + */ + public function stop(); + + /** + * Tests if this Spool mechanism has started. + * + * @return boolean + */ + public function isStarted(); + + /** + * Queues a message. + * @param Swift_Mime_Message $message The message to store + * + * @return boolean Whether the operation has succeeded + */ + public function queueMessage(Swift_Mime_Message $message); + + /** + * Sends messages using the given transport instance. + * + * @param Swift_Transport $transport A transport instance + * @param string[] &$failedRecipients An array of failures by-reference + * + * @return int The number of sent emails + */ + public function flushQueue(Swift_Transport $transport, &$failedRecipients = null); +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SpoolTransport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SpoolTransport.php new file mode 100644 index 0000000..156f9b6 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SpoolTransport.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Stores Messages in a queue. + * @package Swift + * @author Fabien Potencier + */ +class Swift_SpoolTransport extends Swift_Transport_SpoolTransport +{ + /** + * Create a new SpoolTransport. + * @param Swift_Spool $spool + */ + public function __construct(Swift_Spool $spool) + { + $arguments = Swift_DependencyContainer::getInstance() + ->createDependenciesFor('transport.spool'); + + $arguments[] = $spool; + + call_user_func_array( + array($this, 'Swift_Transport_SpoolTransport::__construct'), + $arguments + ); + } + + /** + * Create a new SpoolTransport instance. + * @param Swift_Spool $spool + * @return Swift_SpoolTransport + */ + public static function newInstance(Swift_Spool $spool) + { + return new self($spool); + } +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilter.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilter.php new file mode 100644 index 0000000..6c262ce --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilter.php @@ -0,0 +1,33 @@ +_search = $search; + $this->_index = array(); + $this->_tree = array(); + $this->_replace = array(); + $this->_repSize = array(); + + $tree = null; + $i = null; + $last_size = $size = 0; + foreach ($search as $i => $search_element) + { + if ($tree !== null) + { + $tree[-1] = min (count($replace) - 1, $i - 1); + $tree[-2] = $last_size; + } + $tree = &$this->_tree; + if (is_array ($search_element)) + { + foreach ($search_element as $k => $char) + { + $this->_index[$char] = true; + if (!isset($tree[$char])) + { + $tree[$char] = array(); + } + $tree = &$tree[$char]; + } + $last_size = $k+1; + $size = max($size, $last_size); + } + else + { + $last_size = 1; + if (!isset($tree[$search_element])) + { + $tree[$search_element] = array(); + } + $tree = &$tree[$search_element]; + $size = max($last_size, $size); + $this->_index[$search_element] = true; + } + } + if ($i !== null) + { + $tree[-1] = min (count ($replace) - 1, $i); + $tree[-2] = $last_size; + $this->_treeMaxLen = $size; + } + foreach ($replace as $rep) + { + if (!is_array($rep)) + { + $rep = array ($rep); + } + $this->_replace[] = $rep; + } + for ($i = count($this->_replace) - 1; $i >= 0; --$i) + { + $this->_replace[$i] = $rep = $this->filter($this->_replace[$i], $i); + $this->_repSize[$i] = count($rep); + } + } + + /** + * Returns true if based on the buffer passed more bytes should be buffered. + * @param array $buffer + * @return boolean + */ + public function shouldBuffer($buffer) + { + $endOfBuffer = end($buffer); + return isset ($this->_index[$endOfBuffer]); + } + + /** + * Perform the actual replacements on $buffer and return the result. + * @param array $buffer + * @return array + */ + public function filter($buffer, $_minReplaces = -1) + { + if ($this->_treeMaxLen == 0) + { + return $buffer; + } + + $newBuffer = array(); + $buf_size = count($buffer); + for ($i = 0; $i < $buf_size; ++$i) + { + $search_pos = $this->_tree; + $last_found = PHP_INT_MAX; + // We try to find if the next byte is part of a search pattern + for ($j = 0; $j <= $this->_treeMaxLen; ++$j) + { + // We have a new byte for a search pattern + if (isset ($buffer [$p = $i + $j]) && isset($search_pos[$buffer[$p]])) + { + $search_pos = $search_pos[$buffer[$p]]; + // We have a complete pattern, save, in case we don't find a better match later + if (isset($search_pos[- 1]) && $search_pos[-1] < $last_found + && $search_pos[-1] > $_minReplaces) + { + $last_found = $search_pos[-1]; + $last_size = $search_pos[-2]; + } + } + // We got a complete pattern + elseif ($last_found !== PHP_INT_MAX) + { + // Adding replacement datas to output buffer + $rep_size = $this->_repSize[$last_found]; + for ($j = 0; $j < $rep_size; ++$j) + { + $newBuffer[] = $this->_replace[$last_found][$j]; + } + // We Move cursor forward + $i += $last_size - 1; + // Edge Case, last position in buffer + if ($i >= $buf_size) + { + $newBuffer[] = $buffer[$i]; + } + + // We start the next loop + continue 2; + } + else + { + // this byte is not in a pattern and we haven't found another pattern + break; + } + } + // Normal byte, move it to output buffer + $newBuffer[] = $buffer[$i]; + } + + return $newBuffer; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilter.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilter.php new file mode 100644 index 0000000..deebcd6 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilter.php @@ -0,0 +1,65 @@ +_search = $search; + $this->_replace = $replace; + } + + /** + * Returns true if based on the buffer passed more bytes should be buffered. + * @param string $buffer + * @return boolean + */ + public function shouldBuffer($buffer) + { + $endOfBuffer = substr($buffer, -1); + foreach ((array) $this->_search as $needle) + { + if (false !== strpos($needle, $endOfBuffer)) + { + return true; + } + } + return false; + } + + /** + * Perform the actual replacements on $buffer and return the result. + * @param string $buffer + * @return string + */ + public function filter($buffer) + { + return str_replace($this->_search, $this->_replace, $buffer); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilterFactory.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilterFactory.php new file mode 100644 index 0000000..4b64487 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilterFactory.php @@ -0,0 +1,51 @@ +_filters[$search][$replace])) + { + if (!isset($this->_filters[$search])) + { + $this->_filters[$search] = array(); + } + + if (!isset($this->_filters[$search][$replace])) + { + $this->_filters[$search][$replace] = array(); + } + + $this->_filters[$search][$replace] + = new Swift_StreamFilters_StringReplacementFilter($search, $replace); + } + + return $this->_filters[$search][$replace]; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SwiftException.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SwiftException.php new file mode 100644 index 0000000..bd3b656 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SwiftException.php @@ -0,0 +1,28 @@ +_eventDispatcher = $dispatcher; + $this->_buffer = $buf; + $this->_lookupHostname(); + } + + /** + * Set the name of the local domain which Swift will identify itself as. + * This should be a fully-qualified domain name and should be truly the domain + * you're using. If your server doesn't have a domain name, use the IP in square + * brackets (i.e. [127.0.0.1]). + * + * @param string $domain + * @return Swift_Transport_AbstractSmtpTransport + */ + public function setLocalDomain($domain) + { + $this->_domain = $domain; + return $this; + } + + /** + * Get the name of the domain Swift will identify as. + * + * @return string + */ + public function getLocalDomain() + { + return $this->_domain; + } + + + /** + * Sets the sourceIp + * @param string $source + */ + public function setSourceIp($source) + { + $this->_sourceIp=$source; + } + + /** + * Returns the ip used to connect to the destination + * @return string + */ + public function getSourceIp() + { + return $this->_sourceIp; + } + + /** + * Start the SMTP connection. + */ + public function start() + { + if (!$this->_started) + { + if ($evt = $this->_eventDispatcher->createTransportChangeEvent($this)) + { + $this->_eventDispatcher->dispatchEvent($evt, 'beforeTransportStarted'); + if ($evt->bubbleCancelled()) + { + return; + } + } + + try + { + $this->_buffer->initialize($this->_getBufferParams()); + } + catch (Swift_TransportException $e) + { + $this->_throwException($e); + } + $this->_readGreeting(); + $this->_doHeloCommand(); + + if ($evt) + { + $this->_eventDispatcher->dispatchEvent($evt, 'transportStarted'); + } + + $this->_started = true; + } + } + + /** + * Test if an SMTP connection has been established. + * + * @return boolean + */ + public function isStarted() + { + return $this->_started; + } + + /** + * Send the given Message. + * + * Recipient/sender data will be retrieved from the Message API. + * The return value is the number of recipients who were accepted for delivery. + * + * @param Swift_Mime_Message $message + * @param string[] &$failedRecipients to collect failures by-reference + * @return int + */ + public function send(Swift_Mime_Message $message, &$failedRecipients = null) + { + $sent = 0; + $failedRecipients = (array) $failedRecipients; + + if ($evt = $this->_eventDispatcher->createSendEvent($this, $message)) + { + $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed'); + if ($evt->bubbleCancelled()) + { + return 0; + } + } + + if (!$reversePath = $this->_getReversePath($message)) + { + throw new Swift_TransportException( + 'Cannot send message without a sender address' + ); + } + + $to = (array) $message->getTo(); + $cc = (array) $message->getCc(); + $bcc = (array) $message->getBcc(); + + $message->setBcc(array()); + + try + { + $sent += $this->_sendTo($message, $reversePath, $to, $failedRecipients); + $sent += $this->_sendCc($message, $reversePath, $cc, $failedRecipients); + $sent += $this->_sendBcc($message, $reversePath, $bcc, $failedRecipients); + } + catch (Exception $e) + { + $message->setBcc($bcc); + throw $e; + } + + $message->setBcc($bcc); + + if ($evt) + { + if ($sent == count($to) + count($cc) + count($bcc)) + { + $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS); + } + elseif ($sent > 0) + { + $evt->setResult(Swift_Events_SendEvent::RESULT_TENTATIVE); + } + else + { + $evt->setResult(Swift_Events_SendEvent::RESULT_FAILED); + } + $evt->setFailedRecipients($failedRecipients); + $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); + } + + $message->generateId(); //Make sure a new Message ID is used + + return $sent; + } + + /** + * Stop the SMTP connection. + */ + public function stop() + { + if ($this->_started) + { + if ($evt = $this->_eventDispatcher->createTransportChangeEvent($this)) + { + $this->_eventDispatcher->dispatchEvent($evt, 'beforeTransportStopped'); + if ($evt->bubbleCancelled()) + { + return; + } + } + + try + { + $this->executeCommand("QUIT\r\n", array(221)); + } + catch (Swift_TransportException $e) {} + + try + { + $this->_buffer->terminate(); + + if ($evt) + { + $this->_eventDispatcher->dispatchEvent($evt, 'transportStopped'); + } + } + catch (Swift_TransportException $e) + { + $this->_throwException($e); + } + } + $this->_started = false; + } + + /** + * Register a plugin. + * + * @param Swift_Events_EventListener $plugin + */ + public function registerPlugin(Swift_Events_EventListener $plugin) + { + $this->_eventDispatcher->bindEventListener($plugin); + } + + /** + * Reset the current mail transaction. + */ + public function reset() + { + $this->executeCommand("RSET\r\n", array(250)); + } + + /** + * Get the IoBuffer where read/writes are occurring. + * + * @return Swift_Transport_IoBuffer + */ + public function getBuffer() + { + return $this->_buffer; + } + + /** + * Run a command against the buffer, expecting the given response codes. + * + * If no response codes are given, the response will not be validated. + * If codes are given, an exception will be thrown on an invalid response. + * + * @param string $command + * @param int[] $codes + * @param string[] &$failures + * @return string + */ + public function executeCommand($command, $codes = array(), &$failures = null) + { + $failures = (array) $failures; + $seq = $this->_buffer->write($command); + $response = $this->_getFullResponse($seq); + if ($evt = $this->_eventDispatcher->createCommandEvent($this, $command, $codes)) + { + $this->_eventDispatcher->dispatchEvent($evt, 'commandSent'); + } + $this->_assertResponseCode($response, $codes); + return $response; + } + + // -- Protected methods + + /** Read the opening SMTP greeting */ + protected function _readGreeting() + { + $this->_assertResponseCode($this->_getFullResponse(0), array(220)); + } + + /** Send the HELO welcome */ + protected function _doHeloCommand() + { + $this->executeCommand( + sprintf("HELO %s\r\n", $this->_domain), array(250) + ); + } + + /** Send the MAIL FROM command */ + protected function _doMailFromCommand($address) + { + $this->executeCommand( + sprintf("MAIL FROM: <%s>\r\n", $address), array(250) + ); + } + + /** Send the RCPT TO command */ + protected function _doRcptToCommand($address) + { + $this->executeCommand( + sprintf("RCPT TO: <%s>\r\n", $address), array(250, 251, 252) + ); + } + + /** Send the DATA command */ + protected function _doDataCommand() + { + $this->executeCommand("DATA\r\n", array(354)); + } + + /** Stream the contents of the message over the buffer */ + protected function _streamMessage(Swift_Mime_Message $message) + { + $this->_buffer->setWriteTranslations(array("\r\n." => "\r\n..")); + try + { + $message->toByteStream($this->_buffer); + $this->_buffer->flushBuffers(); + } + catch (Swift_TransportException $e) + { + $this->_throwException($e); + } + $this->_buffer->setWriteTranslations(array()); + $this->executeCommand("\r\n.\r\n", array(250)); + } + + /** Determine the best-use reverse path for this message */ + protected function _getReversePath(Swift_Mime_Message $message) + { + $return = $message->getReturnPath(); + $sender = $message->getSender(); + $from = $message->getFrom(); + $path = null; + if (!empty($return)) + { + $path = $return; + } + elseif (!empty($sender)) + { + // Don't use array_keys + reset($sender); // Reset Pointer to first pos + $path = key($sender); // Get key + } + elseif (!empty($from)) + { + reset($from); // Reset Pointer to first pos + $path = key($from); // Get key + } + return $path; + } + + /** Throw a TransportException, first sending it to any listeners */ + protected function _throwException(Swift_TransportException $e) + { + if ($evt = $this->_eventDispatcher->createTransportExceptionEvent($this, $e)) + { + $this->_eventDispatcher->dispatchEvent($evt, 'exceptionThrown'); + if (!$evt->bubbleCancelled()) + { + throw $e; + } + } + else + { + throw $e; + } + } + + /** Throws an Exception if a response code is incorrect */ + protected function _assertResponseCode($response, $wanted) + { + list($code) = sscanf($response, '%3d'); + $valid = (empty($wanted) || in_array($code, $wanted)); + + if ($evt = $this->_eventDispatcher->createResponseEvent($this, $response, + $valid)) + { + $this->_eventDispatcher->dispatchEvent($evt, 'responseReceived'); + } + + if (!$valid) + { + $this->_throwException( + new Swift_TransportException( + 'Expected response code ' . implode('/', $wanted) . ' but got code ' . + '"' . $code . '", with message "' . $response . '"' + ) + ); + } + } + + /** Get an entire multi-line response using its sequence number */ + protected function _getFullResponse($seq) + { + $response = ''; + try + { + do + { + $line = $this->_buffer->readLine($seq); + $response .= $line; + } + while (null !== $line && false !== $line && ' ' != $line{3}); + } + catch (Swift_TransportException $e) + { + $this->_throwException($e); + } + return $response; + } + + // -- Private methods + + /** Send an email to the given recipients from the given reverse path */ + private function _doMailTransaction($message, $reversePath, + array $recipients, array &$failedRecipients) + { + $sent = 0; + $this->_doMailFromCommand($reversePath); + foreach ($recipients as $forwardPath) + { + try + { + $this->_doRcptToCommand($forwardPath); + $sent++; + } + catch (Swift_TransportException $e) + { + $failedRecipients[] = $forwardPath; + } + } + + if ($sent != 0) + { + $this->_doDataCommand(); + $this->_streamMessage($message); + } + else + { + $this->reset(); + } + + return $sent; + } + + /** Send a message to the given To: recipients */ + private function _sendTo(Swift_Mime_Message $message, $reversePath, + array $to, array &$failedRecipients) + { + if (empty($to)) + { + return 0; + } + return $this->_doMailTransaction($message, $reversePath, array_keys($to), + $failedRecipients); + } + + /** Send a message to the given Cc: recipients */ + private function _sendCc(Swift_Mime_Message $message, $reversePath, + array $cc, array &$failedRecipients) + { + if (empty($cc)) + { + return 0; + } + return $this->_doMailTransaction($message, $reversePath, array_keys($cc), + $failedRecipients); + } + + /** Send a message to all Bcc: recipients */ + private function _sendBcc(Swift_Mime_Message $message, $reversePath, + array $bcc, array &$failedRecipients) + { + $sent = 0; + foreach ($bcc as $forwardPath => $name) + { + $message->setBcc(array($forwardPath => $name)); + $sent += $this->_doMailTransaction( + $message, $reversePath, array($forwardPath), $failedRecipients + ); + } + return $sent; + } + + /** Try to determine the hostname of the server this is run on */ + private function _lookupHostname() + { + if (!empty($_SERVER['SERVER_NAME']) + && $this->_isFqdn($_SERVER['SERVER_NAME'])) + { + $this->_domain = $_SERVER['SERVER_NAME']; + } + elseif (!empty($_SERVER['SERVER_ADDR'])) + { + $this->_domain = sprintf('[%s]', $_SERVER['SERVER_ADDR']); + } + } + + /** Determine is the $hostname is a fully-qualified name */ + private function _isFqdn($hostname) + { + //We could do a really thorough check, but there's really no point + if (false !== $dotPos = strpos($hostname, '.')) + { + return ($dotPos > 0) && ($dotPos != strlen($hostname) - 1); + } + else + { + return false; + } + } + + /** + * Destructor. + */ + public function __destruct() + { + $this->stop(); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php new file mode 100644 index 0000000..1595211 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php @@ -0,0 +1,85 @@ +executeCommand("AUTH CRAM-MD5\r\n", array(334)); + $challenge = base64_decode(substr($challenge, 4)); + $message = base64_encode( + $username . ' ' . $this->_getResponse($password, $challenge) + ); + $agent->executeCommand(sprintf("%s\r\n", $message), array(235)); + return true; + } + catch (Swift_TransportException $e) + { + $agent->executeCommand("RSET\r\n", array(250)); + return false; + } + } + + /** + * Generate a CRAM-MD5 response from a server challenge. + * @param string $secret + * @param string $challenge + * @return string + */ + private function _getResponse($secret, $challenge) + { + if (strlen($secret) > 64) + { + $secret = pack('H32', md5($secret)); + } + + if (strlen($secret) < 64) + { + $secret = str_pad($secret, 64, chr(0)); + } + + $k_ipad = substr($secret, 0, 64) ^ str_repeat(chr(0x36), 64); + $k_opad = substr($secret, 0, 64) ^ str_repeat(chr(0x5C), 64); + + $inner = pack('H32', md5($k_ipad . $challenge)); + $digest = md5($k_opad . $inner); + + return $digest; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/LoginAuthenticator.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/LoginAuthenticator.php new file mode 100644 index 0000000..312b7e2 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/LoginAuthenticator.php @@ -0,0 +1,55 @@ +executeCommand("AUTH LOGIN\r\n", array(334)); + $agent->executeCommand(sprintf("%s\r\n", base64_encode($username)), array(334)); + $agent->executeCommand(sprintf("%s\r\n", base64_encode($password)), array(235)); + return true; + } + catch (Swift_TransportException $e) + { + $agent->executeCommand("RSET\r\n", array(250)); + return false; + } + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php new file mode 100644 index 0000000..ca588ea --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php @@ -0,0 +1,54 @@ +executeCommand(sprintf("AUTH PLAIN %s\r\n", $message), array(235)); + return true; + } + catch (Swift_TransportException $e) + { + $agent->executeCommand("RSET\r\n", array(250)); + return false; + } + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php new file mode 100644 index 0000000..1d98cd6 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php @@ -0,0 +1,259 @@ +setAuthenticators($authenticators); + } + + /** + * Set the Authenticators which can process a login request. + * @param Swift_Transport_Esmtp_Authenticator[] $authenticators + */ + public function setAuthenticators(array $authenticators) + { + $this->_authenticators = $authenticators; + } + + /** + * Get the Authenticators which can process a login request. + * @return Swift_Transport_Esmtp_Authenticator[] + */ + public function getAuthenticators() + { + return $this->_authenticators; + } + + /** + * Set the username to authenticate with. + * @param string $username + */ + public function setUsername($username) + { + $this->_username = $username; + } + + /** + * Get the username to authenticate with. + * @return string + */ + public function getUsername() + { + return $this->_username; + } + + /** + * Set the password to authenticate with. + * @param string $password + */ + public function setPassword($password) + { + $this->_password = $password; + } + + /** + * Get the password to authenticate with. + * @return string + */ + public function getPassword() + { + return $this->_password; + } + + /** + * Set the auth mode to use to authenticate. + * @param string $mode + */ + public function setAuthMode($mode) + { + $this->_auth_mode = $mode; + } + + /** + * Get the auth mode to use to authenticate. + * @return string + */ + public function getAuthMode() + { + return $this->_auth_mode; + } + + /** + * Get the name of the ESMTP extension this handles. + * @return boolean + */ + public function getHandledKeyword() + { + return 'AUTH'; + } + + /** + * Set the parameters which the EHLO greeting indicated. + * @param string[] $parameters + */ + public function setKeywordParams(array $parameters) + { + $this->_esmtpParams = $parameters; + } + + /** + * Runs immediately after a EHLO has been issued. + * @param Swift_Transport_SmtpAgent $agent to read/write + */ + public function afterEhlo(Swift_Transport_SmtpAgent $agent) + { + if ($this->_username) + { + $count = 0; + foreach ($this->_getAuthenticatorsForAgent() as $authenticator) + { + if (in_array(strtolower($authenticator->getAuthKeyword()), + array_map('strtolower', $this->_esmtpParams))) + { + $count++; + if ($authenticator->authenticate($agent, $this->_username, $this->_password)) + { + return; + } + } + } + throw new Swift_TransportException( + 'Failed to authenticate on SMTP server with username "' . + $this->_username . '" using ' . $count . ' possible authenticators' + ); + } + } + + /** + * Not used. + */ + public function getMailParams() + { + return array(); + } + + /** + * Not used. + */ + public function getRcptParams() + { + return array(); + } + + /** + * Not used. + */ + public function onCommand(Swift_Transport_SmtpAgent $agent, + $command, $codes = array(), &$failedRecipients = null, &$stop = false) + { + } + + /** + * Returns +1, -1 or 0 according to the rules for usort(). + * This method is called to ensure extensions can be execute in an appropriate order. + * @param string $esmtpKeyword to compare with + * @return int + */ + public function getPriorityOver($esmtpKeyword) + { + return 0; + } + + /** + * Returns an array of method names which are exposed to the Esmtp class. + * @return string[] + */ + public function exposeMixinMethods() + { + return array('setUsername', 'getUsername', 'setPassword', 'getPassword', 'setAuthMode', 'getAuthMode'); + } + + /** + * Not used. + */ + public function resetState() + { + } + + // -- Protected methods + + /** + * Returns the authenticator list for the given agent. + * @param Swift_Transport_SmtpAgent $agent + * @return array + * @access protected + */ + protected function _getAuthenticatorsForAgent() + { + if (!$mode = strtolower($this->_auth_mode)) + { + return $this->_authenticators; + } + + foreach ($this->_authenticators as $authenticator) + { + if (strtolower($authenticator->getAuthKeyword()) == $mode) + { + return array($authenticator); + } + } + + throw new Swift_TransportException('Auth mode '.$mode.' is invalid'); + } +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Authenticator.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Authenticator.php new file mode 100644 index 0000000..4af223e --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Authenticator.php @@ -0,0 +1,37 @@ +. + * @return string[] + */ + public function getMailParams(); + + /** + * Get params which are appended to RCPT TO:<>. + * @return string[] + */ + public function getRcptParams(); + + /** + * Runs when a command is due to be sent. + * @param Swift_Transport_SmtpAgent $agent to read/write + * @param string $command to send + * @param int[] $codes expected in response + * @param string[] &$failedRecipients + * @param boolean &$stop to be set true if the command is now sent + */ + public function onCommand(Swift_Transport_SmtpAgent $agent, + $command, $codes = array(), &$failedRecipients = null, &$stop = false); + + /** + * Returns +1, -1 or 0 according to the rules for usort(). + * This method is called to ensure extensions can be execute in an appropriate order. + * @param string $esmtpKeyword to compare with + * @return int + */ + public function getPriorityOver($esmtpKeyword); + + /** + * Returns an array of method names which are exposed to the Esmtp class. + * @return string[] + */ + public function exposeMixinMethods(); + + /** + * Tells this handler to clear any buffers and reset its state. + */ + public function resetState(); + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php new file mode 100644 index 0000000..54f9ff5 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php @@ -0,0 +1,395 @@ + 'tcp', + 'host' => 'localhost', + 'port' => 25, + 'timeout' => 30, + 'blocking' => 1, + 'tls' => false, + 'type' => Swift_Transport_IoBuffer::TYPE_SOCKET + ); + + /** + * Creates a new EsmtpTransport using the given I/O buffer. + * @param Swift_Transport_IoBuffer $buf + * @param Swift_Transport_EsmtpHandler[] $extensionHandlers + * @param Swift_Events_EventDispatcher $dispatcher + */ + public function __construct(Swift_Transport_IoBuffer $buf, + array $extensionHandlers, Swift_Events_EventDispatcher $dispatcher) + { + parent::__construct($buf, $dispatcher); + $this->setExtensionHandlers($extensionHandlers); + } + + /** + * Set the host to connect to. + * @param string $host + * @return Swift_Transport_EsmtpTransport + */ + public function setHost($host) + { + $this->_params['host'] = $host; + return $this; + } + + /** + * Get the host to connect to. + * @return string + */ + public function getHost() + { + return $this->_params['host']; + } + + /** + * Set the port to connect to. + * @param int $port + * @return Swift_Transport_EsmtpTransport + */ + public function setPort($port) + { + $this->_params['port'] = (int) $port; + return $this; + } + + /** + * Get the port to connect to. + * @return int + */ + public function getPort() + { + return $this->_params['port']; + } + + /** + * Set the connection timeout. + * @param int $timeout seconds + * @return Swift_Transport_EsmtpTransport + */ + public function setTimeout($timeout) + { + $this->_params['timeout'] = (int) $timeout; + $this->_buffer->setParam('timeout', (int) $timeout); + return $this; + } + + /** + * Get the connection timeout. + * @return int + */ + public function getTimeout() + { + return $this->_params['timeout']; + } + + /** + * Set the encryption type (tls or ssl) + * @param string $encryption + * @return Swift_Transport_EsmtpTransport + */ + public function setEncryption($enc) + { + if ('tls' == $enc) + { + $this->_params['protocol'] = 'tcp'; + $this->_params['tls'] = true; + } else { + $this->_params['protocol'] = $enc; + $this->_params['tls'] = false; + } + return $this; + } + + /** + * Get the encryption type. + * @return string + */ + public function getEncryption() + { + return $this->_params['tls'] ? 'tls' : $this->_params['protocol']; + } + + /** + * Sets the sourceIp + * @param string $source + * @return Swift_Transport_EsmtpTransport + */ + public function setSourceIp($source) + { + $this->_params['sourceIp']=$source; + return $this; + } + + /** + * Returns the ip used to connect to the destination + * @return string + */ + public function getSourceIp() + { + return $this->_params['sourceIp']; + } + + /** + * Set ESMTP extension handlers. + * @param Swift_Transport_EsmtpHandler[] $handlers + * @return Swift_Transport_EsmtpTransport + */ + public function setExtensionHandlers(array $handlers) + { + $assoc = array(); + foreach ($handlers as $handler) + { + $assoc[$handler->getHandledKeyword()] = $handler; + } + uasort($assoc, array($this, '_sortHandlers')); + $this->_handlers = $assoc; + $this->_setHandlerParams(); + return $this; + } + + /** + * Get ESMTP extension handlers. + * @return Swift_Transport_EsmtpHandler[] + */ + public function getExtensionHandlers() + { + return array_values($this->_handlers); + } + + /** + * Run a command against the buffer, expecting the given response codes. + * If no response codes are given, the response will not be validated. + * If codes are given, an exception will be thrown on an invalid response. + * @param string $command + * @param int[] $codes + * @param string[] &$failures + * @return string + */ + public function executeCommand($command, $codes = array(), &$failures = null) + { + $failures = (array) $failures; + $stopSignal = false; + $response = null; + foreach ($this->_getActiveHandlers() as $handler) + { + $response = $handler->onCommand( + $this, $command, $codes, $failures, $stopSignal + ); + if ($stopSignal) + { + return $response; + } + } + return parent::executeCommand($command, $codes, $failures); + } + + // -- Mixin invocation code + + /** Mixin handling method for ESMTP handlers */ + public function __call($method, $args) + { + foreach ($this->_handlers as $handler) + { + if (in_array(strtolower($method), + array_map('strtolower', (array) $handler->exposeMixinMethods()) + )) + { + $return = call_user_func_array(array($handler, $method), $args); + //Allow fluid method calls + if (is_null($return) && substr($method, 0, 3) == 'set') + { + return $this; + } + else + { + return $return; + } + } + } + trigger_error('Call to undefined method ' . $method, E_USER_ERROR); + } + + // -- Protected methods + + /** Get the params to initialize the buffer */ + protected function _getBufferParams() + { + return $this->_params; + } + + /** Overridden to perform EHLO instead */ + protected function _doHeloCommand() + { + try + { + $response = $this->executeCommand( + sprintf("EHLO %s\r\n", $this->_domain), array(250) + ); + } + catch (Swift_TransportException $e) + { + return parent::_doHeloCommand(); + } + + if ($this->_params['tls']) + { + try + { + $this->executeCommand("STARTTLS\r\n", array(220)); + + if (!$this->_buffer->startTLS()) + { + throw new Swift_TransportException('Unable to connect with TLS encryption'); + } + + try + { + $response = $this->executeCommand( + sprintf("EHLO %s\r\n", $this->_domain), array(250) + ); + } + catch (Swift_TransportException $e) + { + return parent::_doHeloCommand(); + } + } + catch (Swift_TransportException $e) + { + $this->_throwException($e); + } + } + + $this->_capabilities = $this->_getCapabilities($response); + $this->_setHandlerParams(); + foreach ($this->_getActiveHandlers() as $handler) + { + $handler->afterEhlo($this); + } + } + + /** Overridden to add Extension support */ + protected function _doMailFromCommand($address) + { + $handlers = $this->_getActiveHandlers(); + $params = array(); + foreach ($handlers as $handler) + { + $params = array_merge($params, (array) $handler->getMailParams()); + } + $paramStr = !empty($params) ? ' ' . implode(' ', $params) : ''; + $this->executeCommand( + sprintf("MAIL FROM: <%s>%s\r\n", $address, $paramStr), array(250) + ); + } + + /** Overridden to add Extension support */ + protected function _doRcptToCommand($address) + { + $handlers = $this->_getActiveHandlers(); + $params = array(); + foreach ($handlers as $handler) + { + $params = array_merge($params, (array) $handler->getRcptParams()); + } + $paramStr = !empty($params) ? ' ' . implode(' ', $params) : ''; + $this->executeCommand( + sprintf("RCPT TO: <%s>%s\r\n", $address, $paramStr), array(250, 251, 252) + ); + } + + // -- Private methods + + /** Determine ESMTP capabilities by function group */ + private function _getCapabilities($ehloResponse) + { + $capabilities = array(); + $ehloResponse = trim($ehloResponse); + $lines = explode("\r\n", $ehloResponse); + array_shift($lines); + foreach ($lines as $line) + { + if (preg_match('/^[0-9]{3}[ -]([A-Z0-9-]+)((?:[ =].*)?)$/Di', $line, $matches)) + { + $keyword = strtoupper($matches[1]); + $paramStr = strtoupper(ltrim($matches[2], ' =')); + $params = !empty($paramStr) ? explode(' ', $paramStr) : array(); + $capabilities[$keyword] = $params; + } + } + return $capabilities; + } + + /** Set parameters which are used by each extension handler */ + private function _setHandlerParams() + { + foreach ($this->_handlers as $keyword => $handler) + { + if (array_key_exists($keyword, $this->_capabilities)) + { + $handler->setKeywordParams($this->_capabilities[$keyword]); + } + } + } + + /** Get ESMTP handlers which are currently ok to use */ + private function _getActiveHandlers() + { + $handlers = array(); + foreach ($this->_handlers as $keyword => $handler) + { + if (array_key_exists($keyword, $this->_capabilities)) + { + $handlers[] = $handler; + } + } + return $handlers; + } + + /** Custom sort for extension handler ordering */ + private function _sortHandlers($a, $b) + { + return $a->getPriorityOver($b->getHandledKeyword()); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/FailoverTransport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/FailoverTransport.php new file mode 100644 index 0000000..ffb822c --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/FailoverTransport.php @@ -0,0 +1,95 @@ +_transports); + $sent = 0; + + for ($i = 0; $i < $maxTransports + && $transport = $this->_getNextTransport(); ++$i) + { + try + { + if (!$transport->isStarted()) + { + $transport->start(); + } + + return $transport->send($message, $failedRecipients); + } + catch (Swift_TransportException $e) + { + $this->_killCurrentTransport(); + } + } + + if (count($this->_transports) == 0) + { + throw new Swift_TransportException( + 'All Transports in FailoverTransport failed, or no Transports available' + ); + } + + return $sent; + } + + // -- Protected methods + + protected function _getNextTransport() + { + if (!isset($this->_currentTransport)) + { + $this->_currentTransport = parent::_getNextTransport(); + } + return $this->_currentTransport; + } + + protected function _killCurrentTransport() + { + $this->_currentTransport = null; + parent::_killCurrentTransport(); + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/IoBuffer.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/IoBuffer.php new file mode 100644 index 0000000..9a46cd9 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/IoBuffer.php @@ -0,0 +1,63 @@ +_transports = $transports; + $this->_deadTransports = array(); + } + + /** + * Get $transports to delegate to. + * + * @return array Swift_Transport + */ + public function getTransports() + { + return array_merge($this->_transports, $this->_deadTransports); + } + + /** + * Test if this Transport mechanism has started. + * + * @return boolean + */ + public function isStarted() + { + return count($this->_transports) > 0; + } + + /** + * Start this Transport mechanism. + */ + public function start() + { + $this->_transports = array_merge($this->_transports, $this->_deadTransports); + } + + /** + * Stop this Transport mechanism. + */ + public function stop() + { + foreach ($this->_transports as $transport) + { + $transport->stop(); + } + } + + /** + * Send the given Message. + * + * Recipient/sender data will be retrieved from the Message API. + * The return value is the number of recipients who were accepted for delivery. + * + * @param Swift_Mime_Message $message + * @param string[] &$failedRecipients to collect failures by-reference + * @return int + */ + public function send(Swift_Mime_Message $message, &$failedRecipients = null) + { + $maxTransports = count($this->_transports); + $sent = 0; + + for ($i = 0; $i < $maxTransports + && $transport = $this->_getNextTransport(); ++$i) + { + try + { + if (!$transport->isStarted()) + { + $transport->start(); + } + if ($sent = $transport->send($message, $failedRecipients)) + { + break; + } + } + catch (Swift_TransportException $e) + { + $this->_killCurrentTransport(); + } + } + + if (count($this->_transports) == 0) + { + throw new Swift_TransportException( + 'All Transports in LoadBalancedTransport failed, or no Transports available' + ); + } + + return $sent; + } + + /** + * Register a plugin. + * + * @param Swift_Events_EventListener $plugin + */ + public function registerPlugin(Swift_Events_EventListener $plugin) + { + foreach ($this->_transports as $transport) + { + $transport->registerPlugin($plugin); + } + } + + // -- Protected methods + + /** + * Rotates the transport list around and returns the first instance. + * + * @return Swift_Transport + * @access protected + */ + protected function _getNextTransport() + { + if ($next = array_shift($this->_transports)) + { + $this->_transports[] = $next; + } + return $next; + } + + /** + * Tag the currently used (top of stack) transport as dead/useless. + * + * @access protected + */ + protected function _killCurrentTransport() + { + if ($transport = array_pop($this->_transports)) + { + try + { + $transport->stop(); + } + catch (Exception $e) + { + } + $this->_deadTransports[] = $transport; + } + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/MailInvoker.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/MailInvoker.php new file mode 100644 index 0000000..dda882f --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/MailInvoker.php @@ -0,0 +1,36 @@ +_invoker = $invoker; + $this->_eventDispatcher = $eventDispatcher; + } + + /** + * Not used. + */ + public function isStarted() + { + return false; + } + + /** + * Not used. + */ + public function start() + { + } + + /** + * Not used. + */ + public function stop() + { + } + + /** + * Set the additional parameters used on the mail() function. + * + * This string is formatted for sprintf() where %s is the sender address. + * + * @param string $params + * @return Swift_Transport_MailTransport + */ + public function setExtraParams($params) + { + $this->_extraParams = $params; + return $this; + } + + /** + * Get the additional parameters used on the mail() function. + * + * This string is formatted for sprintf() where %s is the sender address. + * + * @return string + */ + public function getExtraParams() + { + return $this->_extraParams; + } + + /** + * Send the given Message. + * + * Recipient/sender data will be retrieved from the Message API. + * The return value is the number of recipients who were accepted for delivery. + * + * @param Swift_Mime_Message $message + * @param string[] &$failedRecipients to collect failures by-reference + * @return int + */ + public function send(Swift_Mime_Message $message, &$failedRecipients = null) + { + $failedRecipients = (array) $failedRecipients; + + if ($evt = $this->_eventDispatcher->createSendEvent($this, $message)) + { + $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed'); + if ($evt->bubbleCancelled()) + { + return 0; + } + } + + $count = ( + count((array) $message->getTo()) + + count((array) $message->getCc()) + + count((array) $message->getBcc()) + ); + + $toHeader = $message->getHeaders()->get('To'); + $subjectHeader = $message->getHeaders()->get('Subject'); + + if (!$toHeader) + { + throw new Swift_TransportException( + 'Cannot send message without a recipient' + ); + } + $to = $toHeader->getFieldBody(); + $subject = $subjectHeader ? $subjectHeader->getFieldBody() : ''; + + $reversePath = $this->_getReversePath($message); + + //Remove headers that would otherwise be duplicated + $message->getHeaders()->remove('To'); + $message->getHeaders()->remove('Subject'); + + $messageStr = $message->toString(); + + $message->getHeaders()->set($toHeader); + $message->getHeaders()->set($subjectHeader); + + //Separate headers from body + if (false !== $endHeaders = strpos($messageStr, "\r\n\r\n")) + { + $headers = substr($messageStr, 0, $endHeaders) . "\r\n"; //Keep last EOL + $body = substr($messageStr, $endHeaders + 4); + } + else + { + $headers = $messageStr . "\r\n"; + $body = ''; + } + + unset($messageStr); + + if ("\r\n" != PHP_EOL) //Non-windows (not using SMTP) + { + $headers = str_replace("\r\n", PHP_EOL, $headers); + $body = str_replace("\r\n", PHP_EOL, $body); + } + else //Windows, using SMTP + { + $headers = str_replace("\r\n.", "\r\n..", $headers); + $body = str_replace("\r\n.", "\r\n..", $body); + } + + if ($this->_invoker->mail($to, $subject, $body, $headers, + sprintf($this->_extraParams, $reversePath))) + { + if ($evt) + { + $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS); + $evt->setFailedRecipients($failedRecipients); + $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); + } + } + else + { + $failedRecipients = array_merge( + $failedRecipients, + array_keys((array) $message->getTo()), + array_keys((array) $message->getCc()), + array_keys((array) $message->getBcc()) + ); + + if ($evt) + { + $evt->setResult(Swift_Events_SendEvent::RESULT_FAILED); + $evt->setFailedRecipients($failedRecipients); + $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); + } + + $message->generateId(); + + $count = 0; + } + + return $count; + } + + /** + * Register a plugin. + * + * @param Swift_Events_EventListener $plugin + */ + public function registerPlugin(Swift_Events_EventListener $plugin) + { + $this->_eventDispatcher->bindEventListener($plugin); + } + + // -- Private methods + + /** Determine the best-use reverse path for this message */ + private function _getReversePath(Swift_Mime_Message $message) + { + $return = $message->getReturnPath(); + $sender = $message->getSender(); + $from = $message->getFrom(); + $path = null; + if (!empty($return)) + { + $path = $return; + } + elseif (!empty($sender)) + { + $keys = array_keys($sender); + $path = array_shift($keys); + } + elseif (!empty($from)) + { + $keys = array_keys($from); + $path = array_shift($keys); + } + return $path; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/NullTransport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/NullTransport.php new file mode 100644 index 0000000..c60d938 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/NullTransport.php @@ -0,0 +1,90 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Pretends messages have been sent, but just ignores them. + * @package Swift + * @author Fabien Potencier + */ +class Swift_Transport_NullTransport implements Swift_Transport +{ + /** The event dispatcher from the plugin API */ + private $_eventDispatcher; + + /** + * Constructor. + */ + public function __construct(Swift_Events_EventDispatcher $eventDispatcher) + { + $this->_eventDispatcher = $eventDispatcher; + } + + /** + * Tests if this Transport mechanism has started. + * + * @return boolean + */ + public function isStarted() + { + return true; + } + + /** + * Starts this Transport mechanism. + */ + public function start() + { + } + + /** + * Stops this Transport mechanism. + */ + public function stop() + { + } + + /** + * Sends the given message. + * + * @param Swift_Mime_Message $message + * @param string[] &$failedRecipients to collect failures by-reference + * + * @return int The number of sent emails + */ + public function send(Swift_Mime_Message $message, &$failedRecipients = null) + { + if ($evt = $this->_eventDispatcher->createSendEvent($this, $message)) + { + $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed'); + if ($evt->bubbleCancelled()) + { + return 0; + } + } + + if ($evt) + { + $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS); + $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); + } + + return 0; + } + + /** + * Register a plugin. + * + * @param Swift_Events_EventListener $plugin + */ + public function registerPlugin(Swift_Events_EventListener $plugin) + { + $this->_eventDispatcher->bindEventListener($plugin); + } +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SendmailTransport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SendmailTransport.php new file mode 100644 index 0000000..1ed74e0 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SendmailTransport.php @@ -0,0 +1,170 @@ + 30, + 'blocking' => 1, + 'command' => '/usr/sbin/sendmail -bs', + 'type' => Swift_Transport_IoBuffer::TYPE_PROCESS + ); + + /** + * Create a new SendmailTransport with $buf for I/O. + * @param Swift_Transport_IoBuffer $buf + * @param Swift_Events_EventDispatcher $dispatcher + */ + public function __construct(Swift_Transport_IoBuffer $buf, + Swift_Events_EventDispatcher $dispatcher) + { + parent::__construct($buf, $dispatcher); + } + + /** + * Start the standalone SMTP session if running in -bs mode. + */ + public function start() + { + if (false !== strpos($this->getCommand(), ' -bs')) + { + parent::start(); + } + } + + /** + * Set the command to invoke. + * If using -t mode you are strongly advised to include -oi or -i in the + * flags. For example: /usr/sbin/sendmail -oi -t + * Swift will append a -f flag if one is not present. + * The recommended mode is "-bs" since it is interactive and failure notifications + * are hence possible. + * @param string $command + * @return Swift_Transport_SendmailTransport + */ + public function setCommand($command) + { + $this->_params['command'] = $command; + return $this; + } + + /** + * Get the sendmail command which will be invoked. + * @return string + */ + public function getCommand() + { + return $this->_params['command']; + } + + /** + * Send the given Message. + * Recipient/sender data will be retrieved from the Message API. + * The return value is the number of recipients who were accepted for delivery. + * NOTE: If using 'sendmail -t' you will not be aware of any failures until + * they bounce (i.e. send() will always return 100% success). + * @param Swift_Mime_Message $message + * @param string[] &$failedRecipients to collect failures by-reference + * @return int + */ + public function send(Swift_Mime_Message $message, &$failedRecipients = null) + { + $failedRecipients = (array) $failedRecipients; + $command = $this->getCommand(); + $buffer = $this->getBuffer(); + + if (false !== strpos($command, ' -t')) + { + if ($evt = $this->_eventDispatcher->createSendEvent($this, $message)) + { + $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed'); + if ($evt->bubbleCancelled()) + { + return 0; + } + } + + if (false === strpos($command, ' -f')) + { + $command .= ' -f' . $this->_getReversePath($message); + } + + $buffer->initialize(array_merge($this->_params, array('command' => $command))); + + if (false === strpos($command, ' -i') && false === strpos($command, ' -oi')) + { + $buffer->setWriteTranslations(array("\r\n" => "\n", "\n." => "\n..")); + } + else + { + $buffer->setWriteTranslations(array("\r\n"=>"\n")); + } + + $count = count((array) $message->getTo()) + + count((array) $message->getCc()) + + count((array) $message->getBcc()) + ; + $message->toByteStream($buffer); + $buffer->flushBuffers(); + $buffer->setWriteTranslations(array()); + $buffer->terminate(); + + if ($evt) + { + $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS); + $evt->setFailedRecipients($failedRecipients); + $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); + } + + $message->generateId(); + } + elseif (false !== strpos($command, ' -bs')) + { + $count = parent::send($message, $failedRecipients); + } + else + { + $this->_throwException(new Swift_TransportException( + 'Unsupported sendmail command flags [' . $command . ']. ' . + 'Must be one of "-bs" or "-t" but can include additional flags.' + )); + } + + return $count; + } + + // -- Protected methods + + /** Get the params to initialize the buffer */ + protected function _getBufferParams() + { + return $this->_params; + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SimpleMailInvoker.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SimpleMailInvoker.php new file mode 100644 index 0000000..cc278d0 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SimpleMailInvoker.php @@ -0,0 +1,57 @@ +. + + */ + + +/** + * This is the implementation class for {@link Swift_Transport_MailInvoker}. + * + * @package Swift + * @subpackage Transport + * @author Chris Corbyn + */ +class Swift_Transport_SimpleMailInvoker implements Swift_Transport_MailInvoker +{ + + /** + * Send mail via the mail() function. + * + * This method takes the same arguments as PHP mail(). + * + * @param string $to + * @param string $subject + * @param string $body + * @param string $headers + * @param string $extraParams + * + * @return boolean + */ + public function mail($to, $subject, $body, $headers = null, $extraParams = null) + { + if (!ini_get('safe_mode')) + { + return @mail($to, $subject, $body, $headers, $extraParams); + } + else + { + return @mail($to, $subject, $body, $headers); + } + } + +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SmtpAgent.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SmtpAgent.php new file mode 100644 index 0000000..ee9b8ed --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SmtpAgent.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Stores Messages in a queue. + * @package Swift + * @author Fabien Potencier + */ +class Swift_Transport_SpoolTransport implements Swift_Transport +{ + /** The spool instance */ + private $_spool; + + /** The event dispatcher from the plugin API */ + private $_eventDispatcher; + + /** + * Constructor. + */ + public function __construct(Swift_Events_EventDispatcher $eventDispatcher, Swift_Spool $spool = null) + { + $this->_eventDispatcher = $eventDispatcher; + $this->_spool = $spool; + } + + /** + * Sets the spool object. + * @param Swift_Spool $spool + * @return Swift_Transport_SpoolTransport + */ + public function setSpool(Swift_Spool $spool) + { + $this->_spool = $spool; + return $this; + } + + /** + * Get the spool object. + * @return Swift_Spool + */ + public function getSpool() + { + return $this->_spool; + } + + /** + * Tests if this Transport mechanism has started. + * + * @return boolean + */ + public function isStarted() + { + return true; + } + + /** + * Starts this Transport mechanism. + */ + public function start() + { + } + + /** + * Stops this Transport mechanism. + */ + public function stop() + { + } + + /** + * Sends the given message. + * + * @param Swift_Mime_Message $message + * @param string[] &$failedRecipients to collect failures by-reference + * + * @return int The number of sent emails + */ + public function send(Swift_Mime_Message $message, &$failedRecipients = null) + { + if ($evt = $this->_eventDispatcher->createSendEvent($this, $message)) + { + $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed'); + if ($evt->bubbleCancelled()) + { + return 0; + } + } + + $success = $this->_spool->queueMessage($message); + + if ($evt) + { + $evt->setResult($success ? Swift_Events_SendEvent::RESULT_SUCCESS : Swift_Events_SendEvent::RESULT_FAILED); + $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); + } + + return 1; + } + + /** + * Register a plugin. + * + * @param Swift_Events_EventListener $plugin + */ + public function registerPlugin(Swift_Events_EventListener $plugin) + { + $this->_eventDispatcher->bindEventListener($plugin); + } +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php new file mode 100644 index 0000000..d9801fa --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php @@ -0,0 +1,329 @@ +_replacementFactory = $replacementFactory; + } + + /** + * Perform any initialization needed, using the given $params. + * Parameters will vary depending upon the type of IoBuffer used. + * @param array $params + */ + public function initialize(array $params) + { + $this->_params = $params; + switch ($params['type']) + { + case self::TYPE_PROCESS: + $this->_establishProcessConnection(); + break; + case self::TYPE_SOCKET: + default: + $this->_establishSocketConnection(); + break; + } + } + + /** + * Set an individual param on the buffer (e.g. switching to SSL). + * @param string $param + * @param mixed $value + */ + public function setParam($param, $value) + { + if (isset($this->_stream)) + { + switch ($param) + { + case 'timeout': + if ($this->_stream) + { + stream_set_timeout($this->_stream, $value); + } + break; + + case 'blocking': + if ($this->_stream) + { + stream_set_blocking($this->_stream, 1); + } + + } + } + $this->_params[$param] = $value; + } + + public function startTLS() + { + return stream_socket_enable_crypto($this->_stream, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); + } + + /** + * Perform any shutdown logic needed. + */ + public function terminate() + { + if (isset($this->_stream)) + { + switch ($this->_params['type']) + { + case self::TYPE_PROCESS: + fclose($this->_in); + fclose($this->_out); + proc_close($this->_stream); + break; + case self::TYPE_SOCKET: + default: + fclose($this->_stream); + break; + } + } + $this->_stream = null; + $this->_out = null; + $this->_in = null; + } + + /** + * Set an array of string replacements which should be made on data written + * to the buffer. This could replace LF with CRLF for example. + * @param string[] $replacements + */ + public function setWriteTranslations(array $replacements) + { + foreach ($this->_translations as $search => $replace) + { + if (!isset($replacements[$search])) + { + $this->removeFilter($search); + unset($this->_translations[$search]); + } + } + + foreach ($replacements as $search => $replace) + { + if (!isset($this->_translations[$search])) + { + $this->addFilter( + $this->_replacementFactory->createFilter($search, $replace), $search + ); + $this->_translations[$search] = true; + } + } + } + + /** + * Get a line of output (including any CRLF). + * The $sequence number comes from any writes and may or may not be used + * depending upon the implementation. + * @param int $sequence of last write to scan from + * @return string + */ + public function readLine($sequence) + { + if (isset($this->_out) && !feof($this->_out)) + { + $line = fgets($this->_out); + if (strlen($line)==0) + { + $metas = stream_get_meta_data($this->_out); + if ($metas['timed_out']) { + throw new Swift_IoException( + 'Connection to ' . + $this->_getReadConnectionDescription() . + ' Timed Out' + ); + } + } + return $line; + } + } + + /** + * Reads $length bytes from the stream into a string and moves the pointer + * through the stream by $length. If less bytes exist than are requested the + * remaining bytes are given instead. If no bytes are remaining at all, boolean + * false is returned. + * @param int $length + * @return string + */ + public function read($length) + { + if (isset($this->_out) && !feof($this->_out)) + { + $ret = fread($this->_out, $length); + if (strlen($ret)==0) + { + $metas = stream_get_meta_data($this->_out); + if ($metas['timed_out']) + { + throw new Swift_IoException( + 'Connection to ' . + $this->_getReadConnectionDescription() . + ' Timed Out' + ); + } + } + return $ret; + } + } + + /** Not implemented */ + public function setReadPointer($byteOffset) + { + } + + // -- Protected methods + + /** Flush the stream contents */ + protected function _flush() + { + if (isset($this->_in)) + { + fflush($this->_in); + } + } + + /** Write this bytes to the stream */ + protected function _commit($bytes) + { + if (isset($this->_in) + && fwrite($this->_in, $bytes)) + { + return ++$this->_sequence; + } + } + + // -- Private methods + + /** + * Establishes a connection to a remote server. + * @access private + */ + private function _establishSocketConnection() + { + $host = $this->_params['host']; + if (!empty($this->_params['protocol'])) + { + $host = $this->_params['protocol'] . '://' . $host; + } + $timeout = 15; + if (!empty($this->_params['timeout'])) + { + $timeout = $this->_params['timeout']; + } + $options = array(); + if (!empty($this->_params['sourceIp'])) + { + $options['socket']['bindto']=$this->_params['sourceIp'].':0'; + } + $this->_stream = @stream_socket_client($host.':'.$this->_params['port'], $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, stream_context_create($options)); + if (false === $this->_stream) + { + throw new Swift_TransportException( + 'Connection could not be established with host ' . $this->_params['host'] . + ' [' . $errstr . ' #' . $errno . ']' + ); + } + if (!empty($this->_params['blocking'])) + { + stream_set_blocking($this->_stream, 1); + } + else + { + stream_set_blocking($this->_stream, 0); + } + stream_set_timeout($this->_stream, $timeout); + $this->_in =& $this->_stream; + $this->_out =& $this->_stream; + } + + /** + * Opens a process for input/output. + * @access private + */ + private function _establishProcessConnection() + { + $command = $this->_params['command']; + $descriptorSpec = array( + 0 => array('pipe', 'r'), + 1 => array('pipe', 'w'), + 2 => array('pipe', 'w') + ); + $this->_stream = proc_open($command, $descriptorSpec, $pipes); + stream_set_blocking($pipes[2], 0); + if ($err = stream_get_contents($pipes[2])) + { + throw new Swift_TransportException( + 'Process could not be started [' . $err . ']' + ); + } + $this->_in =& $pipes[0]; + $this->_out =& $pipes[1]; + } + + + private function _getReadConnectionDescription() + { + switch ($this->_params['type']) + { + case self::TYPE_PROCESS: + return 'Process '.$this->_params['command']; + break; + + case self::TYPE_SOCKET: + default: + $host = $this->_params['host']; + if (!empty($this->_params['protocol'])) + { + $host = $this->_params['protocol'] . '://' . $host; + } + $host.=':'.$this->_params['port']; + return $host; + break; + } + } +} diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/TransportException.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/TransportException.php new file mode 100644 index 0000000..7df6e0b --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/TransportException.php @@ -0,0 +1,30 @@ + + */ +class Swift_Validate +{ + /** + * Grammar Object + * @var Swift_Mime_Grammar + */ + private static $grammar = null; + + /** + * Checks if an email matches the current grammars + * @param string $email + */ + public static function email($email) + { + if (self::$grammar===null) + { + self::$grammar = Swift_DependencyContainer::getInstance() + ->lookup('mime.grammar'); + } + return preg_match( + '/^' . self::$grammar->getDefinition('addr-spec') . '$/D', + $email + ); + } +} \ No newline at end of file diff --git a/vendor/swiftmailer/swiftmailer/lib/dependency_maps/cache_deps.php b/vendor/swiftmailer/swiftmailer/lib/dependency_maps/cache_deps.php new file mode 100644 index 0000000..6058206 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/dependency_maps/cache_deps.php @@ -0,0 +1,25 @@ + register('cache') + -> asAliasOf('cache.array') + + -> register('tempdir') + -> asValue('/tmp') + + -> register('cache.null') + -> asSharedInstanceOf('Swift_KeyCache_NullKeyCache') + + -> register('cache.array') + -> asSharedInstanceOf('Swift_KeyCache_ArrayKeyCache') + -> withDependencies(array('cache.inputstream')) + + -> register('cache.disk') + -> asSharedInstanceOf('Swift_KeyCache_DiskKeyCache') + -> withDependencies(array('cache.inputstream', 'tempdir')) + + -> register('cache.inputstream') + -> asNewInstanceOf('Swift_KeyCache_SimpleKeyCacheInputStream') + + ; diff --git a/vendor/swiftmailer/swiftmailer/lib/dependency_maps/message_deps.php b/vendor/swiftmailer/swiftmailer/lib/dependency_maps/message_deps.php new file mode 100644 index 0000000..38ba4c0 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/dependency_maps/message_deps.php @@ -0,0 +1,9 @@ + register('message.message') + -> asNewInstanceOf('Swift_Message') + + -> register('message.mimepart') + -> asNewInstanceOf('Swift_MimePart'); diff --git a/vendor/swiftmailer/swiftmailer/lib/dependency_maps/mime_deps.php b/vendor/swiftmailer/swiftmailer/lib/dependency_maps/mime_deps.php new file mode 100644 index 0000000..6d7b30d --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/dependency_maps/mime_deps.php @@ -0,0 +1,105 @@ + register('properties.charset') + -> asValue('utf-8') + + -> register('mime.grammar') + -> asSharedInstanceOf('Swift_Mime_Grammar') + + -> register('mime.message') + -> asNewInstanceOf('Swift_Mime_SimpleMessage') + -> withDependencies(array( + 'mime.headerset', + 'mime.qpcontentencoder', + 'cache', + 'mime.grammar', + 'properties.charset' + )) + + -> register('mime.part') + -> asNewInstanceOf('Swift_Mime_MimePart') + -> withDependencies(array( + 'mime.headerset', + 'mime.qpcontentencoder', + 'cache', + 'mime.grammar', + 'properties.charset' + )) + + -> register('mime.attachment') + -> asNewInstanceOf('Swift_Mime_Attachment') + -> withDependencies(array( + 'mime.headerset', + 'mime.base64contentencoder', + 'cache', + 'mime.grammar' + )) + -> addConstructorValue($swift_mime_types) + + -> register('mime.embeddedfile') + -> asNewInstanceOf('Swift_Mime_EmbeddedFile') + -> withDependencies(array( + 'mime.headerset', + 'mime.base64contentencoder', + 'cache', + 'mime.grammar' + )) + -> addConstructorValue($swift_mime_types) + + -> register('mime.headerfactory') + -> asNewInstanceOf('Swift_Mime_SimpleHeaderFactory') + -> withDependencies(array( + 'mime.qpheaderencoder', + 'mime.rfc2231encoder', + 'mime.grammar', + 'properties.charset' + )) + + -> register('mime.headerset') + -> asNewInstanceOf('Swift_Mime_SimpleHeaderSet') + -> withDependencies(array('mime.headerfactory', 'properties.charset')) + + -> register('mime.qpheaderencoder') + -> asNewInstanceOf('Swift_Mime_HeaderEncoder_QpHeaderEncoder') + -> withDependencies(array('mime.charstream')) + + -> register('mime.charstream') + -> asNewInstanceOf('Swift_CharacterStream_NgCharacterStream') + -> withDependencies(array('mime.characterreaderfactory', 'properties.charset')) + + -> register('mime.bytecanonicalizer') + -> asSharedInstanceOf('Swift_StreamFilters_ByteArrayReplacementFilter') + -> addConstructorValue(array(array(0x0D, 0x0A), array(0x0D), array(0x0A))) + -> addConstructorValue(array(array(0x0A), array(0x0A), array(0x0D, 0x0A))) + + -> register('mime.characterreaderfactory') + -> asSharedInstanceOf('Swift_CharacterReaderFactory_SimpleCharacterReaderFactory') + + -> register('mime.qpcontentencoder') + -> asNewInstanceOf('Swift_Mime_ContentEncoder_QpContentEncoder') + -> withDependencies(array('mime.charstream', 'mime.bytecanonicalizer')) + + -> register('mime.7bitcontentencoder') + -> asNewInstanceOf('Swift_Mime_ContentEncoder_PlainContentEncoder') + -> addConstructorValue('7bit') + -> addConstructorValue(true) + + -> register('mime.8bitcontentencoder') + -> asNewInstanceOf('Swift_Mime_ContentEncoder_PlainContentEncoder') + -> addConstructorValue('8bit') + -> addConstructorValue(true) + + -> register('mime.base64contentencoder') + -> asSharedInstanceOf('Swift_Mime_ContentEncoder_Base64ContentEncoder') + + -> register('mime.rfc2231encoder') + -> asNewInstanceOf('Swift_Encoder_Rfc2231Encoder') + -> withDependencies(array('mime.charstream')) + + ; + +unset($swift_mime_types); diff --git a/vendor/swiftmailer/swiftmailer/lib/dependency_maps/transport_deps.php b/vendor/swiftmailer/swiftmailer/lib/dependency_maps/transport_deps.php new file mode 100644 index 0000000..52c3341 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/dependency_maps/transport_deps.php @@ -0,0 +1,70 @@ + register('transport.smtp') + -> asNewInstanceOf('Swift_Transport_EsmtpTransport') + -> withDependencies(array( + 'transport.buffer', + array('transport.authhandler'), + 'transport.eventdispatcher' + )) + + -> register('transport.sendmail') + -> asNewInstanceOf('Swift_Transport_SendmailTransport') + -> withDependencies(array( + 'transport.buffer', + 'transport.eventdispatcher' + )) + + -> register('transport.mail') + -> asNewInstanceOf('Swift_Transport_MailTransport') + -> withDependencies(array('transport.mailinvoker', 'transport.eventdispatcher')) + + -> register('transport.loadbalanced') + -> asNewInstanceOf('Swift_Transport_LoadBalancedTransport') + + -> register('transport.failover') + -> asNewInstanceOf('Swift_Transport_FailoverTransport') + + -> register('transport.spool') + -> asNewInstanceOf('Swift_Transport_SpoolTransport') + -> withDependencies(array('transport.eventdispatcher')) + + -> register('transport.null') + -> asNewInstanceOf('Swift_Transport_NullTransport') + -> withDependencies(array('transport.eventdispatcher')) + + -> register('transport.mailinvoker') + -> asSharedInstanceOf('Swift_Transport_SimpleMailInvoker') + + -> register('transport.buffer') + -> asNewInstanceOf('Swift_Transport_StreamBuffer') + -> withDependencies(array('transport.replacementfactory')) + + -> register('transport.authhandler') + -> asNewInstanceOf('Swift_Transport_Esmtp_AuthHandler') + -> withDependencies(array( + array( + 'transport.crammd5auth', + 'transport.loginauth', + 'transport.plainauth' + ) + )) + + -> register('transport.crammd5auth') + -> asNewInstanceOf('Swift_Transport_Esmtp_Auth_CramMd5Authenticator') + + -> register('transport.loginauth') + -> asNewInstanceOf('Swift_Transport_Esmtp_Auth_LoginAuthenticator') + + -> register('transport.plainauth') + -> asNewInstanceOf('Swift_Transport_Esmtp_Auth_PlainAuthenticator') + + -> register('transport.eventdispatcher') + -> asNewInstanceOf('Swift_Events_SimpleEventDispatcher') + + -> register('transport.replacementfactory') + -> asSharedInstanceOf('Swift_StreamFilters_StringReplacementFilterFactory') + + ; diff --git a/vendor/swiftmailer/swiftmailer/lib/mime_types.php b/vendor/swiftmailer/swiftmailer/lib/mime_types.php new file mode 100644 index 0000000..65c9aa0 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/mime_types.php @@ -0,0 +1,76 @@ + 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'avi' => 'video/avi', + 'bmp' => 'image/bmp', + 'bz2' => 'application/x-bz2', + 'csv' => 'text/csv', + 'dmg' => 'application/x-apple-diskimage', + 'doc' => 'application/msword', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'eml' => 'message/rfc822', + 'aps' => 'application/postscript', + 'exe' => 'application/x-ms-dos-executable', + 'flv' => 'video/x-flv', + 'gif' => 'image/gif', + 'gz' => 'application/x-gzip', + 'hqx' => 'application/stuffit', + 'htm' => 'text/html', + 'html' => 'text/html', + 'jar' => 'application/x-java-archive', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'm3u' => 'audio/x-mpegurl', + 'm4a' => 'audio/mp4', + 'mdb' => 'application/x-msaccess', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mov' => 'video/quicktime', + 'mp3' => 'audio/mpeg', + 'mp4' => 'video/mp4', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'odg' => 'vnd.oasis.opendocument.graphics', + 'odp' => 'vnd.oasis.opendocument.presentation', + 'odt' => 'vnd.oasis.opendocument.text', + 'ods' => 'vnd.oasis.opendocument.spreadsheet', + 'ogg' => 'audio/ogg', + 'pdf' => 'application/pdf', + 'png' => 'image/png', + 'ppt' => 'application/vnd.ms-powerpoint', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'ps' => 'application/postscript', + 'rar' => 'application/x-rar-compressed', + 'rtf' => 'application/rtf', + 'tar' => 'application/x-tar', + 'sit' => 'application/x-stuffit', + 'svg' => 'image/svg+xml', + 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', + 'ttf' => 'application/x-font-truetype', + 'txt' => 'text/plain', + 'vcf' => 'text/x-vcard', + 'wav' => 'audio/wav', + 'wma' => 'audio/x-ms-wma', + 'wmv' => 'audio/x-ms-wmv', + 'xls' => 'application/excel', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xml' => 'application/xml', + 'zip' => 'application/zip' +); diff --git a/vendor/swiftmailer/swiftmailer/lib/preferences.php b/vendor/swiftmailer/swiftmailer/lib/preferences.php new file mode 100644 index 0000000..c9b5a5c --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/preferences.php @@ -0,0 +1,22 @@ +setCharset('utf-8'); + +// Without these lines the default caching mechanism is "array" but this uses a lot of memory. +// If possible, use a disk cache to enable attaching large attachments etc. +// You can override the default temporary directory by setting the TMPDIR environment variable. +if (function_exists('sys_get_temp_dir') && is_writable(sys_get_temp_dir())) +{ + Swift_Preferences::getInstance() + -> setTempDir(sys_get_temp_dir()) + -> setCacheType('disk'); +} + +Swift_Preferences::getInstance()->setQPDotEscape(false); diff --git a/vendor/swiftmailer/swiftmailer/lib/swift_init.php b/vendor/swiftmailer/swiftmailer/lib/swift_init.php new file mode 100644 index 0000000..7780767 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/lib/swift_init.php @@ -0,0 +1,27 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle; + +use Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler\TemplateResourcesPass; +use Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler\AssetFactoryPass; +use Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler\AssetManagerPass; +use Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler\CheckYuiFilterPass; +use Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler\FilterManagerPass; +use Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler\CheckCssEmbedFilterPass; +use Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler\CheckClosureFilterPass; +use Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler\TemplatingPass; +use Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler\SprocketsFilterPass; +use Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler\RouterResourcePass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\HttpKernel\Bundle\Bundle; + +/** + * Assetic integration. + * + * @author Kris Wallsmith + */ +class AsseticBundle extends Bundle +{ + public function build(ContainerBuilder $container) + { + parent::build($container); + + $container->addCompilerPass(new TemplateResourcesPass()); + $container->addCompilerPass(new CheckClosureFilterPass()); + $container->addCompilerPass(new CheckCssEmbedFilterPass()); + $container->addCompilerPass(new CheckYuiFilterPass()); + $container->addCompilerPass(new SprocketsFilterPass()); + $container->addCompilerPass(new TemplatingPass()); + $container->addCompilerPass(new AssetFactoryPass()); + $container->addCompilerPass(new AssetManagerPass()); + $container->addCompilerPass(new FilterManagerPass()); + $container->addCompilerPass(new RouterResourcePass()); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/CacheWarmer/AssetManagerCacheWarmer.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/CacheWarmer/AssetManagerCacheWarmer.php new file mode 100644 index 0000000..871626c --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/CacheWarmer/AssetManagerCacheWarmer.php @@ -0,0 +1,41 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\CacheWarmer; + +use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * The AssetManagerCacheWarmer warms up the formula loader. + * + * @author Kris Wallsmith + */ +class AssetManagerCacheWarmer implements CacheWarmerInterface +{ + private $container; + + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + public function warmUp($cacheDir) + { + $am = $this->container->get('assetic.asset_manager'); + $am->load(); + } + + public function isOptional() + { + return true; + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Command/DumpCommand.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Command/DumpCommand.php new file mode 100644 index 0000000..5014f21 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Command/DumpCommand.php @@ -0,0 +1,232 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Command; + +use Assetic\Util\PathUtils; + +use Assetic\AssetWriter; +use Assetic\Asset\AssetInterface; +use Assetic\Factory\LazyAssetManager; +use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Dumps assets to the filesystem. + * + * @author Kris Wallsmith + */ +class DumpCommand extends ContainerAwareCommand +{ + private $basePath; + private $verbose; + private $am; + + protected function configure() + { + $this + ->setName('assetic:dump') + ->setDescription('Dumps all assets to the filesystem') + ->addArgument('write_to', InputArgument::OPTIONAL, 'Override the configured asset root') + ->addOption('watch', null, InputOption::VALUE_NONE, 'Check for changes every second, debug mode only') + ->addOption('force', null, InputOption::VALUE_NONE, 'Force an initial generation of all assets (used with --watch)') + ->addOption('period', null, InputOption::VALUE_REQUIRED, 'Set the polling period in seconds (used with --watch)', 1) + ; + } + + protected function initialize(InputInterface $input, OutputInterface $output) + { + parent::initialize($input, $output); + + $this->basePath = $input->getArgument('write_to') ?: $this->getContainer()->getParameter('assetic.write_to'); + $this->verbose = $input->getOption('verbose'); + $this->am = $this->getContainer()->get('assetic.asset_manager'); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $output->writeln(sprintf('Dumping all %s assets.', $input->getOption('env'))); + $output->writeln(sprintf('Debug mode is %s.', $input->getOption('no-debug') ? 'off' : 'on')); + $output->writeln(''); + + if (!$input->getOption('watch')) { + foreach ($this->am->getNames() as $name) { + $this->dumpAsset($name, $output); + } + + return; + } + + if (!$this->am->isDebug()) { + throw new \RuntimeException('The --watch option is only available in debug mode.'); + } + + $this->watch($input, $output); + } + + /** + * Watches a asset manager for changes. + * + * This method includes an infinite loop the continuously polls the asset + * manager for changes. + * + * @param InputInterface $input The command input + * @param OutputInterface $output The command output + */ + private function watch(InputInterface $input, OutputInterface $output) + { + $refl = new \ReflectionClass('Assetic\\AssetManager'); + $prop = $refl->getProperty('assets'); + $prop->setAccessible(true); + + $cache = sys_get_temp_dir().'/assetic_watch_'.substr(sha1($this->basePath), 0, 7); + if ($input->getOption('force') || !file_exists($cache)) { + $previously = array(); + } else { + $previously = unserialize(file_get_contents($cache)); + } + + $error = ''; + while (true) { + try { + foreach ($this->am->getNames() as $name) { + if ($this->checkAsset($name, $previously)) { + $this->dumpAsset($name, $output); + } + } + + // reset the asset manager + $prop->setValue($this->am, array()); + $this->am->load(); + + file_put_contents($cache, serialize($previously)); + $error = ''; + + sleep($input->getOption('period')); + } catch (\Exception $e) { + if ($error != $msg = $e->getMessage()) { + $output->writeln('[error] '.$msg); + $error = $msg; + } + } + } + } + + /** + * Checks if an asset should be dumped. + * + * @param string $name The asset name + * @param array &$previously An array of previous visits + * + * @return Boolean Whether the asset should be dumped + */ + private function checkAsset($name, array &$previously) + { + $formula = $this->am->hasFormula($name) ? serialize($this->am->getFormula($name)) : null; + $asset = $this->am->get($name); + $mtime = $asset->getLastModified(); + + if (isset($previously[$name])) { + $changed = $previously[$name]['mtime'] != $mtime || $previously[$name]['formula'] != $formula; + } else { + $changed = true; + } + + $previously[$name] = array('mtime' => $mtime, 'formula' => $formula); + + return $changed; + } + + /** + * Writes an asset. + * + * If the application or asset is in debug mode, each leaf asset will be + * dumped as well. + * + * @param string $name An asset name + * @param OutputInterface $output The command output + */ + private function dumpAsset($name, OutputInterface $output) + { + $asset = $this->am->get($name); + $formula = $this->am->getFormula($name); + + // start by dumping the main asset + $this->doDump($asset, $output); + + // dump each leaf if debug + if (isset($formula[2]['debug']) ? $formula[2]['debug'] : $this->am->isDebug()) { + foreach ($asset as $leaf) { + $this->doDump($leaf, $output); + } + } + } + + /** + * Performs the asset dump. + * + * @param AssetInterface $asset An asset + * @param OutputInterface $output The command output + * + * @throws RuntimeException If there is a problem writing the asset + */ + private function doDump(AssetInterface $asset, OutputInterface $output) + { + $writer = new AssetWriter(sys_get_temp_dir(), $this->getContainer()->getParameter('assetic.variables')); + $ref = new \ReflectionMethod($writer, 'getCombinations'); + $ref->setAccessible(true); + $combinations = $ref->invoke($writer, $asset->getVars()); + + foreach ($combinations as $combination) { + $asset->setValues($combination); + + $target = rtrim($this->basePath, '/').'/'.str_replace('_controller/', '', + PathUtils::resolvePath($asset->getTargetPath(), $asset->getVars(), + $asset->getValues())); + if (!is_dir($dir = dirname($target))) { + $output->writeln(sprintf( + '%s [dir+] %s', + date('H:i:s'), + $dir + )); + if (false === @mkdir($dir, 0777, true)) { + throw new \RuntimeException('Unable to create directory '.$dir); + } + } + + $output->writeln(sprintf( + '%s [file+] %s', + date('H:i:s'), + $target + )); + if ($this->verbose) { + if ($asset instanceof \Traversable) { + foreach ($asset as $leaf) { + $root = $leaf->getSourceRoot(); + $path = $leaf->getSourcePath(); + $output->writeln(sprintf(' %s/%s', $root ?: '[unknown root]', $path ?: '[unknown path]')); + } + } else { + $root = $asset->getSourceRoot(); + $path = $asset->getSourcePath(); + $output->writeln(sprintf(' %s/%s', $root ?: '[unknown root]', $path ?: '[unknown path]')); + } + } + + if (false === @file_put_contents($target, $asset->dump())) { + throw new \RuntimeException('Unable to write file '.$target); + } + } + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Config/AsseticResource.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Config/AsseticResource.php new file mode 100644 index 0000000..3e1db07 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Config/AsseticResource.php @@ -0,0 +1,75 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Config; + +use Assetic\Factory\Resource\ResourceInterface as AsseticResourceInterface; +use Symfony\Component\Config\Resource\ResourceInterface as SymfonyResourceInterface; + +/** + * Turns an Assetic resource into a Symfony one. + * + * @author Kris Wallsmith + */ +class AsseticResource implements SymfonyResourceInterface +{ + private $resource; + + public function __construct(AsseticResourceInterface $resource) + { + $this->resource = $resource; + } + + public function __toString() + { + return (string) $this->resource; + } + + public function isFresh($timestamp) + { + return $this->resource->isFresh($timestamp); + } + + /** + * Returns the Assetic resource. + * + * @return AsseticResourceInterface The wrapped Assetic resource + */ + public function getResource() + { + return $this->resource; + } + + public function exists() + { + return true; + } + + public function getId() + { + return md5('assetic'.$this->resource); + } + + public function getModificationTime() + { + return -1; + } + + public function serialize() + { + return serialize($this->resource); + } + + public function unserialize($serialized) + { + $this->resource = unserialize($serialized); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Controller/AsseticController.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Controller/AsseticController.php new file mode 100644 index 0000000..bc3a1ad --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Controller/AsseticController.php @@ -0,0 +1,121 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Controller; + +use Assetic\ValueSupplierInterface; + +use Assetic\Asset\AssetCache; +use Assetic\Asset\AssetInterface; +use Assetic\Factory\LazyAssetManager; +use Assetic\Cache\CacheInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Symfony\Component\HttpKernel\Profiler\Profiler; + +/** + * Serves assets. + * + * @author Kris Wallsmith + */ +class AsseticController +{ + protected $request; + protected $am; + protected $cache; + protected $enableProfiler; + protected $profiler; + protected $valueSupplier; + + public function __construct(Request $request, LazyAssetManager $am, CacheInterface $cache, $enableProfiler = false, Profiler $profiler = null) + { + $this->request = $request; + $this->am = $am; + $this->cache = $cache; + $this->enableProfiler = (boolean) $enableProfiler; + $this->profiler = $profiler; + } + + public function setValueSupplier(ValueSupplierInterface $supplier) + { + $this->valueSupplier = $supplier; + } + + public function render($name, $pos = null) + { + if (!$this->enableProfiler && null !== $this->profiler) { + $this->profiler->disable(); + } + + if (!$this->am->has($name)) { + throw new NotFoundHttpException(sprintf('The "%s" asset could not be found.', $name)); + } + + $asset = $this->am->get($name); + if (null !== $pos && !$asset = $this->findAssetLeaf($asset, $pos)) { + throw new NotFoundHttpException(sprintf('The "%s" asset does not include a leaf at position %d.', $name, $pos)); + } + + $response = $this->createResponse(); + $response->setExpires(new \DateTime()); + + // last-modified + if (null !== $lastModified = $asset->getLastModified()) { + $date = new \DateTime(); + $date->setTimestamp($lastModified); + $response->setLastModified($date); + } + + // etag + if ($this->am->hasFormula($name)) { + $formula = $this->am->getFormula($name); + $formula['last_modified'] = $lastModified; + $response->setETag(md5(serialize($formula))); + } + + if ($response->isNotModified($this->request)) { + return $response; + } + + $response->setContent($this->cachifyAsset($asset)->dump()); + + return $response; + } + + protected function createResponse() + { + return new Response(); + } + + protected function cachifyAsset(AssetInterface $asset) + { + if ($vars = $asset->getVars()) { + if (null === $this->valueSupplier) { + throw new \RuntimeException(sprintf('You must configure a value supplier if you have assets with variables.')); + } + + $asset->setValues(array_intersect_key($this->valueSupplier->getValues(), array_flip($vars))); + } + + return new AssetCache($asset, $this->cache); + } + + private function findAssetLeaf(\Traversable $asset, $pos) + { + $i = 0; + foreach ($asset as $leaf) { + if ($pos == $i++) { + return $leaf; + } + } + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DefaultValueSupplier.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DefaultValueSupplier.php new file mode 100644 index 0000000..c365bc0 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DefaultValueSupplier.php @@ -0,0 +1,35 @@ + + */ +class DefaultValueSupplier implements ValueSupplierInterface +{ + protected $container; + + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + public function getValues() + { + if (!$this->container->isScopeActive('request')) { + return array(); + } + + $request = $this->container->get('request'); + + return array( + 'locale' => $request->getLocale(), + 'env' => $this->container->getParameter('kernel.environment'), + ); + } +} \ No newline at end of file diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/AsseticExtension.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/AsseticExtension.php new file mode 100644 index 0000000..ce2503a --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/AsseticExtension.php @@ -0,0 +1,144 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\DependencyInjection; + +use Symfony\Component\Config\FileLocator; +use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\HttpKernel\DependencyInjection\Extension; + +/** + * Semantic asset configuration. + * + * @author Kris Wallsmith + */ +class AsseticExtension extends Extension +{ + /** + * Loads the configuration. + * + * @param array $configs An array of configuration settings + * @param ContainerBuilder $container A ContainerBuilder instance + */ + public function load(array $configs, ContainerBuilder $container) + { + $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); + $loader->load('assetic.xml'); + $loader->load('templating_twig.xml'); + $loader->load('templating_php.xml'); + + $processor = new Processor(); + $configuration = $this->getConfiguration($configs, $container); + $config = $processor->processConfiguration($configuration, $configs); + + $container->setParameter('assetic.debug', $config['debug']); + $container->setParameter('assetic.use_controller', $config['use_controller']['enabled']); + $container->setParameter('assetic.enable_profiler', $config['use_controller']['profiler']); + $container->setParameter('assetic.read_from', $config['read_from']); + $container->setParameter('assetic.write_to', $config['write_to']); + $container->setParameter('assetic.variables', $config['variables']); + + $container->setParameter('assetic.java.bin', $config['java']); + $container->setParameter('assetic.node.bin', $config['node']); + $container->setParameter('assetic.ruby.bin', $config['ruby']); + $container->setParameter('assetic.sass.bin', $config['sass']); + + // register formulae + $formulae = array(); + foreach ($config['assets'] as $name => $formula) { + $formulae[$name] = array($formula['inputs'], $formula['filters'], $formula['options']); + } + + if ($formulae) { + $container->getDefinition('assetic.config_resource')->replaceArgument(0, $formulae); + } else { + $container->removeDefinition('assetic.config_loader'); + $container->removeDefinition('assetic.config_resource'); + } + + // register filters + foreach ($config['filters'] as $name => $filter) { + if (isset($filter['resource'])) { + $loader->load($container->getParameterBag()->resolveValue($filter['resource'])); + unset($filter['resource']); + } else { + $loader->load('filters/'.$name.'.xml'); + } + + if (isset($filter['file'])) { + $container->getDefinition('assetic.filter.'.$name)->setFile($filter['file']); + unset($filter['file']); + } + + if (isset($filter['apply_to'])) { + if (!is_array($filter['apply_to'])) { + $filter['apply_to'] = array($filter['apply_to']); + } + + foreach ($filter['apply_to'] as $i => $pattern) { + $worker = new DefinitionDecorator('assetic.worker.ensure_filter'); + $worker->replaceArgument(0, '/'.$pattern.'/'); + $worker->replaceArgument(1, new Reference('assetic.filter.'.$name)); + $worker->addTag('assetic.factory_worker'); + + $container->setDefinition('assetic.filter.'.$name.'.worker'.$i, $worker); + } + + unset($filter['apply_to']); + } + + foreach ($filter as $key => $value) { + $container->setParameter('assetic.filter.'.$name.'.'.$key, $value); + } + } + + // twig functions + $container->setParameter('assetic.twig_extension.functions', $config['twig']['functions']); + + // choose dynamic or static + if ($useController = $container->getParameterBag()->resolveValue($container->getParameterBag()->get('assetic.use_controller'))) { + $loader->load('controller.xml'); + $container->getDefinition('assetic.helper.dynamic')->addTag('templating.helper', array('alias' => 'assetic')); + $container->removeDefinition('assetic.helper.static'); + } else { + $container->getDefinition('assetic.helper.static')->addTag('templating.helper', array('alias' => 'assetic')); + $container->removeDefinition('assetic.helper.dynamic'); + } + + $container->setParameter('assetic.bundles', $config['bundles']); + } + + /** + * Returns the base path for the XSD files. + * + * @return string The XSD base path + */ + public function getXsdValidationBasePath() + { + return __DIR__ . '/../Resources/config/schema'; + } + + public function getNamespace() + { + return 'http://symfony.com/schema/dic/assetic'; + } + + public function getConfiguration(array $config, ContainerBuilder $container) + { + $bundles = $container->getParameter('kernel.bundles'); + + return new Configuration(array_keys($bundles)); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/AssetFactoryPass.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/AssetFactoryPass.php new file mode 100644 index 0000000..46647c4 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/AssetFactoryPass.php @@ -0,0 +1,36 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Adds services tagged as workers to the asset factory. + * + * @author Kris Wallsmith + */ +class AssetFactoryPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('assetic.asset_factory')) { + return; + } + + $factory = $container->getDefinition('assetic.asset_factory'); + foreach ($container->findTaggedServiceIds('assetic.factory_worker') as $id => $attr) { + $factory->addMethodCall('addWorker', array(new Reference($id))); + } + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/AssetManagerPass.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/AssetManagerPass.php new file mode 100644 index 0000000..fe45f9c --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/AssetManagerPass.php @@ -0,0 +1,62 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Adds services tagged as assets to the asset manager. + * + * @author Kris Wallsmith + */ +class AssetManagerPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('assetic.asset_manager')) { + return; + } + + $am = $container->getDefinition('assetic.asset_manager'); + + // add assets + foreach ($container->findTaggedServiceIds('assetic.asset') as $id => $attributes) { + foreach ($attributes as $attr) { + if (isset($attr['alias'])) { + $am->addMethodCall('set', array($attr['alias'], new Reference($id))); + } + } + } + + // add loaders + $loaders = array(); + foreach ($container->findTaggedServiceIds('assetic.formula_loader') as $id => $attributes) { + foreach ($attributes as $attr) { + if (isset($attr['alias'])) { + $loaders[$attr['alias']] = new Reference($id); + } + } + } + $am->replaceArgument(1, $loaders); + + // add resources + foreach ($container->findTaggedServiceIds('assetic.formula_resource') as $id => $attributes) { + foreach ($attributes as $attr) { + if (isset($attr['loader'])) { + $am->addMethodCall('addResource', array(new Reference($id), $attr['loader'])); + } + } + } + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/CheckClosureFilterPass.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/CheckClosureFilterPass.php new file mode 100644 index 0000000..3e1eec0 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/CheckClosureFilterPass.php @@ -0,0 +1,36 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Tags either the closure JAR or API filter for the filter manager. + * + * @author Kris Wallsmith + */ +class CheckClosureFilterPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if ($container->hasDefinition('assetic.filter.closure.jar') + && $container->hasParameter('assetic.filter.closure.jar') + && $container->getParameterBag()->resolveValue($container->getParameter('assetic.filter.closure.jar'))) { + $container->removeDefinition('assetic.filter.closure.api'); + $container->setAlias('assetic.filter.closure', 'assetic.filter.closure.jar'); + } elseif ($container->hasDefinition('assetic.filter.closure.api')) { + $container->removeDefinition('assetic.filter.closure.jar'); + $container->setAlias('assetic.filter.closure', 'assetic.filter.closure.api'); + } + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/CheckCssEmbedFilterPass.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/CheckCssEmbedFilterPass.php new file mode 100644 index 0000000..e9c660c --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/CheckCssEmbedFilterPass.php @@ -0,0 +1,31 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Checks that the location of the CssEmbed JAR has been configured. + * + * @author Kris Wallsmith + */ +class CheckCssEmbedFilterPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if ($container->hasDefinition('assetic.filter.cssembed') && + !$container->getParameterBag()->resolveValue($container->getParameter('assetic.filter.cssembed.jar'))) { + throw new \RuntimeException('The "assetic.filters.cssembed" configuration requires a "jar" value.'); + } + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/CheckYuiFilterPass.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/CheckYuiFilterPass.php new file mode 100644 index 0000000..2c1f55c --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/CheckYuiFilterPass.php @@ -0,0 +1,36 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Checks that the location of the YUI JAR has been configured. + * + * @author Kris Wallsmith + */ +class CheckYuiFilterPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if ($container->hasDefinition('assetic.filter.yui_css') && + !$container->getParameterBag()->resolveValue($container->getParameter('assetic.filter.yui_css.jar'))) { + throw new \RuntimeException('The "assetic.filters.yui_css" configuration requires a "jar" value.'); + } + + if ($container->hasDefinition('assetic.filter.yui_js') && + !$container->getParameterBag()->resolveValue($container->getParameter('assetic.filter.yui_js.jar'))) { + throw new \RuntimeException('The "assetic.filters.yui_js" configuration requires a "jar" value.'); + } + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/FilterManagerPass.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/FilterManagerPass.php new file mode 100644 index 0000000..af1ad24 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/FilterManagerPass.php @@ -0,0 +1,44 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Adds services tagged as filters to the filter manager. + * + * @author Kris Wallsmith + */ +class FilterManagerPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('assetic.filter_manager')) { + return; + } + + $mapping = array(); + foreach ($container->findTaggedServiceIds('assetic.filter') as $id => $attributes) { + foreach ($attributes as $attr) { + if (isset($attr['alias'])) { + $mapping[$attr['alias']] = $id; + } + } + } + + $container + ->getDefinition('assetic.filter_manager') + ->replaceArgument(1, $mapping); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/RouterResourcePass.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/RouterResourcePass.php new file mode 100644 index 0000000..770485d --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/RouterResourcePass.php @@ -0,0 +1,44 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\Yaml\Yaml; + +/** + * This pass adds Assetic routes when use_controller is true. + * + * @author Kris Wallsmith + */ +class RouterResourcePass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (!$container->getParameter('assetic.use_controller') || !$container->getParameter('router.resource')) { + return; + } + + $file = $container->getParameter('kernel.cache_dir').'/assetic/routing.yml'; + + if (!is_dir($dir = dirname($file))) { + mkdir($dir, 0777, true); + } + + file_put_contents($file, Yaml::dump(array( + '_assetic' => array('resource' => '.', 'type' => 'assetic'), + '_app' => array('resource' => $container->getParameter('router.resource')), + ))); + + $container->setParameter('router.resource', $file); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/SprocketsFilterPass.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/SprocketsFilterPass.php new file mode 100644 index 0000000..50ffce4 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/SprocketsFilterPass.php @@ -0,0 +1,35 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Finishes configuration of the Sprockets filter. + * + * @author Kris Wallsmith + */ +class SprocketsFilterPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('assetic.filter.sprockets')) { + return; + } + + $filter = $container->getDefinition('assetic.filter.sprockets'); + foreach ($container->getParameter('assetic.filter.sprockets.include_dirs') as $dir) { + $filter->addMethodCall('addIncludeDir', array($dir)); + } + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/TemplateResourcesPass.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/TemplateResourcesPass.php new file mode 100644 index 0000000..c734b53 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/TemplateResourcesPass.php @@ -0,0 +1,67 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Bundle\AsseticBundle\DependencyInjection\DirectoryResourceDefinition; + +/** + * This pass adds directory resources to scan for assetic assets. + * + * @author Kris Wallsmith + * @author Lukas Kahwe Smith + */ +class TemplateResourcesPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('assetic.asset_manager')) { + return; + } + + $engines = $container->getParameter('templating.engines'); + + // bundle and kernel resources + $bundles = $container->getParameter('kernel.bundles'); + $asseticBundles = $container->getParameterBag()->resolveValue($container->getParameter('assetic.bundles')); + foreach ($asseticBundles as $bundleName) { + $rc = new \ReflectionClass($bundles[$bundleName]); + foreach ($engines as $engine) { + $this->setBundleDirectoryResources($container, $engine, dirname($rc->getFileName()), $bundleName); + } + } + + foreach ($engines as $engine) { + $this->setAppDirectoryResources($container, $engine); + } + } + + protected function setBundleDirectoryResources(ContainerBuilder $container, $engine, $bundleDirName, $bundleName) + { + $container->setDefinition( + 'assetic.'.$engine.'_directory_resource.'.$bundleName, + new DirectoryResourceDefinition($bundleName, $engine, array( + $container->getParameter('kernel.root_dir').'/Resources/'.$bundleName.'/views', + $bundleDirName.'/Resources/views', + )) + ); + } + + protected function setAppDirectoryResources(ContainerBuilder $container, $engine) + { + $container->setDefinition( + 'assetic.'.$engine.'_directory_resource.kernel', + new DirectoryResourceDefinition('', $engine, array($container->getParameter('kernel.root_dir').'/Resources/views')) + ); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/TemplatingPass.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/TemplatingPass.php new file mode 100644 index 0000000..8a0fdfb --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/TemplatingPass.php @@ -0,0 +1,44 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * This pass removes services associated with unused templating engines. + * + * @author Kris Wallsmith + */ +class TemplatingPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('assetic.asset_manager')) { + return; + } + + $engines = $container->getParameterBag()->resolveValue($container->getParameter('templating.engines')); + + if (!in_array('twig', $engines)) { + foreach ($container->findTaggedServiceIds('assetic.templating.twig') as $id => $attr) { + $container->removeDefinition($id); + } + } + + if (!in_array('php', $engines)) { + foreach ($container->findTaggedServiceIds('assetic.templating.php') as $id => $attr) { + $container->removeDefinition($id); + } + } + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Configuration.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Configuration.php new file mode 100644 index 0000000..accfb4f --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/Configuration.php @@ -0,0 +1,199 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\AsseticBundle\DependencyInjection; + +use Symfony\Component\Process\ExecutableFinder; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; + +/** + * This class contains the configuration information for the bundle + * + * This information is solely responsible for how the different configuration + * sections are normalized, and merged. + * + * @author Christophe Coevoet + * @author Kris Wallsmith + */ +class Configuration implements ConfigurationInterface +{ + private $bundles; + + /** + * Constructor + * + * @param array $bundles An array of bundle names + */ + public function __construct(array $bundles) + { + $this->bundles = $bundles; + } + + /** + * Generates the configuration tree builder. + * + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder + */ + public function getConfigTreeBuilder() + { + $builder = new TreeBuilder(); + $finder = new ExecutableFinder(); + + $builder->root('assetic') + ->children() + ->booleanNode('debug')->defaultValue('%kernel.debug%')->end() + ->arrayNode('use_controller') + ->addDefaultsIfNotSet() + ->treatTrueLike(array('enabled' => true)) + ->treatFalseLike(array('enabled' => false)) + ->children() + ->booleanNode('enabled')->defaultValue('%kernel.debug%')->end() + ->booleanNode('profiler')->defaultFalse()->end() + ->end() + ->end() + ->scalarNode('read_from')->defaultValue('%kernel.root_dir%/../web')->end() + ->scalarNode('write_to')->defaultValue('%assetic.read_from%')->end() + ->scalarNode('java')->defaultValue(function() use($finder) { return $finder->find('java', '/usr/bin/java'); })->end() + ->scalarNode('node')->defaultValue(function() use($finder) { return $finder->find('node', '/usr/bin/node'); })->end() + ->scalarNode('ruby')->defaultValue(function() use($finder) { return $finder->find('ruby', '/usr/bin/ruby'); })->end() + ->scalarNode('sass')->defaultValue(function() use($finder) { return $finder->find('sass', '/usr/bin/sass'); })->end() + ->end() + + // variables + ->fixXmlConfig('variable') + ->children() + ->arrayNode('variables') + ->useAttributeAsKey('name') + ->prototype('array') + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + + // bundles + ->fixXmlConfig('bundle') + ->children() + ->arrayNode('bundles') + ->defaultValue($this->bundles) + ->prototype('scalar') + ->validate() + ->ifNotInArray($this->bundles) + ->thenInvalid('%s is not a valid bundle.') + ->end() + ->end() + ->end() + ->end() + + // assets + ->fixXmlConfig('asset') + ->children() + ->arrayNode('assets') + ->requiresAtLeastOneElement() + ->useAttributeAsKey('name') + ->prototype('array') + ->beforeNormalization() + // a scalar is a simple formula of one input file + ->ifTrue(function($v) { return !is_array($v); }) + ->then(function($v) { return array('inputs' => array($v)); }) + ->end() + ->beforeNormalization() + ->always() + ->then(function($v) + { + // cast scalars as array + foreach (array('input', 'inputs', 'filter', 'filters') as $key) { + if (isset($v[$key]) && !is_array($v[$key])) { + $v[$key] = array($v[$key]); + } + } + + // organize arbitrary options + foreach ($v as $key => $value) { + if (!in_array($key, array('input', 'inputs', 'filter', 'filters', 'option', 'options'))) { + $v['options'][$key] = $value; + unset($v[$key]); + } + } + + return $v; + }) + ->end() + + // the formula + ->fixXmlConfig('input') + ->fixXmlConfig('filter') + ->children() + ->arrayNode('inputs') + ->prototype('scalar')->end() + ->end() + ->arrayNode('filters') + ->prototype('scalar')->end() + ->end() + ->arrayNode('options') + ->useAttributeAsKey('name') + ->prototype('variable')->end() + ->end() + ->end() + ->end() + ->end() + ->end() + + // filters + ->fixXmlConfig('filter') + ->children() + ->arrayNode('filters') + ->requiresAtLeastOneElement() + ->useAttributeAsKey('name') + ->prototype('variable') + ->treatNullLike(array()) + ->validate() + ->ifTrue(function($v) { return !is_array($v); }) + ->thenInvalid('The assetic.filters config %s must be either null or an array.') + ->end() + ->end() + ->validate() + ->always(function($v) use ($finder) { + if (isset($v['compass']) && !isset($v['compass']['bin'])) { + $v['compass']['bin'] = $finder->find('compass', '/usr/bin/compass'); + } + + return $v; + }) + ->end() + ->end() + ->end() + + // twig + ->children() + ->arrayNode('twig') + ->addDefaultsIfNotSet() + ->fixXmlConfig('function') + ->children() + ->arrayNode('functions') + ->defaultValue(array()) + ->useAttributeAsKey('name') + ->prototype('variable') + ->treatNullLike(array()) + ->validate() + ->ifTrue(function($v) { return !is_array($v); }) + ->thenInvalid('The assetic.twig.functions config %s must be either null or an array.') + ->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ; + + return $builder; + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/DirectoryResourceDefinition.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/DirectoryResourceDefinition.php new file mode 100644 index 0000000..f572a65 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/DependencyInjection/DirectoryResourceDefinition.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\Bundle\AsseticBundle\DependencyInjection; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Encapsulates logic for creating a directory resource. + * + * @author Kris Wallsmith + */ +class DirectoryResourceDefinition extends Definition +{ + /** + * Constructor. + * + * @param string $bundle A bundle name or empty string + * @param string $engine The templating engine + * @param array $dirs An array of directories to merge + */ + public function __construct($bundle, $engine, array $dirs) + { + if (!count($dirs)) { + throw new \InvalidArgumentException('You must provide at least one directory.'); + } + + parent::__construct(); + + $this + ->addTag('assetic.templating.'.$engine) + ->addTag('assetic.formula_resource', array('loader' => $engine)); + ; + + if (1 == count($dirs)) { + // no need to coalesce + self::configureDefinition($this, $bundle, $engine, reset($dirs)); + return; + } + + // gather the wrapped resource definitions + $resources = array(); + foreach ($dirs as $dir) { + $resources[] = $resource = new Definition(); + self::configureDefinition($resource, $bundle, $engine, $dir); + } + + $this + ->setClass('%assetic.coalescing_directory_resource.class%') + ->addArgument($resources) + ->setPublic(false) + ; + } + + static private function configureDefinition(Definition $definition, $bundle, $engine, $dir) + { + $definition + ->setClass('%assetic.directory_resource.class%') + ->addArgument(new Reference('templating.loader')) + ->addArgument($bundle) + ->addArgument($dir) + ->addArgument('/\.[^.]+\.'.$engine.'$/') + ->setPublic(false) + ; + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/EventListener/RequestListener.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/EventListener/RequestListener.php new file mode 100644 index 0000000..ae1d874 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/EventListener/RequestListener.php @@ -0,0 +1,31 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\EventListener; + +use Symfony\Component\HttpKernel\Event\GetResponseEvent; + +/** + * Adds a few formats to each request. + * + * @author Kris Wallsmith + */ +class RequestListener +{ + public function onKernelRequest(GetResponseEvent $event) + { + $request = $event->getRequest(); + + $request->setFormat('png', 'image/png'); + $request->setFormat('jpg', 'image/jpeg'); + $request->setFormat('gif', 'image/gif'); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Exception/InvalidBundleException.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Exception/InvalidBundleException.php new file mode 100644 index 0000000..960473f --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Exception/InvalidBundleException.php @@ -0,0 +1,26 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Exception; + +class InvalidBundleException extends \LogicException +{ + public function __construct($bundle, $usage, $template, array $enabled, $code = 0, \Exception $previous = null) + { + $message = sprintf('You must add %s to the assetic.bundle config to use %s in %s.', $bundle, $usage, $template); + + if ($enabled) { + $message .= sprintf(' (currently enabled: %s)', implode(', ', $enabled)); + } + + parent::__construct($message, $code, $previous); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/AssetFactory.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/AssetFactory.php new file mode 100644 index 0000000..85f7324 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/AssetFactory.php @@ -0,0 +1,97 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Factory; + +use Assetic\Factory\AssetFactory as BaseAssetFactory; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; +use Symfony\Component\HttpKernel\KernelInterface; + +/** + * Loads asset formulae from the filesystem. + * + * @author Kris Wallsmith + */ +class AssetFactory extends BaseAssetFactory +{ + private $kernel; + private $container; + private $parameterBag; + + /** + * Constructor. + * + * @param KernelInterface $kernel The kernel is used to parse bundle notation + * @param ContainerInterface $container The container is used to load the managers lazily, thus avoiding a circular dependency + * @param ParameterBagInterface $parameterBag The container parameter bag + * @param string $baseDir The base directory for relative inputs + * @param Boolean $debug The current debug mode + */ + public function __construct(KernelInterface $kernel, ContainerInterface $container, ParameterBagInterface $parameterBag, $baseDir, $debug = false) + { + $this->kernel = $kernel; + $this->container = $container; + $this->parameterBag = $parameterBag; + + parent::__construct($baseDir, $debug); + } + + /** + * Adds support for bundle notation file and glob assets and parameter placeholders. + * + * FIXME: This is a naive implementation of globs in that it doesn't + * attempt to support bundle inheritance within the glob pattern itself. + */ + protected function parseInput($input, array $options = array()) + { + $input = $this->parameterBag->resolveValue($input); + + // expand bundle notation + if ('@' == $input[0] && false !== strpos($input, '/')) { + // use the bundle path as this asset's root + $bundle = substr($input, 1); + if (false !== $pos = strpos($bundle, '/')) { + $bundle = substr($bundle, 0, $pos); + } + $options['root'] = array($this->kernel->getBundle($bundle)->getPath()); + + // canonicalize the input + if (false !== $pos = strpos($input, '*')) { + // locateResource() does not support globs so we provide a naive implementation here + list($before, $after) = explode('*', $input, 2); + $input = $this->kernel->locateResource($before).'*'.$after; + } else { + $input = $this->kernel->locateResource($input); + } + } + + return parent::parseInput($input, $options); + } + + protected function createAssetReference($name) + { + if (!$this->getAssetManager()) { + $this->setAssetManager($this->container->get('assetic.asset_manager')); + } + + return parent::createAssetReference($name); + } + + protected function getFilter($name) + { + if (!$this->getFilterManager()) { + $this->setFilterManager($this->container->get('assetic.filter_manager')); + } + + return parent::getFilter($name); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Loader/AsseticHelperFormulaLoader.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Loader/AsseticHelperFormulaLoader.php new file mode 100644 index 0000000..3f69e18 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Loader/AsseticHelperFormulaLoader.php @@ -0,0 +1,87 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Factory\Loader; + +use Assetic\Factory\Loader\BasePhpFormulaLoader; + +/** + * Loads formulae from Symfony2 PHP templates. + * + * @author Kris Wallsmith + */ +class AsseticHelperFormulaLoader extends BasePhpFormulaLoader +{ + protected function registerPrototypes() + { + return array( + '$view[\'assetic\']->javascripts(*)' => array('output' => 'js/*.js'), + '$view[\'assetic\']->stylesheets(*)' => array('output' => 'css/*.css'), + '$view[\'assetic\']->image(*)' => array('output' => 'images/*', 'single' => true), + '$view["assetic"]->javascripts(*)' => array('output' => 'js/*.js'), + '$view["assetic"]->stylesheets(*)' => array('output' => 'css/*.css'), + '$view["assetic"]->image(*)' => array('output' => 'images/*', 'single' => true), + '$view->get(\'assetic\')->javascripts(*)' => array('output' => 'js/*.js'), + '$view->get(\'assetic\')->stylesheets(*)' => array('output' => 'css/*.css'), + '$view->get(\'assetic\')->image(*)' => array('output' => 'images/*', 'single' => true), + '$view->get("assetic")->javascripts(*)' => array('output' => 'js/*.js'), + '$view->get("assetic")->stylesheets(*)' => array('output' => 'css/*.css'), + '$view->get("assetic")->image(*)' => array('output' => 'images/*', 'single' => true), + ); + } + + protected function registerSetupCode() + { + return <<<'EOF' +class Helper +{ + public function assets() + { + global $_call; + $_call = func_get_args(); + } + + public function javascripts() + { + global $_call; + $_call = func_get_args(); + } + + public function stylesheets() + { + global $_call; + $_call = func_get_args(); + } + + public function image() + { + global $_call; + $_call = func_get_args(); + } +} + +class View extends ArrayObject +{ + public function __construct(Helper $helper) + { + parent::__construct(array('assetic' => $helper)); + } + + public function get() + { + return $this['assetic']; + } +} + +$view = new View(new Helper()); +EOF; + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Loader/ConfigurationLoader.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Loader/ConfigurationLoader.php new file mode 100644 index 0000000..28385e1 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Loader/ConfigurationLoader.php @@ -0,0 +1,29 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Factory\Loader; + +use Assetic\Factory\Loader\FormulaLoaderInterface; +use Assetic\Factory\Resource\ResourceInterface; +use Symfony\Bundle\AsseticBundle\Factory\Resource\ConfigurationResource; + +/** + * Loads configured formulae. + * + * @author Kris Wallsmith + */ +class ConfigurationLoader implements FormulaLoaderInterface +{ + public function load(ResourceInterface $resource) + { + return $resource instanceof ConfigurationResource ? $resource->getContent() : array(); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Resource/CoalescingDirectoryResource.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Resource/CoalescingDirectoryResource.php new file mode 100644 index 0000000..1ad87e9 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Resource/CoalescingDirectoryResource.php @@ -0,0 +1,30 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Factory\Resource; + +use Assetic\Factory\Resource\CoalescingDirectoryResource as BaseCoalescingDirectoryResource; +use Assetic\Factory\Resource\ResourceInterface; + +/** + * Coalesces multiple directories together into one merged resource. + * + * @author Kris Wallsmith + */ +class CoalescingDirectoryResource extends BaseCoalescingDirectoryResource +{ + protected function getRelativeName(ResourceInterface $file, ResourceInterface $directory) + { + $name = (string) $file; + + return substr($name, strpos($name, ':')); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Resource/ConfigurationResource.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Resource/ConfigurationResource.php new file mode 100644 index 0000000..e1fac48 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Resource/ConfigurationResource.php @@ -0,0 +1,44 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Factory\Resource; + +use Assetic\Factory\Resource\ResourceInterface; + +/** + * A configured resource. + * + * @author Kris Wallsmith + */ +class ConfigurationResource implements ResourceInterface +{ + private $formulae; + + public function __construct(array $formulae) + { + $this->formulae = $formulae; + } + + public function isFresh($timestamp) + { + return true; + } + + public function getContent() + { + return $this->formulae; + } + + public function __toString() + { + return 'symfony'; + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Resource/DirectoryResource.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Resource/DirectoryResource.php new file mode 100644 index 0000000..54ce81c --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Resource/DirectoryResource.php @@ -0,0 +1,51 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Factory\Resource; + +use Assetic\Factory\Resource\DirectoryResource as BaseDirectoryResource; +use Symfony\Component\Templating\Loader\LoaderInterface; + +/** + * A directory resource that creates Symfony2 templating resources. + * + * @author Kris Wallsmith + */ +class DirectoryResource extends BaseDirectoryResource +{ + protected $loader; + protected $bundle; + protected $path; + + /** + * Constructor. + * + * @param LoaderInterface $loader The templating loader + * @param string $bundle The current bundle name + * @param string $path The directory path + * @param string $pattern A regex pattern for file basenames + */ + public function __construct(LoaderInterface $loader, $bundle, $path, $pattern = null) + { + $this->loader = $loader; + $this->bundle = $bundle; + $this->path = rtrim($path, '/').'/'; + + parent::__construct($path, $pattern); + } + + public function getIterator() + { + return is_dir($this->path) + ? new DirectoryResourceIterator($this->loader, $this->bundle, $this->path, $this->getInnerIterator()) + : new \EmptyIterator(); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Resource/DirectoryResourceIterator.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Resource/DirectoryResourceIterator.php new file mode 100644 index 0000000..e31cc7e --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Resource/DirectoryResourceIterator.php @@ -0,0 +1,45 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Factory\Resource; + +use Symfony\Component\Templating\Loader\LoaderInterface; + +class DirectoryResourceIterator extends \RecursiveIteratorIterator +{ + protected $loader; + protected $bundle; + protected $path; + + /** + * Constructor. + * + * @param LoaderInterface $loader The templating loader + * @param string $bundle The current bundle name + * @param string $path The directory + * @param RecursiveIterator $iterator The inner iterator + */ + public function __construct(LoaderInterface $loader, $bundle, $path, \RecursiveIterator $iterator) + { + $this->loader = $loader; + $this->bundle = $bundle; + $this->path = $path; + + parent::__construct($iterator); + } + + public function current() + { + $file = parent::current(); + + return new FileResource($this->loader, $this->bundle, $this->path, $file->getPathname()); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Resource/FileResource.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Resource/FileResource.php new file mode 100644 index 0000000..72585d5 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Resource/FileResource.php @@ -0,0 +1,88 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Factory\Resource; + +use Assetic\Factory\Resource\ResourceInterface; +use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference; +use Symfony\Component\Templating\Loader\LoaderInterface; + +/** + * A file resource. + * + * @author Kris Wallsmith + */ +class FileResource implements ResourceInterface +{ + protected $loader; + protected $bundle; + protected $baseDir; + protected $path; + protected $template; + + /** + * Constructor. + * + * @param LoaderInterface $loader The templating loader + * @param string $bundle The current bundle name + * @param string $baseDir The directory + * @param string $path The file path + */ + public function __construct(LoaderInterface $loader, $bundle, $baseDir, $path) + { + $this->loader = $loader; + $this->bundle = $bundle; + $this->baseDir = $baseDir; + $this->path = $path; + } + + public function isFresh($timestamp) + { + return $this->loader->isFresh($this->getTemplate(), $timestamp); + } + + public function getContent() + { + $templateReference = $this->getTemplate(); + $fileResource = $this->loader->load($templateReference); + + if (!$fileResource) { + throw new \InvalidArgumentException(sprintf('Unable to find template "%s".', $templateReference)); + } + + return $fileResource->getContent(); + } + + public function __toString() + { + return (string) $this->getTemplate(); + } + + protected function getTemplate() + { + if (null === $this->template) { + $this->template = self::createTemplateReference($this->bundle, substr($this->path, strlen($this->baseDir))); + } + + return $this->template; + } + + static private function createTemplateReference($bundle, $file) + { + $parts = explode('/', strtr($file, '\\', '/')); + $elements = explode('.', array_pop($parts)); + $engine = array_pop($elements); + $format = array_pop($elements); + $name = implode('.', $elements); + + return new TemplateReference($bundle, implode('/', $parts), $name, $format, $engine); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Worker/UseControllerWorker.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Worker/UseControllerWorker.php new file mode 100644 index 0000000..b894154 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Factory/Worker/UseControllerWorker.php @@ -0,0 +1,33 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Factory\Worker; + +use Assetic\Asset\AssetInterface; +use Assetic\Factory\Worker\WorkerInterface; + +/** + * Prepends a fake front controller so the asset knows where it is-ish. + * + * @author Kris Wallsmith + */ +class UseControllerWorker implements WorkerInterface +{ + public function process(AssetInterface $asset) + { + $targetUrl = $asset->getTargetPath(); + if ($targetUrl && '/' != $targetUrl[0] && 0 !== strpos($targetUrl, '_controller/')) { + $asset->setTargetPath('_controller/'.$targetUrl); + } + + return $asset; + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/FilterManager.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/FilterManager.php new file mode 100644 index 0000000..c547a86 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/FilterManager.php @@ -0,0 +1,55 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle; + +use Assetic\FilterManager as BaseFilterManager; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Lazy filter manager. + * + * @author Kris Wallsmith + */ +class FilterManager extends BaseFilterManager +{ + protected $container; + protected $mappings; + + /** + * Constructor. + * + * @param ContainerInterface $container The service container + * @param array $mappings A hash of filter names to service ids + */ + public function __construct(ContainerInterface $container, array $mappings) + { + $this->container = $container; + $this->mappings = $mappings; + } + + public function get($name) + { + return isset($this->mappings[$name]) + ? $this->container->get($this->mappings[$name]) + : parent::get($name); + } + + public function has($name) + { + return isset($this->mappings[$name]) || parent::has($name); + } + + public function getNames() + { + return array_unique(array_merge(array_keys($this->mappings), parent::getNames())); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/assetic.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/assetic.xml new file mode 100644 index 0000000..df3cc0b --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/assetic.xml @@ -0,0 +1,79 @@ + + + + + + Symfony\Bundle\AsseticBundle\Factory\AssetFactory + Assetic\Factory\LazyAssetManager + Symfony\Bundle\AsseticBundle\CacheWarmer\AssetManagerCacheWarmer + Assetic\Factory\Loader\CachedFormulaLoader + Assetic\Cache\ConfigCache + Symfony\Bundle\AsseticBundle\Factory\Loader\ConfigurationLoader + Symfony\Bundle\AsseticBundle\Factory\Resource\ConfigurationResource + Symfony\Bundle\AsseticBundle\Factory\Resource\CoalescingDirectoryResource + Symfony\Bundle\AsseticBundle\Factory\Resource\DirectoryResource + Symfony\Bundle\AsseticBundle\FilterManager + Assetic\Factory\Worker\EnsureFilterWorker + Symfony\Bundle\AsseticBundle\DefaultValueSupplier + + + %kernel.cache_dir%/assetic + + + + + + + + + + + + + + + + + + + %assetic.read_from% + %assetic.debug% + + + + + + + + + + + + %assetic.cache_dir%/config + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/controller.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/controller.xml new file mode 100644 index 0000000..19b348f --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/controller.xml @@ -0,0 +1,41 @@ + + + + + + Symfony\Bundle\AsseticBundle\Controller\AsseticController + Symfony\Bundle\AsseticBundle\Routing\AsseticLoader + Assetic\Cache\FilesystemCache + Symfony\Bundle\AsseticBundle\Factory\Worker\UseControllerWorker + Symfony\Bundle\AsseticBundle\EventListener\RequestListener + + + + + + + + + + + + %assetic.enable_profiler% + + + + + + + + %assetic.cache_dir%/assets + + + + + + + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/closure.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/closure.xml new file mode 100644 index 0000000..4450220 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/closure.xml @@ -0,0 +1,31 @@ + + + + + + Assetic\Filter\GoogleClosure\CompilerApiFilter + Assetic\Filter\GoogleClosure\CompilerJarFilter + %assetic.java.bin% + null + + + + + + %assetic.filter.closure.jar% + %assetic.filter.closure.java% + + %assetic.filter.closure.compilation_level% + + + + + + + %assetic.filter.closure.compilation_level% + + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/coffee.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/coffee.xml new file mode 100644 index 0000000..4feda54 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/coffee.xml @@ -0,0 +1,22 @@ + + + + + + Assetic\Filter\CoffeeScriptFilter + /usr/bin/coffee + %assetic.node.bin% + null + + + + + + %assetic.filter.coffee.bin% + %assetic.filter.coffee.node% + %assetic.filter.coffee.bare% + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/compass.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/compass.xml new file mode 100644 index 0000000..43bbec2 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/compass.xml @@ -0,0 +1,36 @@ + + + + + + Assetic\Filter\CompassFilter + /usr/bin/compass + false + null + null + null + null + null + null + null + + + + + + + %assetic.filter.compass.bin% + %assetic.filter.compass.debug% + %assetic.filter.compass.style% + %assetic.filter.compass.images_dir% + %assetic.filter.compass.javascripts_dir% + %assetic.filter.compass.http_path% + %assetic.filter.compass.http_images_path% + %assetic.filter.compass.generated_images_path% + %assetic.filter.compass.http_javascripts_path% + %assetic.filter.compass.plugins% + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/cssembed.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/cssembed.xml new file mode 100644 index 0000000..ccf0d56 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/cssembed.xml @@ -0,0 +1,34 @@ + + + + + + Assetic\Filter\CssEmbedFilter + %assetic.java.bin% + + %kernel.charset% + false + null + null + false + null + null + + + + + + %assetic.filter.cssembed.jar% + %assetic.filter.cssembed.java% + %assetic.filter.cssembed.charset% + %assetic.filter.cssembed.mhtml% + %assetic.filter.cssembed.mhtml_root% + %assetic.filter.cssembed.root% + %assetic.filter.cssembed.skip_missing% + %assetic.filter.cssembed.max_uri_length% + %assetic.filter.cssembed.max_image_size% + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/cssimport.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/cssimport.xml new file mode 100644 index 0000000..08440cd --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/cssimport.xml @@ -0,0 +1,16 @@ + + + + + + Assetic\Filter\CssImportFilter + + + + + + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/cssmin.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/cssmin.xml new file mode 100644 index 0000000..0fd1057 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/cssmin.xml @@ -0,0 +1,20 @@ + + + + + + Assetic\Filter\CssMinFilter + + + + + + + + %assetic.filter.cssmin.filters% + %assetic.filter.cssmin.plugins% + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/cssrewrite.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/cssrewrite.xml new file mode 100644 index 0000000..383d8cd --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/cssrewrite.xml @@ -0,0 +1,16 @@ + + + + + + Assetic\Filter\CssRewriteFilter + + + + + + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/gss.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/gss.xml new file mode 100644 index 0000000..a1514bf --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/gss.xml @@ -0,0 +1,20 @@ + + + + + + Assetic\Filter\GssFilter + %assetic.java.bin% + + + + + + + %assetic.filter.gss.jar% + %assetic.filter.gss.java% + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/jpegoptim.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/jpegoptim.xml new file mode 100644 index 0000000..0de4069 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/jpegoptim.xml @@ -0,0 +1,22 @@ + + + + + + Assetic\Filter\JpegoptimFilter + /usr/bin/jpegoptim + false + null + + + + + + %assetic.filter.jpegoptim.bin% + %assetic.filter.jpegoptim.strip_all% + %assetic.filter.jpegoptim.max% + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/jpegtran.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/jpegtran.xml new file mode 100644 index 0000000..3d0f854 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/jpegtran.xml @@ -0,0 +1,26 @@ + + + + + + Assetic\Filter\JpegtranFilter + /usr/bin/jpegtran + null + false + false + null + + + + + + %assetic.filter.jpegtran.bin% + %assetic.filter.jpegtran.copy% + %assetic.filter.jpegtran.optimize% + %assetic.filter.jpegtran.progressive% + %assetic.filter.jpegtran.restart% + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/less.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/less.xml new file mode 100644 index 0000000..dacaf22 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/less.xml @@ -0,0 +1,22 @@ + + + + + + Assetic\Filter\LessFilter + %assetic.node.bin% + %assetic.node.paths% + null + + + + + + %assetic.filter.less.node% + %assetic.filter.less.node_paths% + %assetic.filter.less.compress% + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/lessphp.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/lessphp.xml new file mode 100644 index 0000000..c4fbefa --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/lessphp.xml @@ -0,0 +1,18 @@ + + + + + + Assetic\Filter\LessphpFilter + + + + + + + %assetic.filter.lessphp.presets% + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/optipng.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/optipng.xml new file mode 100644 index 0000000..5925e77 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/optipng.xml @@ -0,0 +1,20 @@ + + + + + + Assetic\Filter\OptiPngFilter + /usr/bin/optipng + null + + + + + + %assetic.filter.optipng.bin% + %assetic.filter.optipng.level% + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/packager.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/packager.xml new file mode 100644 index 0000000..6446116 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/packager.xml @@ -0,0 +1,18 @@ + + + + + + Assetic\Filter\PackagerFilter + + + + + + + %assetic.filter.packager.packages% + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/pngout.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/pngout.xml new file mode 100644 index 0000000..2c5af72 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/pngout.xml @@ -0,0 +1,26 @@ + + + + + + Assetic\Filter\PngoutFilter + /usr/bin/pngout + null + null + null + null + + + + + + %assetic.filter.pngout.bin% + %assetic.filter.pngout.color% + %assetic.filter.pngout.filter% + %assetic.filter.pngout.strategy% + %assetic.filter.pngout.block_split_threshold% + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/sass.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/sass.xml new file mode 100644 index 0000000..2c4e931 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/sass.xml @@ -0,0 +1,22 @@ + + + + + + Assetic\Filter\Sass\SassFilter + %assetic.sass.bin% + null + null + + + + + + %assetic.filter.sass.bin% + %assetic.filter.sass.style% + %assetic.filter.sass.compass% + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/scss.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/scss.xml new file mode 100644 index 0000000..006c454 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/scss.xml @@ -0,0 +1,22 @@ + + + + + + Assetic\Filter\Sass\ScssFilter + %assetic.sass.bin% + null + null + + + + + + %assetic.filter.scss.sass% + %assetic.filter.scss.style% + %assetic.filter.scss.compass% + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/sprockets.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/sprockets.xml new file mode 100644 index 0000000..27808c3 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/sprockets.xml @@ -0,0 +1,23 @@ + + + + + + Assetic\Filter\SprocketsFilter + null + %assetic.ruby.bin% + %assetic.write_to% + + + + + + + %assetic.filter.sprockets.lib% + %assetic.filter.sprockets.ruby% + %assetic.filter.sprockets.asset_root% + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/stylus.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/stylus.xml new file mode 100644 index 0000000..cfc5b93 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/stylus.xml @@ -0,0 +1,22 @@ + + + + + + Assetic\Filter\StylusFilter + %assetic.node.bin% + %assetic.node.paths% + null + + + + + + %assetic.filter.stylus.node% + %assetic.filter.stylus.node_paths% + %assetic.filter.stylus.compress% + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/uglifyjs.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/uglifyjs.xml new file mode 100644 index 0000000..3ccb42b --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/uglifyjs.xml @@ -0,0 +1,32 @@ + + + + + + Assetic\Filter\UglifyJsFilter + /usr/bin/uglifyjs + %assetic.node.bin% + false + false + false + + + + + + %assetic.filter.uglifyjs.bin% + %assetic.filter.uglifyjs.node% + + %assetic.filter.uglifyjs.beautify% + + + %assetic.filter.uglifyjs.no_copyright% + + + %assetic.filter.uglifyjs.unsafe% + + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/yui_css.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/yui_css.xml new file mode 100644 index 0000000..a5808c6 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/yui_css.xml @@ -0,0 +1,22 @@ + + + + + + Assetic\Filter\Yui\CssCompressorFilter + %assetic.java.bin% + + %kernel.charset% + + + + + + %assetic.filter.yui_css.jar% + %assetic.filter.yui_css.java% + %assetic.filter.yui_css.charset% + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/yui_js.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/yui_js.xml new file mode 100644 index 0000000..75a53e6 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/filters/yui_js.xml @@ -0,0 +1,28 @@ + + + + + + Assetic\Filter\Yui\JsCompressorFilter + %assetic.java.bin% + + %kernel.charset% + null + null + null + + + + + + %assetic.filter.yui_js.jar% + %assetic.filter.yui_js.java% + %assetic.filter.yui_js.charset% + %assetic.filter.yui_js.nomunge% + %assetic.filter.yui_js.preserve_semi% + %assetic.filter.yui_js.disable_optimizations% + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/schema/assetic-1.0.xsd b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/schema/assetic-1.0.xsd new file mode 100644 index 0000000..82e35a3 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/schema/assetic-1.0.xsd @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/templating_php.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/templating_php.xml new file mode 100644 index 0000000..b6843d9 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/templating_php.xml @@ -0,0 +1,39 @@ + + + + + + Symfony\Bundle\AsseticBundle\Templating\DynamicAsseticHelper + Symfony\Bundle\AsseticBundle\Templating\StaticAsseticHelper + Symfony\Bundle\AsseticBundle\Factory\Loader\AsseticHelperFormulaLoader + + + + + + + + + + + + + + + + + + + + + %kernel.debug% + + + + + + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/templating_twig.xml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/templating_twig.xml new file mode 100644 index 0000000..8ab025b --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Resources/config/templating_twig.xml @@ -0,0 +1,35 @@ + + + + + + Symfony\Bundle\AsseticBundle\Twig\AsseticExtension + Assetic\Extension\Twig\TwigFormulaLoader + + + + + + + + + %assetic.use_controller% + %assetic.twig_extension.functions% + %assetic.bundles% + + + + + + + + %kernel.debug% + + + + + + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Routing/AsseticLoader.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Routing/AsseticLoader.php new file mode 100644 index 0000000..b2e8385 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Routing/AsseticLoader.php @@ -0,0 +1,122 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Routing; + +use Assetic\Asset\AssetInterface; +use Assetic\Factory\LazyAssetManager; +use Symfony\Bundle\AsseticBundle\Config\AsseticResource; +use Symfony\Component\Config\Loader\Loader; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Routing\Route; +use Symfony\Component\Routing\RouteCollection; + +/** + * Loads routes for all assets. + * + * Assets should only be served through the routing system for ease-of-use + * during development. + * + * For example, add the following to your application's routing_dev.yml: + * + * _assetic: + * resource: . + * type: assetic + * + * In a production environment you should use the `assetic:dump` command to + * create static asset files. + * + * @author Kris Wallsmith + */ +class AsseticLoader extends Loader +{ + protected $am; + + public function __construct(LazyAssetManager $am) + { + $this->am = $am; + } + + public function load($routingResource, $type = null) + { + $routes = new RouteCollection(); + + // resources + foreach ($this->am->getResources() as $resources) { + if (!$resources instanceof \Traversable) { + $resources = array($resources); + } + foreach ($resources as $resource) { + $routes->addResource(new AsseticResource($resource)); + } + } + + // routes + foreach ($this->am->getNames() as $name) { + $asset = $this->am->get($name); + $formula = $this->am->getFormula($name); + + $this->loadRouteForAsset($routes, $asset, $name); + + $debug = isset($formula[2]['debug']) ? $formula[2]['debug'] : $this->am->isDebug(); + $combine = isset($formula[2]['combine']) ? $formula[2]['combine'] : !$debug; + + // add a route for each "leaf" in debug mode + if (!$combine) { + $i = 0; + foreach ($asset as $leaf) { + $this->loadRouteForAsset($routes, $leaf, $name, $i++); + } + } + } + + return $routes; + } + + /** + * Loads a route to serve an supplied asset. + * + * The fake front controller that {@link UseControllerWorker} adds to the + * target URL will be removed before set as a route pattern. + * + * @param RouteCollection $routes The route collection + * @param AssetInterface $asset The asset + * @param string $name The name to use + * @param integer $pos The leaf index + */ + private function loadRouteForAsset(RouteCollection $routes, AssetInterface $asset, $name, $pos = null) + { + $defaults = array( + '_controller' => 'assetic.controller:render', + 'name' => $name, + 'pos' => $pos, + ); + + // remove the fake front controller + $pattern = str_replace('_controller/', '', $asset->getTargetPath()); + + if ($format = pathinfo($pattern, PATHINFO_EXTENSION)) { + $defaults['_format'] = $format; + } + + $route = '_assetic_'.$name; + if (null !== $pos) { + $route .= '_'.$pos; + } + + $routes->add($route, new Route($pattern, $defaults)); + } + + public function supports($resource, $type = null) + { + return 'assetic' == $type; + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Templating/AsseticHelper.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Templating/AsseticHelper.php new file mode 100644 index 0000000..4944209 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Templating/AsseticHelper.php @@ -0,0 +1,157 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Templating; + +use Assetic\Asset\AssetInterface; +use Assetic\Factory\AssetFactory; +use Assetic\Util\TraversableString; +use Symfony\Component\Templating\Helper\Helper; + +/** + * The "assetic" templating helper. + * + * @author Kris Wallsmith + */ +abstract class AsseticHelper extends Helper +{ + protected $factory; + + /** + * Constructor. + * + * @param AssetFactory $factory The asset factory + */ + public function __construct(AssetFactory $factory) + { + $this->factory = $factory; + } + + /** + * Returns an array of javascript urls. + */ + public function javascripts($inputs = array(), $filters = array(), array $options = array()) + { + if (!isset($options['output'])) { + $options['output'] = 'js/*.js'; + } + + return $this->getAssetUrls($inputs, $filters, $options); + } + + /** + * Returns an array of stylesheet urls. + */ + public function stylesheets($inputs = array(), $filters = array(), array $options = array()) + { + if (!isset($options['output'])) { + $options['output'] = 'css/*.css'; + } + + return $this->getAssetUrls($inputs, $filters, $options); + } + + /** + * Returns an array of one image url. + */ + public function image($inputs = array(), $filters = array(), array $options = array()) + { + if (!isset($options['output'])) { + $options['output'] = 'images/*'; + } + + $options['single'] = true; + + return $this->getAssetUrls($inputs, $filters, $options); + } + + /** + * Gets the URLs for the configured asset. + * + * Usage looks something like this: + * + * assets('@jquery, js/src/core/*', '?yui_js') as $url): ?> + * + * + * + * When in debug mode, the helper returns an array of one or more URLs. + * When not in debug mode it returns an array of one URL. + * + * @param array|string $inputs An array or comma-separated list of input strings + * @param array|string $filters An array or comma-separated list of filter names + * @param array $options An array of options + * + * @return array An array of URLs for the asset + */ + private function getAssetUrls($inputs = array(), $filters = array(), array $options = array()) + { + $explode = function($value) + { + return array_map('trim', explode(',', $value)); + }; + + if (!is_array($inputs)) { + $inputs = $explode($inputs); + } + + if (!is_array($filters)) { + $filters = $explode($filters); + } + + if (!isset($options['debug'])) { + $options['debug'] = $this->factory->isDebug(); + } + + if (!isset($options['combine'])) { + $options['combine'] = !$options['debug']; + } + + if (isset($options['single']) && $options['single'] && 1 < count($inputs)) { + $inputs = array_slice($inputs, -1); + } + + if (!isset($options['name'])) { + $options['name'] = $this->factory->generateAssetName($inputs, $filters, $options); + } + + $asset = $this->factory->createAsset($inputs, $filters, $options); + + $one = $this->getAssetUrl($asset, $options); + $many = array(); + if ($options['combine']) { + $many[] = $one; + } else { + $i = 0; + foreach ($asset as $leaf) { + $many[] = $this->getAssetUrl($leaf, array_replace($options, array( + 'name' => $options['name'].'_'.$i++, + ))); + } + } + + return new TraversableString($one, $many); + } + + /** + * Returns an URL for the supplied asset. + * + * @param AssetInterface $asset An asset + * @param array $options An array of options + * + * @return string An echo-ready URL + */ + abstract protected function getAssetUrl(AssetInterface $asset, $options = array()); + + public function getName() + { + return 'assetic'; + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Templating/DynamicAsseticHelper.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Templating/DynamicAsseticHelper.php new file mode 100644 index 0000000..c4bdcd7 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Templating/DynamicAsseticHelper.php @@ -0,0 +1,44 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Templating; + +use Assetic\Asset\AssetInterface; +use Assetic\Factory\AssetFactory; +use Symfony\Bundle\FrameworkBundle\Templating\Helper\RouterHelper; + +/** + * The dynamic "assetic" templating helper. + * + * @author Kris Wallsmith + */ +class DynamicAsseticHelper extends AsseticHelper +{ + private $routerHelper; + + /** + * Constructor. + * + * @param RouterHelper $routerHelper The router helper + * @param AssetFactory $factory The asset factory + */ + public function __construct(RouterHelper $routerHelper, AssetFactory $factory) + { + $this->routerHelper = $routerHelper; + + parent::__construct($factory); + } + + protected function getAssetUrl(AssetInterface $asset, $options = array()) + { + return $this->routerHelper->generate('_assetic_'.$options['name']); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Templating/StaticAsseticHelper.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Templating/StaticAsseticHelper.php new file mode 100644 index 0000000..39ba793 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Templating/StaticAsseticHelper.php @@ -0,0 +1,44 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Templating; + +use Assetic\Asset\AssetInterface; +use Assetic\Factory\AssetFactory; +use Symfony\Component\Templating\Helper\CoreAssetsHelper; + +/** + * The static "assetic" templating helper. + * + * @author Kris Wallsmith + */ +class StaticAsseticHelper extends AsseticHelper +{ + private $assetsHelper; + + /** + * Constructor. + * + * @param CoreAssetsHelper $assetsHelper The assets helper + * @param AssetFactory $factory The asset factory + */ + public function __construct(CoreAssetsHelper $assetsHelper, AssetFactory $factory) + { + $this->assetsHelper = $assetsHelper; + + parent::__construct($factory); + } + + protected function getAssetUrl(AssetInterface $asset, $options = array()) + { + return $this->assetsHelper->getUrl($asset->getTargetPath(), isset($options['package']) ? $options['package'] : null); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/CacheWarmer/AssetManagerCacheWarmerTest.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/CacheWarmer/AssetManagerCacheWarmerTest.php new file mode 100644 index 0000000..597fe4d --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/CacheWarmer/AssetManagerCacheWarmerTest.php @@ -0,0 +1,51 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Tests\CacheWarmer; + +use Symfony\Bundle\AsseticBundle\CacheWarmer\AssetManagerCacheWarmer; + +class AssetManagerCacheWarmerTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Assetic\\AssetManager')) { + $this->markTestSkipped('Assetic is not available.'); + } + } + + public function testWarmUp() + { + $am = $this + ->getMockBuilder('Assetic\\Factory\\LazyAssetManager') + ->disableOriginalConstructor() + ->getMock() + ; + + $am->expects($this->once())->method('load'); + + $container = $this + ->getMockBuilder('Symfony\\Component\\DependencyInjection\\Container') + ->setConstructorArgs(array()) + ->getMock() + ; + + $container + ->expects($this->once()) + ->method('get') + ->with('assetic.asset_manager') + ->will($this->returnValue($am)) + ; + + $warmer = new AssetManagerCacheWarmer($container); + $warmer->warmUp('/path/to/cache'); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Command/DumpCommandTest.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Command/DumpCommandTest.php new file mode 100644 index 0000000..a2862c7 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Command/DumpCommandTest.php @@ -0,0 +1,202 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Tests\Command; + +use Symfony\Bundle\AsseticBundle\Command\DumpCommand; +use Symfony\Component\Console\Input\ArrayInput; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\NullOutput; + +class DumpCommandTest extends \PHPUnit_Framework_TestCase +{ + private $writeTo; + private $application; + private $definition; + private $kernel; + private $container; + private $am; + + protected function setUp() + { + if (!class_exists('Assetic\\AssetManager')) { + $this->markTestSkipped('Assetic is not available.'); + } + + $this->writeTo = sys_get_temp_dir().'/assetic_dump'; + + $this->application = $this->getMockBuilder('Symfony\\Bundle\\FrameworkBundle\\Console\\Application') + ->disableOriginalConstructor() + ->getMock(); + $this->definition = $this->getMockBuilder('Symfony\\Component\\Console\\Input\\InputDefinition') + ->disableOriginalConstructor() + ->getMock(); + $this->kernel = $this->getMock('Symfony\\Component\\HttpKernel\\KernelInterface'); + $this->helperSet = $this->getMock('Symfony\\Component\\Console\\Helper\\HelperSet'); + $this->container = $this->getMock('Symfony\\Component\\DependencyInjection\\ContainerInterface'); + $this->am = $this->getMockBuilder('Assetic\\Factory\\LazyAssetManager') + ->disableOriginalConstructor() + ->getMock(); + + $this->application->expects($this->any()) + ->method('getDefinition') + ->will($this->returnValue($this->definition)); + $this->definition->expects($this->any()) + ->method('getArguments') + ->will($this->returnValue(array())); + $this->definition->expects($this->any()) + ->method('getOptions') + ->will($this->returnValue(array( + new InputOption('--verbose', '-v', InputOption::VALUE_NONE, 'Increase verbosity of messages.'), + new InputOption('--env', '-e', InputOption::VALUE_REQUIRED, 'The Environment name.', 'dev'), + new InputOption('--no-debug', null, InputOption::VALUE_NONE, 'Switches off debug mode.'), + ))); + $this->application->expects($this->any()) + ->method('getKernel') + ->will($this->returnValue($this->kernel)); + $this->application->expects($this->once()) + ->method('getHelperSet') + ->will($this->returnValue($this->helperSet)); + $this->kernel->expects($this->any()) + ->method('getContainer') + ->will($this->returnValue($this->container)); + + $writeTo = $this->writeTo; + $this->container->expects($this->any()) + ->method('getParameter') + ->will($this->returnCallback(function($p) use($writeTo) { + if ('assetic.write_to' === $p) { + return $writeTo; + } else if ('assetic.variables' === $p) { + return array(); + } + + throw new \RuntimeException(sprintf('Unknown parameter "%s".', $p)); + })); + + $this->container->expects($this->once()) + ->method('get') + ->with('assetic.asset_manager') + ->will($this->returnValue($this->am)); + + $this->command = new DumpCommand(); + $this->command->setApplication($this->application); + } + + protected function tearDown() + { + if (is_dir($this->writeTo)) { + array_map('unlink', glob($this->writeTo.'/*')); + rmdir($this->writeTo); + } + } + + public function testEmptyAssetManager() + { + $this->am->expects($this->once()) + ->method('getNames') + ->will($this->returnValue(array())); + + $this->command->run(new ArrayInput(array()), new NullOutput()); + } + + public function testDumpOne() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $this->am->expects($this->once()) + ->method('getNames') + ->will($this->returnValue(array('test_asset'))); + $this->am->expects($this->once()) + ->method('get') + ->with('test_asset') + ->will($this->returnValue($asset)); + $this->am->expects($this->once()) + ->method('getFormula') + ->with('test_asset') + ->will($this->returnValue(array())); + $this->am->expects($this->once()) + ->method('isDebug') + ->will($this->returnValue(false)); + $asset->expects($this->once()) + ->method('getTargetPath') + ->will($this->returnValue('test_asset.css')); + $asset->expects($this->once()) + ->method('dump') + ->will($this->returnValue('/* test_asset */')); + $asset->expects($this->any()) + ->method('getVars') + ->will($this->returnValue(array())); + $asset->expects($this->any()) + ->method('getValues') + ->will($this->returnValue(array())); + + $this->command->run(new ArrayInput(array()), new NullOutput()); + + $this->assertFileExists($this->writeTo.'/test_asset.css'); + $this->assertEquals('/* test_asset */', file_get_contents($this->writeTo.'/test_asset.css')); + } + + public function testDumpDebug() + { + $asset = $this->getMock('Assetic\\Asset\\AssetCollection'); + $leaf = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $this->am->expects($this->once()) + ->method('getNames') + ->will($this->returnValue(array('test_asset'))); + $this->am->expects($this->once()) + ->method('get') + ->with('test_asset') + ->will($this->returnValue($asset)); + $this->am->expects($this->once()) + ->method('getFormula') + ->with('test_asset') + ->will($this->returnValue(array())); + $this->am->expects($this->once()) + ->method('isDebug') + ->will($this->returnValue(true)); + $asset->expects($this->once()) + ->method('getTargetPath') + ->will($this->returnValue('test_asset.css')); + $asset->expects($this->once()) + ->method('dump') + ->will($this->returnValue('/* test_asset */')); + $asset->expects($this->once()) + ->method('getIterator') + ->will($this->returnValue(new \ArrayIterator(array($leaf)))); + $asset->expects($this->any()) + ->method('getVars') + ->will($this->returnValue(array())); + $asset->expects($this->any()) + ->method('getValues') + ->will($this->returnValue(array())); + $leaf->expects($this->once()) + ->method('getTargetPath') + ->will($this->returnValue('test_leaf.css')); + $leaf->expects($this->once()) + ->method('dump') + ->will($this->returnValue('/* test_leaf */')); + $leaf->expects($this->any()) + ->method('getVars') + ->will($this->returnValue(array())); + $leaf->expects($this->any()) + ->method('getValues') + ->will($this->returnValue(array())); + + $this->command->run(new ArrayInput(array()), new NullOutput()); + + $this->assertFileExists($this->writeTo.'/test_asset.css'); + $this->assertFileExists($this->writeTo.'/test_leaf.css'); + $this->assertEquals('/* test_asset */', file_get_contents($this->writeTo.'/test_asset.css')); + $this->assertEquals('/* test_leaf */', file_get_contents($this->writeTo.'/test_leaf.css')); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Controller/AsseticControllerTest.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Controller/AsseticControllerTest.php new file mode 100644 index 0000000..5fb058e --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Controller/AsseticControllerTest.php @@ -0,0 +1,167 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Tests\Controller; + +use Symfony\Bundle\AsseticBundle\Controller\AsseticController; + +class AsseticControllerTest extends \PHPUnit_Framework_TestCase +{ + protected $request; + protected $headers; + protected $am; + protected $cache; + + protected $controller; + + protected function setUp() + { + if (!class_exists('Assetic\\AssetManager')) { + $this->markTestSkipped('Assetic is not available.'); + } + + $this->request = $this->getMock('Symfony\\Component\\HttpFoundation\\Request'); + $this->headers = $this->getMock('Symfony\\Component\\HttpFoundation\\ParameterBag'); + $this->request->headers = $this->headers; + $this->am = $this->getMockBuilder('Assetic\\Factory\\LazyAssetManager') + ->disableOriginalConstructor() + ->getMock(); + $this->cache = $this->getMock('Assetic\\Cache\\CacheInterface'); + + $this->controller = new AsseticController($this->request, $this->am, $this->cache); + } + + public function testRenderNotFound() + { + $this->setExpectedException('Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException'); + + $name = 'foo'; + + $this->am->expects($this->once()) + ->method('has') + ->with($name) + ->will($this->returnValue(false)); + + $this->controller->render($name); + } + + public function testRenderLastModifiedFresh() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $name = 'foo'; + $lastModified = strtotime('2010-10-10 10:10:10'); + $ifModifiedSince = gmdate('D, d M Y H:i:s', $lastModified).' GMT'; + + $asset->expects($this->any())->method('getFilters')->will($this->returnValue(array())); + $this->am->expects($this->once())->method('has')->with($name)->will($this->returnValue(true)); + $this->am->expects($this->once())->method('get')->with($name)->will($this->returnValue($asset)); + $asset->expects($this->once())->method('getLastModified')->will($this->returnValue($lastModified)); + $this->headers->expects($this->once())->method('get')->with('If-Modified-Since')->will($this->returnValue($ifModifiedSince)); + + $asset->expects($this->never()) + ->method('dump'); + + $response = $this->controller->render($name); + $this->assertEquals(304, $response->getStatusCode(), '->render() sends a Not Modified response when If-Modified-Since is fresh'); + } + + public function testRenderLastModifiedStale() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $name = 'foo'; + $content = '==ASSET_CONTENT=='; + $lastModified = strtotime('2010-10-10 10:10:10'); + $ifModifiedSince = gmdate('D, d M Y H:i:s', $lastModified - 300).' GMT'; + + $asset->expects($this->any())->method('getFilters')->will($this->returnValue(array())); + $this->am->expects($this->once())->method('has')->with($name)->will($this->returnValue(true)); + $this->am->expects($this->once())->method('get')->with($name)->will($this->returnValue($asset)); + $asset->expects($this->exactly(2))->method('getLastModified')->will($this->returnValue($lastModified)); + $this->headers->expects($this->once())->method('get')->with('If-Modified-Since')->will($this->returnValue($ifModifiedSince)); + + $this->cache->expects($this->once()) + ->method('has') + ->with($this->isType('string')) + ->will($this->returnValue(false)); + $asset->expects($this->once()) + ->method('dump') + ->will($this->returnValue($content)); + + $response = $this->controller->render($name); + $this->assertEquals(200, $response->getStatusCode(), '->render() sends an OK response when If-Modified-Since is stale'); + $this->assertEquals($content, $response->getContent(), '->render() sends the dumped asset as the response content'); + } + + public function testRenderETagFresh() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $name = 'foo'; + $formula = array(array('js/core.js'), array(), array('')); + $etag = md5(serialize($formula + array('last_modified' => null))); + + $asset->expects($this->any())->method('getFilters')->will($this->returnValue(array())); + $this->am->expects($this->once())->method('has')->with($name)->will($this->returnValue(true)); + $this->am->expects($this->once())->method('get')->with($name)->will($this->returnValue($asset)); + + $this->am->expects($this->once()) + ->method('hasFormula') + ->with($name) + ->will($this->returnValue(true)); + $this->am->expects($this->once()) + ->method('getFormula') + ->with($name) + ->will($this->returnValue($formula)); + $this->request->expects($this->once()) + ->method('getETags') + ->will($this->returnValue(array('"'.$etag.'"'))); + $asset->expects($this->never()) + ->method('dump'); + + $response = $this->controller->render($name); + $this->assertEquals(304, $response->getStatusCode(), '->render() sends a Not Modified response when If-None-Match is fresh'); + } + + public function testRenderETagStale() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $name = 'foo'; + $content = '==ASSET_CONTENT=='; + $formula = array(array('js/core.js'), array(), array('')); + $etag = md5(serialize($formula + array('last_modified' => null))); + + $asset->expects($this->any())->method('getFilters')->will($this->returnValue(array())); + $this->am->expects($this->once())->method('has')->with($name)->will($this->returnValue(true)); + $this->am->expects($this->once())->method('get')->with($name)->will($this->returnValue($asset)); + + $this->am->expects($this->once()) + ->method('hasFormula') + ->with($name) + ->will($this->returnValue(true)); + $this->am->expects($this->once()) + ->method('getFormula') + ->with($name) + ->will($this->returnValue($formula)); + $this->request->expects($this->once()) + ->method('getETags') + ->will($this->returnValue(array('"123"'))); + $asset->expects($this->once()) + ->method('dump') + ->will($this->returnValue($content)); + + $response = $this->controller->render($name); + $this->assertEquals(200, $response->getStatusCode(), '->render() sends an OK response when If-None-Match is stale'); + $this->assertEquals($content, $response->getContent(), '->render() sends the dumped asset as the response content'); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/DependencyInjection/AsseticExtensionTest.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/DependencyInjection/AsseticExtensionTest.php new file mode 100644 index 0000000..ebdb8cb --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/DependencyInjection/AsseticExtensionTest.php @@ -0,0 +1,215 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Tests\DependencyInjection; + +use Symfony\Bundle\AsseticBundle\DependencyInjection\AsseticExtension; +use Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler\CheckYuiFilterPass; +use Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler\CheckClosureFilterPass; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Dumper\PhpDumper; +use Symfony\Component\DependencyInjection\Scope; +use Symfony\Component\HttpFoundation\Request; + +class AsseticExtensionTest extends \PHPUnit_Framework_TestCase +{ + private $kernel; + private $container; + + static public function assertSaneContainer(Container $container, $message = '') + { + $errors = array(); + foreach ($container->getServiceIds() as $id) { + try { + $container->get($id); + } catch (\Exception $e) { + $errors[$id] = $e->getMessage(); + } + } + + self::assertEquals(array(), $errors, $message); + } + + protected function setUp() + { + if (!class_exists('Assetic\\AssetManager')) { + $this->markTestSkipped('Assetic is not available.'); + } + + $this->kernel = $this->getMock('Symfony\\Component\\HttpKernel\\KernelInterface'); + + $this->container = new ContainerBuilder(); + $this->container->addScope(new Scope('request')); + $this->container->register('request', 'Symfony\\Component\\HttpFoundation\\Request')->setScope('request'); + $this->container->register('templating.helper.assets', $this->getMockClass('Symfony\\Component\\Templating\\Helper\\AssetsHelper')); + $this->container->register('templating.helper.router', $this->getMockClass('Symfony\\Bundle\\FrameworkBundle\\Templating\\Helper\\RouterHelper')) + ->addArgument(new Definition($this->getMockClass('Symfony\\Component\\Routing\\RouterInterface'))); + $this->container->register('twig', 'Twig_Environment'); + $this->container->setParameter('kernel.bundles', array()); + $this->container->setParameter('kernel.cache_dir', __DIR__); + $this->container->setParameter('kernel.debug', false); + $this->container->setParameter('kernel.root_dir', __DIR__); + $this->container->setParameter('kernel.charset', 'UTF-8'); + $this->container->set('kernel', $this->kernel); + } + + /** + * @dataProvider getDebugModes + */ + public function testDefaultConfig($debug) + { + $this->container->setParameter('kernel.debug', $debug); + + $extension = new AsseticExtension(); + $extension->load(array(array()), $this->container); + + $this->assertFalse($this->container->has('assetic.filter.yui_css'), '->load() does not load the yui_css filter when a yui value is not provided'); + $this->assertFalse($this->container->has('assetic.filter.yui_js'), '->load() does not load the yui_js filter when a yui value is not provided'); + + $this->assertSaneContainer($this->getDumpedContainer()); + } + + public function getDebugModes() + { + return array( + array(true), + array(false), + ); + } + + /** + * @dataProvider getFilterNames + */ + public function testFilterConfigs($name, $config = array()) + { + $extension = new AsseticExtension(); + $extension->load(array(array('filters' => array($name => $config))), $this->container); + + $this->assertSaneContainer($this->getDumpedContainer()); + } + + public function getFilterNames() + { + return array( + array('closure', array('jar' => '/path/to/closure.jar')), + array('coffee'), + array('compass'), + array('cssembed', array('jar' => '/path/to/cssembed.jar')), + array('cssimport'), + array('cssrewrite'), + array('jpegoptim'), + array('jpegtran'), + array('less'), + array('lessphp'), + array('optipng'), + array('packager'), + array('pngout'), + array('sass'), + array('scss'), + array('sprockets', array('include_dirs' => array('foo'))), + array('stylus'), + array('yui_css', array('jar' => '/path/to/yuicompressor.jar')), + array('yui_js', array('jar' => '/path/to/yuicompressor.jar')), + ); + } + + /** + * @dataProvider getUseControllerKeys + */ + public function testUseController($bool, $includes, $omits) + { + $extension = new AsseticExtension(); + $extension->load(array(array('use_controller' => $bool)), $this->container); + + foreach ($includes as $id) { + $this->assertTrue($this->container->has($id), '"'.$id.'" is registered when use_controller is '.$bool); + } + + foreach ($omits as $id) { + $this->assertFalse($this->container->has($id), '"'.$id.'" is not registered when use_controller is '.$bool); + } + + $this->assertSaneContainer($this->getDumpedContainer()); + } + + public function getUseControllerKeys() + { + return array( + array(true, array('assetic.routing_loader', 'assetic.controller'), array()), + array(false, array(), array('assetic.routing_loader', 'assetic.controller')), + ); + } + + /** + * @dataProvider getClosureJarAndExpected + */ + public function testClosureCompilerPass($jar, $expected) + { + $this->container->addCompilerPass(new CheckClosureFilterPass()); + + $extension = new AsseticExtension(); + $extension->load(array(array( + 'filters' => array( + 'closure' => array('jar' => $jar), + ), + )), $this->container); + + $container = $this->getDumpedContainer(); + $this->assertSaneContainer($container); + + $this->assertTrue($this->container->getDefinition($expected)->hasTag('assetic.filter')); + $this->assertNotEmpty($container->getParameter('assetic.filter.closure.java')); + } + + public function getClosureJarAndExpected() + { + return array( + array(null, 'assetic.filter.closure.api'), + array('/path/to/closure.jar', 'assetic.filter.closure.jar'), + ); + } + + public function testInvalidYuiConfig() + { + $this->setExpectedException('RuntimeException', 'assetic.filters.yui_js'); + + $this->container->addCompilerPass(new CheckYuiFilterPass()); + + $extension = new AsseticExtension(); + $extension->load(array(array( + 'filters' => array( + 'yui_js' => array(), + ), + )), $this->container); + + $this->getDumpedContainer(); + } + + private function getDumpedContainer() + { + static $i = 0; + $class = 'AsseticExtensionTestContainer'.$i++; + + $this->container->compile(); + + $dumper = new PhpDumper($this->container); + eval('?>'.$dumper->dump(array('class' => $class))); + + $container = new $class(); + $container->enterScope('request'); + $container->set('request', Request::create('/')); + $container->set('kernel', $this->kernel); + + return $container; + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Factory/AssetFactoryTest.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Factory/AssetFactoryTest.php new file mode 100644 index 0000000..89f2f9e --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Factory/AssetFactoryTest.php @@ -0,0 +1,97 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Tests\Factory; + +use Symfony\Bundle\AsseticBundle\Factory\AssetFactory; + +class AssetFactoryTest extends \PHPUnit_Framework_TestCase +{ + protected $kernel; + protected $factory; + protected $container; + + protected function setUp() + { + if (!class_exists('Assetic\\AssetManager')) { + $this->markTestSkipped('Assetic is not available.'); + } + + $this->kernel = $this->getMock('Symfony\\Component\\HttpKernel\\KernelInterface'); + $this->container = $this->getMock('Symfony\\Component\\DependencyInjection\\ContainerInterface'); + $this->parameterBag = $this->getMock('Symfony\\Component\\DependencyInjection\\ParameterBag\\ParameterBagInterface'); + $this->factory = new AssetFactory($this->kernel, $this->container, $this->parameterBag, '/path/to/web'); + } + + public function testBundleNotation() + { + $input = '@MyBundle/Resources/css/main.css'; + $bundle = $this->getMock('Symfony\\Component\\HttpKernel\\Bundle\\BundleInterface'); + + $this->parameterBag->expects($this->once()) + ->method('resolveValue') + ->will($this->returnCallback(function($v) { return $v; })); + $this->kernel->expects($this->once()) + ->method('getBundle') + ->with('MyBundle') + ->will($this->returnValue($bundle)); + $this->kernel->expects($this->once()) + ->method('locateResource') + ->with($input) + ->will($this->returnValue('/path/to/MyBundle/Resources/css/main.css')); + $bundle->expects($this->once()) + ->method('getPath') + ->will($this->returnValue('/path/to/MyBundle')); + + $coll = $this->factory->createAsset($input)->all(); + $asset = $coll[0]; + + $this->assertEquals('/path/to/MyBundle', $asset->getSourceRoot(), '->createAsset() sets the asset root'); + $this->assertEquals('Resources/css/main.css', $asset->getSourcePath(), '->createAsset() sets the asset path'); + } + + /** + * @dataProvider getGlobs + */ + public function testBundleGlobNotation($input) + { + $bundle = $this->getMock('Symfony\\Component\\HttpKernel\\Bundle\\BundleInterface'); + + $this->parameterBag->expects($this->once()) + ->method('resolveValue') + ->will($this->returnCallback(function($v) { return $v; })); + $this->kernel->expects($this->once()) + ->method('getBundle') + ->with('MyBundle') + ->will($this->returnValue($bundle)); + $this->kernel->expects($this->once()) + ->method('locateResource') + ->with('@MyBundle/Resources/css/') + ->will($this->returnValue('/path/to/MyBundle/Resources/css/')); + $bundle->expects($this->once()) + ->method('getPath') + ->will($this->returnValue('/path/to/MyBundle')); + + $coll = $this->factory->createAsset($input)->all(); + $asset = $coll[0]; + + $this->assertEquals('/path/to/MyBundle', $asset->getSourceRoot(), '->createAsset() sets the asset root'); + $this->assertNull($asset->getSourcePath(), '->createAsset() sets the asset path to null'); + } + + public function getGlobs() + { + return array( + array('@MyBundle/Resources/css/*'), + array('@MyBundle/Resources/css/*/*.css'), + ); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Factory/Resource/CoalescingDirectoryResourceTest.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Factory/Resource/CoalescingDirectoryResourceTest.php new file mode 100644 index 0000000..4967e45 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Factory/Resource/CoalescingDirectoryResourceTest.php @@ -0,0 +1,63 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Tests\Factory\Resource; + +use Symfony\Bundle\AsseticBundle\Factory\Resource\CoalescingDirectoryResource; + +class CoalescingDirectoryResourceTest extends \PHPUnit_Framework_TestCase +{ + public function testFiltering() + { + $dir1 = $this->getMock('Assetic\\Factory\\Resource\\IteratorResourceInterface'); + $file1a = $this->getMock('Assetic\\Factory\\Resource\\ResourceInterface'); + $file1b = $this->getMock('Assetic\\Factory\\Resource\\ResourceInterface'); + + $dir2 = $this->getMock('Assetic\\Factory\\Resource\\IteratorResourceInterface'); + $file2a = $this->getMock('Assetic\\Factory\\Resource\\ResourceInterface'); + $file2c = $this->getMock('Assetic\\Factory\\Resource\\ResourceInterface'); + + $dir1->expects($this->any()) + ->method('getIterator') + ->will($this->returnValue(new \ArrayIterator(array($file1a, $file1b)))); + $file1a->expects($this->any()) + ->method('__toString') + ->will($this->returnValue('FooBundle:Foo:file1.foo.bar')); + $file1b->expects($this->any()) + ->method('__toString') + ->will($this->returnValue('FooBundle:Foo:file2.foo.bar')); + + $dir2->expects($this->any()) + ->method('getIterator') + ->will($this->returnValue(new \ArrayIterator(array($file2a, $file2c)))); + $file2a->expects($this->any()) + ->method('__toString') + ->will($this->returnValue('BarBundle:Foo:file1.foo.bar')); + $file2c->expects($this->any()) + ->method('__toString') + ->will($this->returnValue('BarBundle:Foo:file3.foo.bar')); + + $resource = new CoalescingDirectoryResource(array($dir1, $dir2)); + + $actual = array(); + foreach ($resource as $file) { + $actual[] = (string) $file; + } + + $expected = array( + 'FooBundle:Foo:file1.foo.bar', + 'FooBundle:Foo:file2.foo.bar', + 'BarBundle:Foo:file3.foo.bar', + ); + + $this->assertEquals($expected, $actual); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Factory/Resource/FileResourceTest.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Factory/Resource/FileResourceTest.php new file mode 100644 index 0000000..2132366 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Factory/Resource/FileResourceTest.php @@ -0,0 +1,31 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Tests\Factory\Resource; + +use Symfony\Bundle\AsseticBundle\Factory\Resource\FileResource; + +class FileResourceTest extends \PHPUnit_Framework_TestCase +{ + private $loader; + + protected function setUp() + { + $this->loader = $this->getMock('Symfony\\Component\\Templating\\Loader\\LoaderInterface'); + } + + public function testCastAsString() + { + $baseDir = '/path/to/MyBundle/Resources/views/'; + $resource = new FileResource($this->loader, 'MyBundle', $baseDir, $baseDir.'Section/template.html.twig'); + $this->assertEquals('MyBundle:Section:template.html.twig', (string) $resource); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/FilterManagerTest.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/FilterManagerTest.php new file mode 100644 index 0000000..9ef67fb --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/FilterManagerTest.php @@ -0,0 +1,59 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Tests; + +use Symfony\Bundle\AsseticBundle\FilterManager; + +class FilterManagerTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Assetic\\AssetManager')) { + $this->markTestSkipped('Assetic is not available.'); + } + } + + public function testGet() + { + $container = $this->getMock('Symfony\\Component\\DependencyInjection\\ContainerInterface'); + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + + $container->expects($this->exactly(2)) + ->method('get') + ->with('assetic.filter.bar') + ->will($this->returnValue($filter)); + + $fm = new FilterManager($container, array('foo' => 'assetic.filter.bar')); + + $this->assertSame($filter, $fm->get('foo'), '->get() loads the filter from the container'); + $this->assertSame($filter, $fm->get('foo'), '->get() loads the filter from the container'); + } + + public function testHas() + { + $container = $this->getMock('Symfony\\Component\\DependencyInjection\\ContainerInterface'); + + $fm = new FilterManager($container, array('foo' => 'assetic.filter.bar')); + $this->assertTrue($fm->has('foo'), '->has() returns true for lazily mapped filters'); + } + + public function testGetNames() + { + $container = $this->getMock('Symfony\\Component\\DependencyInjection\\ContainerInterface'); + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + + $fm = new FilterManager($container, array('foo' => 'assetic.filter.bar')); + $fm->set('bar', $filter); + + $this->assertEquals(array('foo', 'bar'), $fm->getNames(), '->getNames() returns all lazy and normal filter names'); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/FunctionalTest.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/FunctionalTest.php new file mode 100644 index 0000000..814c1cd --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/FunctionalTest.php @@ -0,0 +1,75 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Tests; + +use Symfony\Component\DomCrawler\Crawler; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Filesystem\Filesystem; + +/** + * @group functional + */ +class FunctionalTest extends \PHPUnit_Framework_TestCase +{ + protected $cacheDir; + + protected function setUp() + { + if (!class_exists('Assetic\\AssetManager')) { + $this->markTestSkipped('Assetic is not available.'); + } + + $this->cacheDir = __DIR__.'/Resources/cache'; + if (file_exists($this->cacheDir)) { + $filesystem = new Filesystem(); + $filesystem->remove($this->cacheDir); + } + + mkdir($this->cacheDir, 0777, true); + } + + protected function tearDown() + { + $filesystem = new Filesystem(); + $filesystem->remove($this->cacheDir); + } + + public function testTwigRenderDebug() + { + $kernel = new TestKernel('test', true); + $kernel->boot(); + $container = $kernel->getContainer(); + $container->enterScope('request'); + $container->set('request', new Request()); + + $content = $container->get('templating')->render('::layout.html.twig'); + $crawler = new Crawler($content); + + $this->assertEquals(3, count($crawler->filter('link[href$=".css"]'))); + $this->assertEquals(2, count($crawler->filter('script[src$=".js"]'))); + } + + public function testPhpRenderDebug() + { + $kernel = new TestKernel('test', true); + $kernel->boot(); + $container = $kernel->getContainer(); + $container->enterScope('request'); + $container->set('request', new Request()); + + $content = $container->get('templating')->render('::layout.html.php'); + $crawler = new Crawler($content); + + $this->assertEquals(3, count($crawler->filter('link[href$=".css"]'))); + $this->assertEquals(2, count($crawler->filter('script[src$=".js"]'))); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/base.html.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/base.html.php new file mode 100644 index 0000000..69a886c --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/base.html.php @@ -0,0 +1,11 @@ + + + + <?php $view['slots']->output('title') ?> + output('stylesheets') ?> + + + output('_content') ?> + output('javascripts') ?> + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/base.html.twig b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/base.html.twig new file mode 100644 index 0000000..f2d8de8 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/base.html.twig @@ -0,0 +1,11 @@ + + + + {% block title '' %} + {% block stylesheets '' %} + + + {% block content '' %} + {% block javascripts '' %} + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/layout.html.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/layout.html.php new file mode 100644 index 0000000..bd70943 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/layout.html.php @@ -0,0 +1,17 @@ +extend('::base.html.php') ?> + +start('stylesheets') ?> + stylesheets('stylesheet1.css, stylesheet2.css, @TestBundle/Resources/css/bundle.css') as $url): ?> + + +stop() ?> + +start('javascripts') ?> + javascripts('javascript1.js, javascript2.js') as $url): ?> + + +stop() ?> + +image('logo.png') as $url): ?> + + diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/layout.html.twig b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/layout.html.twig new file mode 100644 index 0000000..24cb963 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/layout.html.twig @@ -0,0 +1,19 @@ +{% extends '::base.html.twig' %} + +{% block stylesheets %} + {% stylesheets 'stylesheet1.css' 'stylesheet2.css' '@TestBundle/Resources/css/bundle.css' %} + + {% endstylesheets %} +{% endblock %} + +{% block javascripts %} + {% javascripts 'javascript1.js' 'javascript2.js' %} + + {% endjavascripts %} +{% endblock %} + +{% block content %} + {% image 'logo.png' %} + + {% endimage %} +{% endblock %} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/config/config.yml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/config/config.yml new file mode 100644 index 0000000..b43798c --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/config/config.yml @@ -0,0 +1,40 @@ +framework: + charset: UTF-8 + secret: xxxxxxxxxx + csrf_protection: + enabled: true + router: { resource: "%kernel.root_dir%/config/routing.yml" } + validation: { enabled: true, enable_annotations: true } + templating: { engines: ['twig', 'php'] } + session: + lifetime: 3600 + auto_start: false + +twig: + debug: %kernel.debug% + strict_variables: %kernel.debug% + +assetic: + use_controller: true + read_from: "%kernel.root_dir%/web" + bundles: [ TestBundle ] + assets: + jquery: js/jquery.js + app_css: + inputs: + - css/main.css + - css/more.css + - @widget_css + filters: [ ?yui_css ] + output: css/packed/app.css + widget_css: + inputs: css/widget.sass + filters: sass + filters: + sass: + apply_to: "\.sass$" + yui_css: + jar: %kernel.root_dir/java/yui-compressor-2.4.6.jar + twig: + functions: + yui_css: { output: css/*.css } diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/config/routing.yml b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/config/routing.yml new file mode 100644 index 0000000..1d36e9b --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/config/routing.yml @@ -0,0 +1,3 @@ +_assetic: + resource: . + type: assetic diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/web/javascript1.js b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/web/javascript1.js new file mode 100644 index 0000000..17f5a35 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/web/javascript1.js @@ -0,0 +1 @@ +// javascript1.js \ No newline at end of file diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/web/javascript2.js b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/web/javascript2.js new file mode 100644 index 0000000..1790420 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/web/javascript2.js @@ -0,0 +1 @@ +// javascript2.js \ No newline at end of file diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/web/stylesheet1.css b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/web/stylesheet1.css new file mode 100644 index 0000000..394efa6 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/web/stylesheet1.css @@ -0,0 +1 @@ +/* stylesheet1.css */ \ No newline at end of file diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/web/stylesheet2.css b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/web/stylesheet2.css new file mode 100644 index 0000000..fbeb02a --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Resources/web/stylesheet2.css @@ -0,0 +1 @@ +/* stylesheet2.css */ \ No newline at end of file diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Templating/AsseticHelperTest.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Templating/AsseticHelperTest.php new file mode 100644 index 0000000..fd1ed8f --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/Templating/AsseticHelperTest.php @@ -0,0 +1,56 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Tests\Templating; + +use Assetic\Asset\AssetCollection; +use Assetic\Asset\AssetInterface; +use Assetic\Asset\StringAsset; +use Assetic\Factory\AssetFactory; +use Symfony\Bundle\AsseticBundle\Templating\AsseticHelper; + +class AsseticHelperTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Assetic\\AssetManager')) { + $this->markTestSkipped('Assetic is not available.'); + } + } + + /** + * @dataProvider getDebugAndCount + */ + public function testUrls($debug, $count, $message) + { + $helper = new AsseticHelperForTest(new AssetFactory('/foo', $debug), $debug); + $urls = $helper->javascripts(array('js/jquery.js', 'js/jquery.plugin.js')); + + $this->assertInstanceOf('Traversable', $urls, '->javascripts() returns an array'); + $this->assertEquals($count, count($urls), $message); + } + + public function getDebugAndCount() + { + return array( + array(false, 1, '->javascripts() returns one url when not in debug mode'), + array(true, 2, '->javascripts() returns many urls when in debug mode'), + ); + } +} + +class AsseticHelperForTest extends AsseticHelper +{ + protected function getAssetUrl(AssetInterface $asset, $options = array()) + { + return $asset->getTargetPath(); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/TestBundle/Resources/css/bundle.css b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/TestBundle/Resources/css/bundle.css new file mode 100644 index 0000000..ab93fa7 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/TestBundle/Resources/css/bundle.css @@ -0,0 +1 @@ +/* bundle.css */ \ No newline at end of file diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/TestBundle/TestBundle.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/TestBundle/TestBundle.php new file mode 100644 index 0000000..89564c2 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/TestBundle/TestBundle.php @@ -0,0 +1,18 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Tests\TestBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class TestBundle extends Bundle +{ +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/TestKernel.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/TestKernel.php new file mode 100644 index 0000000..3f1c0a8 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/TestKernel.php @@ -0,0 +1,38 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Tests; + +use Symfony\Component\Config\Loader\LoaderInterface; +use Symfony\Component\HttpKernel\Kernel; + +class TestKernel extends Kernel +{ + public function getRootDir() + { + return __DIR__.'/Resources'; + } + + public function registerBundles() + { + return array( + new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(), + new \Symfony\Bundle\TwigBundle\TwigBundle(), + new \Symfony\Bundle\AsseticBundle\AsseticBundle(), + new \Symfony\Bundle\AsseticBundle\Tests\TestBundle\TestBundle(), + ); + } + + public function registerContainerConfiguration(LoaderInterface $loader) + { + $loader->load(__DIR__.'/Resources/config/config.yml'); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/bootstrap.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/bootstrap.php new file mode 100644 index 0000000..e7b1f84 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Tests/bootstrap.php @@ -0,0 +1,17 @@ +registerNamespace('Symfony', $_SERVER['SYMFONY']); +$loader->registerNamespace('Assetic', $_SERVER['ASSETIC']); +$loader->registerPrefix('Twig_', $_SERVER['TWIG']); +$loader->register(); + +spl_autoload_register(function($class) +{ + if (0 === strpos($class, 'Symfony\\Bundle\\AsseticBundle\\') && + file_exists($file = __DIR__.'/../'.implode('/', array_slice(explode('\\', $class), 3)).'.php')) { + require_once $file; + } +}); diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Twig/AsseticExtension.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Twig/AsseticExtension.php new file mode 100644 index 0000000..9cbec1f --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Twig/AsseticExtension.php @@ -0,0 +1,69 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Twig; + +use Assetic\ValueSupplierInterface; +use Assetic\Extension\Twig\AsseticExtension as BaseAsseticExtension; +use Assetic\Factory\AssetFactory; +use Symfony\Component\Templating\TemplateNameParserInterface; + +/** + * Assetic extension. + * + * @author Kris Wallsmith + */ +class AsseticExtension extends BaseAsseticExtension +{ + private $useController; + + public function __construct(AssetFactory $factory, TemplateNameParserInterface $templateNameParser, $useController = false, $functions = array(), $enabledBundles = array(), ValueSupplierInterface $valueSupplier = null) + { + parent::__construct($factory, $functions, $valueSupplier); + + $this->useController = $useController; + $this->templateNameParser = $templateNameParser; + $this->enabledBundles = $enabledBundles; + } + + public function getTokenParsers() + { + return array( + $this->createTokenParser('javascripts', 'js/*.js'), + $this->createTokenParser('stylesheets', 'css/*.css'), + $this->createTokenParser('image', 'images/*', true), + ); + } + + public function getNodeVisitors() + { + return array( + new AsseticNodeVisitor($this->templateNameParser, $this->enabledBundles), + ); + } + + public function getGlobals() + { + $globals = parent::getGlobals(); + $globals['assetic']['use_controller'] = $this->useController; + + return $globals; + } + + private function createTokenParser($tag, $output, $single = false) + { + $tokenParser = new AsseticTokenParser($this->factory, $tag, $output, $single, array('package')); + $tokenParser->setTemplateNameParser($this->templateNameParser); + $tokenParser->setEnabledBundles($this->enabledBundles); + + return $tokenParser; + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Twig/AsseticNode.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Twig/AsseticNode.php new file mode 100644 index 0000000..1a6a0cc --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Twig/AsseticNode.php @@ -0,0 +1,83 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Twig; + +use Assetic\Asset\AssetInterface; +use Assetic\Extension\Twig\AsseticNode as BaseAsseticNode; + +/** + * Assetic node. + * + * @author Kris Wallsmith + */ +class AsseticNode extends BaseAsseticNode +{ + protected function compileAssetUrl(\Twig_Compiler $compiler, AssetInterface $asset, $name) + { + $compiler + ->raw('isset($context[\'assetic\'][\'use_controller\']) && $context[\'assetic\'][\'use_controller\'] ? ') + ->subcompile($this->getPathFunction($name)) + ->raw(' : ') + ->subcompile($this->getAssetFunction(new TargetPathNode($this, $asset, $name))) + ; + } + + private function getPathFunction($name) + { + return new \Twig_Node_Expression_Function( + version_compare(\Twig_Environment::VERSION, '1.2.0-DEV', '<') + ? new \Twig_Node_Expression_Name('path', $this->getLine()) : 'path', + new \Twig_Node(array(new \Twig_Node_Expression_Constant('_assetic_'.$name, $this->getLine()))), + $this->getLine() + ); + } + + private function getAssetFunction($path) + { + $arguments = array($path); + + if ($this->hasAttribute('package')) { + $arguments[] = new \Twig_Node_Expression_Constant($this->getAttribute('package'), $this->getLine()); + } + + return new \Twig_Node_Expression_Function( + version_compare(\Twig_Environment::VERSION, '1.2.0-DEV', '<') + ? new \Twig_Node_Expression_Name('asset', $this->getLine()) : 'asset', + new \Twig_Node($arguments), + $this->getLine() + ); + } +} + +class TargetPathNode extends AsseticNode +{ + private $node; + private $asset; + private $name; + + public function __construct(AsseticNode $node, AssetInterface $asset, $name) + { + $this->node = $node; + $this->asset = $asset; + $this->name = $name; + } + + public function compile(\Twig_Compiler $compiler) + { + BaseAsseticNode::compileAssetUrl($compiler, $this->asset, $this->name); + } + + public function getLine() + { + return $this->node->getLine(); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Twig/AsseticNodeVisitor.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Twig/AsseticNodeVisitor.php new file mode 100644 index 0000000..9dc7d7b --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Twig/AsseticNodeVisitor.php @@ -0,0 +1,120 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Twig; + +use Assetic\Extension\Twig\AsseticFilterFunction; +use Symfony\Bundle\AsseticBundle\Exception\InvalidBundleException; +use Symfony\Component\Templating\TemplateNameParserInterface; + +/** + * Assetic node visitor. + * + * @author Kris Wallsmith + */ +class AsseticNodeVisitor implements \Twig_NodeVisitorInterface +{ + private $templateNameParser; + private $enabledBundles; + private $useNodeName; + + public function __construct(TemplateNameParserInterface $templateNameParser, array $enabledBundles) + { + $this->templateNameParser = $templateNameParser; + $this->enabledBundles = $enabledBundles; + + $this->useNodeName = version_compare(\Twig_Environment::VERSION, '1.2.0-DEV', '<'); + } + + public function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env) + { + return $node; + } + + public function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env) + { + if (!$formula = $this->checkNode($node, $env, $name)) { + return $node; + } + + // check the bundle + $templateRef = $this->templateNameParser->parse($env->getParser()->getStream()->getFilename()); + $bundle = $templateRef->get('bundle'); + if ($bundle && !in_array($bundle, $this->enabledBundles)) { + throw new InvalidBundleException($bundle, "the $name() function", $templateRef->getLogicalName(), $this->enabledBundles); + } + + list($input, $filters, $options) = $formula; + $line = $node->getLine(); + + // check context and call either asset() or path() + return new \Twig_Node_Expression_Conditional( + new \Twig_Node_Expression_GetAttr( + new \Twig_Node_Expression_Name('assetic', $line), + new \Twig_Node_Expression_Constant('use_controller', $line), + new \Twig_Node(), + \Twig_TemplateInterface::ARRAY_CALL, + $line + ), + new \Twig_Node_Expression_Function( + $this->useNodeName ? new \Twig_Node_Expression_Name('path', $line) : 'path', + new \Twig_Node(array( + new \Twig_Node_Expression_Constant('_assetic_'.$options['name'], $line), + )), + $line + ), + new \Twig_Node_Expression_Function( + $this->useNodeName ? new \Twig_Node_Expression_Name('asset', $line) : 'asset', + new \Twig_Node(array($node, new \Twig_Node_Expression_Constant(isset($options['package']) ? $options['package'] : null, $line))), + $line + ), + $line + ); + } + + /** + * Extracts formulae from filter function nodes. + * + * @return array|null The formula + */ + private function checkNode(\Twig_NodeInterface $node, \Twig_Environment $env, & $name = null) + { + if ($node instanceof \Twig_Node_Expression_Function) { + $name = $this->useNodeName + ? $node->getNode('name')->getAttribute('name') + : $node->getAttribute('name'); + if ($env->getFunction($name) instanceof AsseticFilterFunction) { + $arguments = array(); + foreach ($node->getNode('arguments') as $argument) { + $arguments[] = eval('return '.$env->compile($argument).';'); + } + + $invoker = $env->getExtension('assetic')->getFilterInvoker($name); + $factory = $invoker->getFactory(); + + $inputs = isset($arguments[0]) ? (array) $arguments[0] : array(); + $filters = $invoker->getFilters(); + $options = array_replace($invoker->getOptions(), isset($arguments[1]) ? $arguments[1] : array()); + + if (!isset($options['name'])) { + $options['name'] = $factory->generateAssetName($inputs, $filters); + } + + return array($inputs, $filters, $options); + } + } + } + + public function getPriority() + { + return 0; + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Twig/AsseticTokenParser.php b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Twig/AsseticTokenParser.php new file mode 100644 index 0000000..2a10fc9 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/Twig/AsseticTokenParser.php @@ -0,0 +1,66 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Twig; + +use Assetic\Asset\AssetInterface; +use Assetic\Extension\Twig\AsseticTokenParser as BaseAsseticTokenParser; +use Symfony\Bundle\AsseticBundle\Exception\InvalidBundleException; +use Symfony\Component\Templating\TemplateNameParserInterface; + +/** + * Assetic token parser. + * + * @author Kris Wallsmith + */ +class AsseticTokenParser extends BaseAsseticTokenParser +{ + private $templateNameParser; + private $enabledBundles; + + public function setTemplateNameParser(TemplateNameParserInterface $templateNameParser) + { + $this->templateNameParser = $templateNameParser; + } + + public function setEnabledBundles(array $enabledBundles = null) + { + $this->enabledBundles = $enabledBundles; + } + + public function parse(\Twig_Token $token) + { + if ($this->templateNameParser && is_array($this->enabledBundles)) { + // check the bundle + $templateRef = null; + try { + $templateRef = $this->templateNameParser->parse($this->parser->getStream()->getFilename()); + } catch (\RuntimeException $e) { + // this happens when the filename isn't a Bundle:* url + // and it contains ".." + } catch (\InvalidArgumentException $e) { + // this happens when the filename isn't a Bundle:* url + // but an absolute path instead + } + $bundle = $templateRef ? $templateRef->get('bundle') : null; + if ($bundle && !in_array($bundle, $this->enabledBundles)) { + throw new InvalidBundleException($bundle, "the {% {$this->getTag()} %} tag", $templateRef->getLogicalName(), $this->enabledBundles); + } + } + + return parent::parse($token); + } + + protected function createNode(AssetInterface $asset, \Twig_NodeInterface $body, array $inputs, array $filters, $name, array $attributes = array(), $lineno = 0, $tag = null) + { + return new AsseticNode($asset, $body, $inputs, $filters, $name, $attributes, $lineno, $tag); + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/UPGRADE.md b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/UPGRADE.md new file mode 100644 index 0000000..a61e131 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/UPGRADE.md @@ -0,0 +1,10 @@ +Changes in version 2.1 +---------------------- + + * Friendlier exception message when using Assetic in a bundle that Assetic + has not been configured to scan + * Assets are no longer dumped to the filesystem when `cache:warmup` is run. + This can only be done using the `assetic:dump` command + * Added support for GSS filter + * Assetic's routes are now automatically added when `use_controller` is + `true` diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/composer.json b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/composer.json new file mode 100644 index 0000000..15c8bdc --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/composer.json @@ -0,0 +1,33 @@ +{ + "name": "symfony/assetic-bundle", + "version": "2.1.0", + "description": "Integrates Assetic into Symfony2", + "keywords": ["assets", "compression", "minification"], + "homepage": "https://github.com/symfony/AsseticBundle", + "type": "symfony-bundle", + "license": "MIT", + "authors": [ + { + "name": "Kris Wallsmith", + "email": "kris.wallsmith@gmail.com", + "homepage": "http://kriswallsmith.net/" + } + ], + "require": { + "php": ">=5.3.0", + "symfony/framework-bundle": "2.1.*", + "kriswallsmith/assetic": "1.1.*" + }, + "suggest": { + "symfony/twig-bundle": "2.1.*" + }, + "autoload": { + "psr-0": { "Symfony\\Bundle\\AsseticBundle": "" } + }, + "target-dir": "Symfony/Bundle/AsseticBundle", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + } +} diff --git a/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/phpunit.xml.dist b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/phpunit.xml.dist new file mode 100644 index 0000000..9e0e4c9 --- /dev/null +++ b/vendor/symfony/assetic-bundle/Symfony/Bundle/AsseticBundle/phpunit.xml.dist @@ -0,0 +1,35 @@ + + + + + + ./Tests/ + + + + + + + + + + + + ./ + + ./Resources + ./Tests + + + + diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/.travis.yml b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/.travis.yml new file mode 100644 index 0000000..39a0efe --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/.travis.yml @@ -0,0 +1,9 @@ +language: php + +php: + - 5.3 + - 5.4 + +before_script: + - curl -s http://getcomposer.org/installer | php + - php composer.phar install --dev diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/AddProcessorsPass.php b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/AddProcessorsPass.php new file mode 100644 index 0000000..21b51a9 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/AddProcessorsPass.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\Bundle\MonologBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Registers processors in Monolog loggers or handlers. + * + * @author Christophe Coevoet + */ +class AddProcessorsPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('monolog.logger')) { + return; + } + + foreach ($container->findTaggedServiceIds('monolog.processor') as $id => $tags) { + foreach ($tags as $tag) { + if (!empty($tag['channel']) && !empty($tag['handler'])) { + throw new \InvalidArgumentException(sprintf('you cannot specify both the "handler" and "channel" attributes for the "monolog.processor" tag on service "%s"', $id)); + } + + if (!empty($tag['handler'])) { + $definition = $container->findDefinition(sprintf('monolog.handler.%s', $tag['handler'])); + } elseif (!empty($tag['channel'])) { + if ('app' === $tag['channel']) { + $definition = $container->getDefinition('monolog.logger'); + } else { + $definition = $container->getDefinition(sprintf('monolog.logger.%s', $tag['channel'])); + } + } else { + $definition = $container->getDefinition('monolog.logger_prototype'); + } + + if (!empty($tag['method'])) { + $processor = array(new Reference($id), $tag['method']); + } else { + // If no method is defined, fallback to use __invoke + $processor = new Reference($id); + } + $definition->addMethodCall('pushProcessor', array($processor)); + } + } + } +} diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/DebugHandlerPass.php b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/DebugHandlerPass.php new file mode 100644 index 0000000..6bb67c5 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/DebugHandlerPass.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\Bundle\MonologBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Definition; +use Monolog\Logger; + +/** + * Adds the DebugHandler when the profiler is enabled. + * + * @author Christophe Coevoet + */ +class DebugHandlerPass implements CompilerPassInterface +{ + private $channelPass; + + public function __construct(LoggerChannelPass $channelPass) + { + $this->channelPass = $channelPass; + } + + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('profiler')) { + return; + } + + $debugHandler = new Definition('%monolog.handler.debug.class%', array(Logger::DEBUG, true)); + $container->setDefinition('monolog.handler.debug', $debugHandler); + + foreach ($this->channelPass->getChannels() as $channel) { + $container + ->getDefinition($channel === 'app' ? 'monolog.logger' : 'monolog.logger.'.$channel) + ->addMethodCall('pushHandler', array(new Reference('monolog.handler.debug'))); + } + } +} diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/LoggerChannelPass.php b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/LoggerChannelPass.php new file mode 100644 index 0000000..030a87f --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/LoggerChannelPass.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\Bundle\MonologBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * Replaces the default logger by another one with its own channel for tagged services. + * + * @author Christophe Coevoet + */ +class LoggerChannelPass implements CompilerPassInterface +{ + protected $channels = array('app'); + + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('monolog.logger')) { + return; + } + + foreach ($container->findTaggedServiceIds('monolog.logger') as $id => $tags) { + foreach ($tags as $tag) { + if (empty($tag['channel']) || 'app' === $tag['channel']) { + continue; + } + + $definition = $container->getDefinition($id); + $loggerId = sprintf('monolog.logger.%s', $tag['channel']); + $this->createLogger($tag['channel'], $loggerId, $container); + + foreach ($definition->getArguments() as $index => $argument) { + if ($argument instanceof Reference && 'logger' === (string) $argument) { + $definition->replaceArgument($index, new Reference($loggerId, $argument->getInvalidBehavior(), $argument->isStrict())); + } + } + + $calls = $definition->getMethodCalls(); + foreach ($calls as $i => $call) { + foreach ($call[1] as $index => $argument) { + if ($argument instanceof Reference && 'logger' === (string) $argument) { + $calls[$i][1][$index] = new Reference($loggerId, $argument->getInvalidBehavior(), $argument->isStrict()); + } + } + } + $definition->setMethodCalls($calls); + } + } + + $handlersToChannels = $container->getParameter('monolog.handlers_to_channels'); + + foreach ($handlersToChannels as $handler => $channels) { + foreach ($this->processChannels($channels) as $channel) { + try { + $logger = $container->getDefinition($channel === 'app' ? 'monolog.logger' : 'monolog.logger.'.$channel); + } catch (InvalidArgumentException $e) { + $msg = 'Monolog configuration error: The logging channel "'.$channel.'" assigned to the "'.substr($handler, 16).'" handler does not exist.'; + throw new \InvalidArgumentException($msg, 0, $e); + } + $logger->addMethodCall('pushHandler', array(new Reference($handler))); + } + } + } + + public function getChannels() + { + return $this->channels; + } + + protected function processChannels($configuration) + { + if (null === $configuration) { + return $this->channels; + } + + if ('inclusive' === $configuration['type']) { + return $configuration['elements']; + } + + return array_diff($this->channels, $configuration['elements']); + } + + protected function createLogger($channel, $loggerId, ContainerBuilder $container) + { + if (!in_array($channel, $this->channels)) { + $logger = new DefinitionDecorator('monolog.logger_prototype'); + $logger->replaceArgument(0, $channel); + $container->setDefinition($loggerId, $logger); + $this->channels[] = $channel; + } + } +} diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/DependencyInjection/Configuration.php b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/DependencyInjection/Configuration.php new file mode 100644 index 0000000..57a0420 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/DependencyInjection/Configuration.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\Bundle\MonologBundle\DependencyInjection; + +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; +use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; + +/** + * This class contains the configuration information for the bundle + * + * This information is solely responsible for how the different configuration + * sections are normalized, and merged. + * + * @author Jordi Boggiano + * @author Christophe Coevoet + */ +class Configuration implements ConfigurationInterface +{ + /** + * Generates the configuration tree builder. + * + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder + */ + public function getConfigTreeBuilder() + { + $treeBuilder = new TreeBuilder(); + $rootNode = $treeBuilder->root('monolog'); + + $rootNode + ->fixXmlConfig('handler') + ->children() + ->arrayNode('handlers') + ->canBeUnset() + ->useAttributeAsKey('name') + ->prototype('array') + ->fixXmlConfig('member') + ->canBeUnset() + ->children() + ->scalarNode('type') + ->isRequired() + ->treatNullLike('null') + ->beforeNormalization() + ->always() + ->then(function($v) { return strtolower($v); }) + ->end() + ->end() + ->scalarNode('id')->end() + ->scalarNode('priority')->defaultValue(0)->end() + ->scalarNode('level')->defaultValue('DEBUG')->end() + ->booleanNode('bubble')->defaultTrue()->end() + ->scalarNode('path')->defaultValue('%kernel.logs_dir%/%kernel.environment%.log')->end() // stream and rotating + ->scalarNode('ident')->defaultFalse()->end() // syslog + ->scalarNode('facility')->defaultValue('user')->end() // syslog + ->scalarNode('max_files')->defaultValue(0)->end() // rotating + ->scalarNode('action_level')->defaultValue('WARNING')->end() // fingers_crossed + ->scalarNode('activation_strategy')->defaultNull()->end() // fingers_crossed + ->booleanNode('stop_buffering')->defaultTrue()->end()// fingers_crossed + ->scalarNode('buffer_size')->defaultValue(0)->end() // fingers_crossed and buffer + ->scalarNode('handler')->end() // fingers_crossed and buffer + ->arrayNode('publisher') + ->canBeUnset() + ->beforeNormalization() + ->ifString() + ->then(function($v) { return array('id'=> $v); }) + ->end() + ->children() + ->scalarNode('id')->end() + ->scalarNode('hostname')->end() + ->scalarNode('port')->defaultValue(12201)->end() + ->scalarNode('chunk_size')->defaultValue(1420)->end() + ->end() + ->validate() + ->ifTrue(function($v) { + return !isset($v['id']) && !isset($v['hostname']); + }) + ->thenInvalid('What must be set is either the hostname or the id.') + ->end() + ->end() // gelf + ->arrayNode('members') // group + ->canBeUnset() + ->performNoDeepMerging() + ->prototype('scalar')->end() + ->end() + ->scalarNode('from_email')->end() // swift_mailer and native_mailer + ->scalarNode('to_email')->end() // swift_mailer and native_mailer + ->scalarNode('subject')->end() // swift_mailer and native_mailer + ->arrayNode('email_prototype') // swift_mailer + ->canBeUnset() + ->beforeNormalization() + ->ifString() + ->then(function($v) { return array('id' => $v); }) + ->end() + ->children() + ->scalarNode('id')->isRequired()->end() + ->scalarNode('factory-method')->defaultNull()->end() + ->end() + ->end() + ->arrayNode('channels') + ->fixXmlConfig('channel', 'elements') + ->canBeUnset() + ->beforeNormalization() + ->ifString() + ->then(function($v) { return array('elements' => array($v)); }) + ->end() + ->beforeNormalization() + ->ifTrue(function($v) { return is_array($v) && is_numeric(key($v)); }) + ->then(function($v) { return array('elements' => $v); }) + ->end() + ->validate() + ->ifTrue(function($v) { return empty($v); }) + ->thenUnset() + ->end() + ->validate() + ->always(function ($v) { + $isExclusive = null; + if (isset($v['type'])) { + $isExclusive = 'exclusive' === $v['type']; + } + + $elements = array(); + foreach ($v['elements'] as $element) { + if (0 === strpos($element, '!')) { + if (false === $isExclusive) { + throw new InvalidConfigurationException('Cannot combine exclusive/inclusive definitions in channels list.'); + } + $elements[] = substr($element, 1); + $isExclusive = true; + } else { + if (true === $isExclusive) { + throw new InvalidConfigurationException('Cannot combine exclusive/inclusive definitions in channels list'); + } + $elements[] = $element; + $isExclusive = false; + } + } + + return array('type' => $isExclusive ? 'exclusive' : 'inclusive', 'elements' => $elements); + }) + ->end() + ->children() + ->scalarNode('type') + ->validate() + ->ifNotInArray(array('inclusive', 'exclusive')) + ->thenInvalid('The type of channels has to be inclusive or exclusive') + ->end() + ->end() + ->arrayNode('elements') + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + ->scalarNode('formatter')->end() + ->end() + ->validate() + ->ifTrue(function($v) { return ('fingers_crossed' === $v['type'] || 'buffer' === $v['type']) && 1 !== count($v['handler']); }) + ->thenInvalid('The handler has to be specified to use a FingersCrossedHandler or BufferHandler') + ->end() + ->validate() + ->ifTrue(function($v) { return 'swift_mailer' === $v['type'] && empty($v['email_prototype']) && (empty($v['from_email']) || empty($v['to_email']) || empty($v['subject'])); }) + ->thenInvalid('The sender, recipient and subject or an email prototype have to be specified to use a SwiftMailerHandler') + ->end() + ->validate() + ->ifTrue(function($v) { return 'native_mailer' === $v['type'] && (empty($v['from_email']) || empty($v['to_email']) || empty($v['subject'])); }) + ->thenInvalid('The sender, recipient and subject have to be specified to use a NativeMailerHandler') + ->end() + ->validate() + ->ifTrue(function($v) { return 'service' === $v['type'] && !isset($v['id']); }) + ->thenInvalid('The id has to be specified to use a service as handler') + ->end() + ->validate() + ->ifTrue(function($v) { return 'gelf' === $v['type'] && !isset($v['publisher']); }) + ->thenInvalid('The publisher has to be specified to use a GelfHandler') + ->end() + ->end() + ->validate() + ->ifTrue(function($v) { return isset($v['debug']); }) + ->thenInvalid('The "debug" name cannot be used as it is reserved for the handler of the profiler') + ->end() + ->example(array( + 'syslog' => array( + 'type' => 'stream', + 'path' => '/var/log/symfony.log', + 'level' => 'ERROR', + 'bubble' => 'false', + 'formatter' => 'my_formatter', + 'processors' => array('some_callable') + ), + 'main' => array( + 'type' => 'fingers_crossed', + 'action_level' => 'WARNING', + 'buffer_size' => 30, + 'handler' => 'custom', + ), + 'custom' => array( + 'type' => 'service', + 'id' => 'my_handler' + ) + )) + ->end() + ->end() + ; + + return $treeBuilder; + } +} diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/DependencyInjection/MonologExtension.php b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/DependencyInjection/MonologExtension.php new file mode 100644 index 0000000..5636a84 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/DependencyInjection/MonologExtension.php @@ -0,0 +1,289 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\MonologBundle\DependencyInjection; + +use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +/** + * MonologExtension is an extension for the Monolog library. + * + * @author Jordi Boggiano + * @author Christophe Coevoet + */ +class MonologExtension extends Extension +{ + private $nestedHandlers = array(); + + /** + * Loads the Monolog configuration. + * + * @param array $configs An array of configuration settings + * @param ContainerBuilder $container A ContainerBuilder instance + */ + public function load(array $configs, ContainerBuilder $container) + { + $configuration = $this->getConfiguration($configs, $container); + $config = $this->processConfiguration($configuration, $configs); + + if (isset($config['handlers'])) { + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('monolog.xml'); + $container->setAlias('logger', 'monolog.logger'); + + $handlers = array(); + + foreach ($config['handlers'] as $name => $handler) { + $handlers[] = array( + 'id' => $this->buildHandler($container, $name, $handler), + 'priority' => $handler['priority'], + 'channels' => isset($handler['channels']) ? $handler['channels'] : null + ); + } + + $handlers = array_reverse($handlers); + uasort($handlers, function($a, $b) { + if ($a['priority'] == $b['priority']) { + return 0; + } + + return $a['priority'] < $b['priority'] ? -1 : 1; + }); + $handlersToChannels = array(); + foreach ($handlers as $handler) { + if (!in_array($handler['id'], $this->nestedHandlers)) { + $handlersToChannels[$handler['id']] = $handler['channels']; + } + } + $container->setParameter('monolog.handlers_to_channels', $handlersToChannels); + + $this->addClassesToCompile(array( + 'Monolog\\Formatter\\FormatterInterface', + 'Monolog\\Formatter\\LineFormatter', + 'Monolog\\Handler\\HandlerInterface', + 'Monolog\\Handler\\AbstractHandler', + 'Monolog\\Handler\\AbstractProcessingHandler', + 'Monolog\\Handler\\StreamHandler', + 'Monolog\\Handler\\FingersCrossedHandler', + 'Monolog\\Handler\\TestHandler', + 'Monolog\\Logger', + 'Symfony\\Bridge\\Monolog\\Logger', + 'Symfony\\Bridge\\Monolog\\Handler\\DebugHandler', + )); + } + } + + /** + * Returns the base path for the XSD files. + * + * @return string The XSD base path + */ + public function getXsdValidationBasePath() + { + return __DIR__.'/../Resources/config/schema'; + } + + public function getNamespace() + { + return 'http://symfony.com/schema/dic/monolog'; + } + + private function buildHandler(ContainerBuilder $container, $name, array $handler) + { + $handlerId = $this->getHandlerId($name); + $definition = new Definition(sprintf('%%monolog.handler.%s.class%%', $handler['type'])); + $handler['level'] = is_int($handler['level']) ? $handler['level'] : constant('Monolog\Logger::'.strtoupper($handler['level'])); + + switch ($handler['type']) { + case 'service': + $container->setAlias($handlerId, $handler['id']); + + return $handlerId; + + case 'stream': + $definition->setArguments(array( + $handler['path'], + $handler['level'], + $handler['bubble'], + )); + break; + + case 'firephp': + $definition->setArguments(array( + $handler['level'], + $handler['bubble'], + )); + $definition->addTag('kernel.event_listener', array('event' => 'kernel.response', 'method' => 'onKernelResponse')); + break; + + case 'gelf': + if (isset($handler['publisher']['id'])) { + $publisherId = $handler['publisher']['id']; + } else { + $publisher = new Definition("%monolog.gelf.publisher.class%", array( + $handler['publisher']['hostname'], + $handler['publisher']['port'], + $handler['publisher']['chunk_size'], + )); + + $publisherId = 'monolog.gelf.publisher'; + $publisher->setPublic(false); + $container->setDefinition($publisherId, $publisher); + } + + $definition->setArguments(array( + new Reference($publisherId), + $handler['level'], + $handler['bubble'], + )); + break; + + case 'chromephp': + $definition->setArguments(array( + $handler['level'], + $handler['bubble'], + )); + $definition->addTag('kernel.event_listener', array('event' => 'kernel.response', 'method' => 'onKernelResponse')); + break; + + case 'rotating_file': + $definition->setArguments(array( + $handler['path'], + $handler['max_files'], + $handler['level'], + $handler['bubble'], + )); + break; + + case 'fingers_crossed': + $handler['action_level'] = is_int($handler['action_level']) ? $handler['action_level'] : constant('Monolog\Logger::'.strtoupper($handler['action_level'])); + $nestedHandlerId = $this->getHandlerId($handler['handler']); + $this->nestedHandlers[] = $nestedHandlerId; + + if (isset($handler['activation_strategy'])) { + $activation = new Reference($handler['activation_strategy']); + } else { + $activation = $handler['action_level']; + } + + $definition->setArguments(array( + new Reference($nestedHandlerId), + $activation, + $handler['buffer_size'], + $handler['bubble'], + $handler['stop_buffering'], + )); + break; + + case 'buffer': + $nestedHandlerId = $this->getHandlerId($handler['handler']); + $this->nestedHandlers[] = $nestedHandlerId; + + $definition->setArguments(array( + new Reference($nestedHandlerId), + $handler['buffer_size'], + $handler['level'], + $handler['bubble'], + )); + break; + + case 'group': + $references = array(); + foreach ($handler['members'] as $nestedHandler) { + $nestedHandlerId = $this->getHandlerId($nestedHandler); + $this->nestedHandlers[] = $nestedHandlerId; + $references[] = new Reference($nestedHandlerId); + } + + $definition->setArguments(array( + $references, + $handler['bubble'], + )); + break; + + case 'syslog': + $definition->setArguments(array( + $handler['ident'], + $handler['facility'], + $handler['level'], + $handler['bubble'], + )); + break; + + case 'swift_mailer': + if (isset($handler['email_prototype'])) { + if (!empty($handler['email_prototype']['method'])) { + $prototype = array(new Reference($handler['email_prototype']['id']), $handler['email_prototype']['method']); + } else { + $prototype = new Reference($handler['email_prototype']['id']); + } + } else { + $message = new Definition('Swift_Message'); + $message->setFactoryService('mailer'); + $message->setFactoryMethod('createMessage'); + $message->setPublic(false); + $message->addMethodCall('setFrom', array($handler['from_email'])); + $message->addMethodCall('setTo', array($handler['to_email'])); + $message->addMethodCall('setSubject', array($handler['subject'])); + $messageId = sprintf('%s.mail_prototype', $handlerId); + $container->setDefinition($messageId, $message); + $prototype = new Reference($messageId); + } + $definition->setArguments(array( + new Reference('mailer'), + $prototype, + $handler['level'], + $handler['bubble'], + )); + break; + + case 'native_mailer': + $definition->setArguments(array( + $handler['to_email'], + $handler['subject'], + $handler['from_email'], + $handler['level'], + $handler['bubble'], + )); + break; + + // Handlers using the constructor of AbstractHandler without adding their own arguments + case 'test': + case 'null': + case 'debug': + $definition->setArguments(array( + $handler['level'], + $handler['bubble'], + )); + break; + + default: + throw new \InvalidArgumentException(sprintf('Invalid handler type "%s" given for handler "%s"', $handler['type'], $name)); + } + + if (!empty($handler['formatter'])) { + $definition->addMethodCall('setFormatter', array(new Reference($handler['formatter']))); + } + $container->setDefinition($handlerId, $definition); + + return $handlerId; + } + + private function getHandlerId($name) + { + return sprintf('monolog.handler.%s', $name); + } +} diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/LICENSE b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/LICENSE new file mode 100644 index 0000000..cdffe7a --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 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/monolog-bundle/Symfony/Bundle/MonologBundle/MonologBundle.php b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/MonologBundle.php new file mode 100644 index 0000000..482f135 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/MonologBundle.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\Bundle\MonologBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\LoggerChannelPass; +use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\DebugHandlerPass; +use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\AddProcessorsPass; + +/** + * Bundle. + * + * @author Jordi Boggiano + */ +class MonologBundle extends Bundle +{ + public function build(ContainerBuilder $container) + { + parent::build($container); + + $container->addCompilerPass($channelPass = new LoggerChannelPass()); + $container->addCompilerPass(new DebugHandlerPass($channelPass)); + $container->addCompilerPass(new AddProcessorsPass()); + } +} diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Resources/config/monolog.xml b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Resources/config/monolog.xml new file mode 100644 index 0000000..5e76780 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Resources/config/monolog.xml @@ -0,0 +1,39 @@ + + + + + + Symfony\Bridge\Monolog\Logger + Gelf\MessagePublisher + Monolog\Handler\StreamHandler + Monolog\Handler\GroupHandler + Monolog\Handler\BufferHandler + Monolog\Handler\RotatingFileHandler + Monolog\Handler\SyslogHandler + Monolog\Handler\NullHandler + Monolog\Handler\TestHandler + Monolog\Handler\GelfHandler + Symfony\Bridge\Monolog\Handler\FirePHPHandler + Symfony\Bridge\Monolog\Handler\ChromePhpHandler + Symfony\Bridge\Monolog\Handler\DebugHandler + Monolog\Handler\SwiftMailerHandler + Monolog\Handler\NativeMailerHandler + + Monolog\Handler\FingersCrossedHandler + Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy + + + + + app + + + + + + + + + diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Resources/config/schema/monolog-1.0.xsd b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Resources/config/schema/monolog-1.0.xsd new file mode 100644 index 0000000..aeba3a3 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Resources/config/schema/monolog-1.0.xsd @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Compiler/AddProcessorsPassTest.php b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Compiler/AddProcessorsPassTest.php new file mode 100644 index 0000000..99374b1 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Compiler/AddProcessorsPassTest.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\Bundle\MonologBundle\Tests\DependencyInjection\Compiler; + +use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\AddProcessorsPass; +use Symfony\Bundle\MonologBundle\Tests\TestCase; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; + +class AddProcessorsPassTest extends TestCase +{ + public function testHandlerProcessors() + { + $container = $this->getContainer(); + + $service = $container->getDefinition('monolog.handler.test'); + $calls = $service->getMethodCalls(); + $this->assertCount(1, $calls); + $this->assertEquals(array('pushProcessor', array(new Reference('test'))), $calls[0]); + + $service = $container->getDefinition('handler_test'); + $calls = $service->getMethodCalls(); + $this->assertCount(1, $calls); + $this->assertEquals(array('pushProcessor', array(new Reference('test2'))), $calls[0]); + } + + protected function getContainer() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../../../Resources/config')); + $loader->load('monolog.xml'); + + $definition = $container->getDefinition('monolog.logger_prototype'); + $container->setDefinition('monolog.handler.test', new Definition('%monolog.handler.null.class%', array (100, false))); + $container->setDefinition('handler_test', new Definition('%monolog.handler.null.class%', array (100, false))); + $container->setAlias('monolog.handler.test2', 'handler_test'); + $definition->addMethodCall('pushHandler', array(new Reference('monolog.handler.test'))); + $definition->addMethodCall('pushHandler', array(new Reference('monolog.handler.test2'))); + + $service = new Definition('TestClass', array('false', new Reference('logger'))); + $service->addTag('monolog.processor', array ('handler' => 'test')); + $container->setDefinition('test', $service); + + $service = new Definition('TestClass', array('false', new Reference('logger'))); + $service->addTag('monolog.processor', array ('handler' => 'test2')); + $container->setDefinition('test2', $service); + + $container->getCompilerPassConfig()->setOptimizationPasses(array()); + $container->getCompilerPassConfig()->setRemovingPasses(array()); + $container->addCompilerPass(new AddProcessorsPass()); + $container->compile(); + + return $container; + } +} diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Compiler/LoggerChannelPassTest.php b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Compiler/LoggerChannelPassTest.php new file mode 100644 index 0000000..e6b670e --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Compiler/LoggerChannelPassTest.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\Bundle\MonologBundle\Tests\DependencyInjection\Compiler; + +use Symfony\Bundle\MonologBundle\Tests\TestCase; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\LoggerChannelPass; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; + +class LoggerChannelPassTest extends TestCase +{ + public function testProcess() + { + $container = $this->getContainer(); + $this->assertTrue($container->hasDefinition('monolog.logger.test'), '->process adds a logger service for tagged service'); + + $service = $container->getDefinition('test'); + $this->assertEquals('monolog.logger.test', (string) $service->getArgument(1), '->process replaces the logger by the new one'); + + + // pushHandlers for service "test" + $expected = array( + 'test' => array('monolog.handler.a', 'monolog.handler.b', 'monolog.handler.c'), + 'foo' => array('monolog.handler.b'), + 'bar' => array('monolog.handler.b', 'monolog.handler.c'), + ); + + foreach ($expected as $serviceName => $handlers) { + $service = $container->getDefinition($serviceName); + $channel = $container->getDefinition((string) $service->getArgument(1)); + + $calls = $channel->getMethodCalls(); + $this->assertCount(count($handlers), $calls); + foreach ($handlers as $i => $handler) { + list($methodName, $arguments) = $calls[$i]; + $this->assertEquals('pushHandler', $methodName); + $this->assertCount(1, $arguments); + $this->assertEquals($handler, (string) $arguments[0]); + } + } + } + + public function testProcessSetters() + { + $container = $this->getContainerWithSetter(); + $this->assertTrue($container->hasDefinition('monolog.logger.test'), '->process adds a logger service for tagged service'); + + $service = $container->getDefinition('foo'); + $calls = $service->getMethodCalls(); + $this->assertEquals('monolog.logger.test', (string) $calls[0][1][0], '->process replaces the logger by the new one in setters'); + } + + protected function getContainer() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../../../Resources/config')); + $loader->load('monolog.xml'); + $definition = $container->getDefinition('monolog.logger_prototype'); + $container->set('monolog.handler.test', new Definition('%monolog.handler.null.class%', array (100, false))); + $definition->addMethodCall('pushHandler', array(new Reference('monolog.handler.test'))); + + // Handlers + $container->set('monolog.handler.a', new Definition('%monolog.handler.null.class%', array (100, false))); + $container->set('monolog.handler.b', new Definition('%monolog.handler.null.class%', array (100, false))); + $container->set('monolog.handler.c', new Definition('%monolog.handler.null.class%', array (100, false))); + + // Channels + foreach (array('test', 'foo', 'bar') as $name) { + $service = new Definition('TestClass', array('false', new Reference('logger'))); + $service->addTag('monolog.logger', array ('channel' => $name)); + $container->setDefinition($name, $service); + } + + $container->setParameter('monolog.handlers_to_channels', array( + 'monolog.handler.a' => array( + 'type' => 'inclusive', + 'elements' => array('test') + ), + 'monolog.handler.b' => null, + 'monolog.handler.c' => array( + 'type' => 'exclusive', + 'elements' => array('foo') + ) + )); + + $container->getCompilerPassConfig()->setOptimizationPasses(array()); + $container->getCompilerPassConfig()->setRemovingPasses(array()); + $container->addCompilerPass(new LoggerChannelPass()); + $container->compile(); + + return $container; + } + + protected function getContainerWithSetter() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../../../Resources/config')); + $loader->load('monolog.xml'); + $definition = $container->getDefinition('monolog.logger_prototype'); + $container->set('monolog.handler.test', new Definition('%monolog.handler.null.class%', array (100, false))); + $definition->addMethodCall('pushHandler', array(new Reference('monolog.handler.test'))); + + // Channels + $service = new Definition('TestClass'); + $service->addTag('monolog.logger', array ('channel' => 'test')); + $service->addMethodCall('setLogger', array(new Reference('logger'))); + $container->setDefinition('foo', $service); + + $container->setParameter('monolog.handlers_to_channels', array()); + + $container->getCompilerPassConfig()->setOptimizationPasses(array()); + $container->getCompilerPassConfig()->setRemovingPasses(array()); + $container->addCompilerPass(new LoggerChannelPass()); + $container->compile(); + + return $container; + } +} diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/ConfigurationTest.php b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/ConfigurationTest.php new file mode 100644 index 0000000..a01bc70 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/ConfigurationTest.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\Bundle\MonologBundle\Tests\DependencyInjection; + +use Symfony\Bundle\MonologBundle\DependencyInjection\Configuration; +use Symfony\Component\Config\Definition\Processor; + +class ConfigurationTest extends \PHPUnit_Framework_TestCase +{ + /** + * Some basic tests to make sure the configuration is correctly processed in + * the standard case. + */ + public function testProcessSimpleCase() + { + $configs = array( + array( + 'handlers' => array('foobar' => array('type' => 'stream', 'path' => '/foo/bar')) + ) + ); + + $config = $this->process($configs); + + $this->assertArrayHasKey('handlers', $config); + $this->assertArrayHasKey('foobar', $config['handlers']); + $this->assertEquals('stream', $config['handlers']['foobar']['type']); + $this->assertEquals('/foo/bar', $config['handlers']['foobar']['path']); + } + + public function provideProcessStringChannels() + { + return array( + array('foo', 'foo', true), + array('!foo', 'foo', false) + ); + } + + /** + * @dataProvider provideProcessStringChannels + */ + public function testProcessStringChannels($string, $expectedString, $isInclusive) + { + $configs = array( + array( + 'handlers' => array( + 'foobar' => array( + 'type' => 'stream', + 'path' => '/foo/bar', + 'channels' => $string + ) + ) + ) + ); + + $config = $this->process($configs); + + $this->assertEquals($isInclusive ? 'inclusive' : 'exclusive', $config['handlers']['foobar']['channels']['type']); + $this->assertCount(1, $config['handlers']['foobar']['channels']['elements']); + $this->assertEquals($expectedString, $config['handlers']['foobar']['channels']['elements'][0]); + } + + public function provideGelfPublisher() + { + return array( + array( + 'gelf.publisher' + ), + array( + array( + 'id' => 'gelf.publisher' + ) + ) + ); + } + + /** + * @dataProvider provideGelfPublisher + */ + public function testGelfPublisherService($publisher) + { + $configs = array( + array( + 'handlers' => array( + 'gelf' => array( + 'type' => 'gelf', + 'publisher' => $publisher, + ), + ) + ) + ); + + $config = $this->process($configs); + + $this->assertArrayHasKey('id', $config['handlers']['gelf']['publisher']); + $this->assertArrayNotHasKey('hostname', $config['handlers']['gelf']['publisher']); + $this->assertEquals('gelf.publisher', $config['handlers']['gelf']['publisher']['id']); + } + + public function testArrays() + { + $configs = array( + array( + 'handlers' => array( + 'foo' => array( + 'type' => 'stream', + 'path' => '/foo', + 'channels' => array('A', 'B') + ), + 'bar' => array( + 'type' => 'stream', + 'path' => '/foo', + 'channels' => array('!C', '!D') + ), + ) + ) + ); + + $config = $this->process($configs); + + // Check foo + $this->assertCount(2, $config['handlers']['foo']['channels']['elements']); + $this->assertEquals('inclusive', $config['handlers']['foo']['channels']['type']); + $this->assertEquals('A', $config['handlers']['foo']['channels']['elements'][0]); + $this->assertEquals('B', $config['handlers']['foo']['channels']['elements'][1]); + + // Check bar + $this->assertCount(2, $config['handlers']['bar']['channels']['elements']); + $this->assertEquals('exclusive', $config['handlers']['bar']['channels']['type']); + $this->assertEquals('C', $config['handlers']['bar']['channels']['elements'][0]); + $this->assertEquals('D', $config['handlers']['bar']['channels']['elements'][1]); + } + + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + */ + public function testInvalidArrays() + { + $configs = array( + array( + 'handlers' => array( + 'foo' => array( + 'type' => 'stream', + 'path' => '/foo', + 'channels' => array('A', '!B') + ) + ) + ) + ); + + $config = $this->process($configs); + } + + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + */ + public function testMergingInvalidChannels() + { + $configs = array( + array( + 'handlers' => array( + 'foo' => array( + 'type' => 'stream', + 'path' => '/foo', + 'channels' => 'A', + ) + ) + ), + array( + 'handlers' => array( + 'foo' => array( + 'channels' => '!B', + ) + ) + ) + ); + + $config = $this->process($configs); + } + + public function testWithType() + { + $configs = array( + array( + 'handlers' => array( + 'foo' => array( + 'type' => 'stream', + 'path' => '/foo', + 'channels' => array( + 'type' => 'inclusive', + 'elements' => array('A', 'B') + ) + ) + ) + ) + ); + + $config = $this->process($configs); + + // Check foo + $this->assertCount(2, $config['handlers']['foo']['channels']['elements']); + $this->assertEquals('inclusive', $config['handlers']['foo']['channels']['type']); + $this->assertEquals('A', $config['handlers']['foo']['channels']['elements'][0]); + $this->assertEquals('B', $config['handlers']['foo']['channels']['elements'][1]); + } + + /** + * Processes an array of configurations and returns a compiled version. + * + * @param array $configs An array of raw configurations + * + * @return array A normalized array + */ + protected function process($configs) + { + $processor = new Processor(); + + return $processor->processConfiguration(new Configuration(), $configs); + } +} diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/handlers_with_channels.xml b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/handlers_with_channels.xml new file mode 100644 index 0000000..d9eb899 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/handlers_with_channels.xml @@ -0,0 +1,31 @@ + + + + + + + + foo + + + + nested + + !foo + !bar + + + + + + + security + doctrine + + + + diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/multiple_handlers.xml b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/multiple_handlers.xml new file mode 100644 index 0000000..fe98c55 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/multiple_handlers.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/new_and_priority.xml b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/new_and_priority.xml new file mode 100644 index 0000000..1cefae5 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/new_and_priority.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/new_and_priority_import.xml b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/new_and_priority_import.xml new file mode 100644 index 0000000..47d9de6 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/new_and_priority_import.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/new_at_end.xml b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/new_at_end.xml new file mode 100644 index 0000000..b6fdd68 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/new_at_end.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/new_at_end_import.xml b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/new_at_end_import.xml new file mode 100644 index 0000000..5370fac --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/new_at_end_import.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/overwriting.xml b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/overwriting.xml new file mode 100644 index 0000000..5b41da0 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/overwriting.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/overwriting_import.xml b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/overwriting_import.xml new file mode 100644 index 0000000..fe98c55 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/xml/overwriting_import.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/handlers_with_channels.yml b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/handlers_with_channels.yml new file mode 100644 index 0000000..583ebae --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/handlers_with_channels.yml @@ -0,0 +1,30 @@ +monolog: + handlers: + custom: + type: stream + path: /tmp/symfony.log + bubble: false + level: ERROR + channels: foo + main: + type: group + members: [nested] + channels: ["!foo", "!bar"] + nested: + type: stream + extra: + type: syslog + ident: monolog + facility: user + level: ALERT + more: + type: native_mailer + to_email: monitoring@example.org + from_email: webmaster@example.org + subject: Monolog report + level: CRITICAL + channels: + type: inclusive + elements: + - security + - doctrine diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/multiple_handlers.yml b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/multiple_handlers.yml new file mode 100644 index 0000000..14af13e --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/multiple_handlers.yml @@ -0,0 +1,13 @@ +monolog: + handlers: + custom: + type: stream + path: /tmp/symfony.log + bubble: false + level: ERROR + main: + type: fingers_crossed + action_level: ERROR + handler: nested + nested: + type: stream diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/new_and_priority.yml b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/new_and_priority.yml new file mode 100644 index 0000000..32fd789 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/new_and_priority.yml @@ -0,0 +1,22 @@ +imports: + - { resource: new_and_priority_import.yml } + +monolog: + handlers: + custom: + type: stream + path: /tmp/symfony.log + bubble: true + level: WARNING + first: + type: rotating_file + path: /tmp/monolog.log + bubble: true + level: ERROR + priority: 3 + last: + type: stream + path: /tmp/last.log + bubble: true + level: ERROR + priority: -3 diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/new_and_priority_import.yml b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/new_and_priority_import.yml new file mode 100644 index 0000000..66f63f2 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/new_and_priority_import.yml @@ -0,0 +1,13 @@ +monolog: + handlers: + custom: + type: stream + path: /tmp/symfony.log + bubble: true + level: ERROR + main: + type: buffer + level: INFO + handler: nested + nested: + type: stream \ No newline at end of file diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/new_at_end.yml b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/new_at_end.yml new file mode 100644 index 0000000..d951d2b --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/new_at_end.yml @@ -0,0 +1,15 @@ +imports: + - { resource: new_at_end_import.yml } + +monolog: + handlers: + custom: + type: stream + path: /tmp/symfony.log + bubble: false + level: WARNING + new: + type: stream + path: /tmp/monolog.log + bubble: true + level: ERROR diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/new_at_end_import.yml b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/new_at_end_import.yml new file mode 100644 index 0000000..d87c3cf --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/new_at_end_import.yml @@ -0,0 +1,13 @@ +monolog: + handlers: + custom: + type: stream + path: /tmp/symfony.log + bubble: true + level: ERROR + main: + type: fingers_crossed + action_level: ERROR + handler: nested + nested: + type: stream \ No newline at end of file diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/overwriting.yml b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/overwriting.yml new file mode 100644 index 0000000..e2ee75a --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/overwriting.yml @@ -0,0 +1,10 @@ +imports: + - { resource: overwriting_import.yml } + +monolog: + handlers: + custom: + type: stream + path: /tmp/symfony.log + bubble: true + level: WARNING diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/overwriting_import.yml b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/overwriting_import.yml new file mode 100644 index 0000000..0b89ea7 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Fixtures/yml/overwriting_import.yml @@ -0,0 +1,13 @@ +monolog: + handlers: + custom: + type: stream + path: /tmp/symfony.log + bubble: false + level: ERROR + main: + type: fingers_crossed + action_level: ERROR + handler: nested + nested: + type: stream \ No newline at end of file diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/MonologExtensionTest.php b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/MonologExtensionTest.php new file mode 100644 index 0000000..6d49ffc --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/MonologExtensionTest.php @@ -0,0 +1,285 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\MonologBundle\Tests\DependencyInjection; + +use Symfony\Bundle\MonologBundle\Tests\TestCase; +use Symfony\Bundle\MonologBundle\DependencyInjection\MonologExtension; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +abstract class MonologExtensionTest extends TestCase +{ + public function testLoadWithDefault() + { + $container = new ContainerBuilder(); + $loader = new MonologExtension(); + + $loader->load(array(array('handlers' => array('main' => array('type' => 'stream')))), $container); + $this->assertTrue($container->hasDefinition('monolog.logger')); + $this->assertTrue($container->hasDefinition('monolog.handler.main')); + + $logger = $container->getDefinition('monolog.logger'); + $this->assertDICDefinitionMethodCallAt(0, $logger, 'pushHandler', array(new Reference('monolog.handler.main'))); + + $handler = $container->getDefinition('monolog.handler.main'); + $this->assertDICDefinitionClass($handler, '%monolog.handler.stream.class%'); + $this->assertDICConstructorArguments($handler, array('%kernel.logs_dir%/%kernel.environment%.log', \Monolog\Logger::DEBUG, true)); + } + + public function testLoadWithCustomValues() + { + $container = new ContainerBuilder(); + $loader = new MonologExtension(); + + $loader->load(array(array('handlers' => array('custom' => array('type' => 'stream', 'path' => '/tmp/symfony.log', 'bubble' => false, 'level' => 'ERROR')))), $container); + $this->assertTrue($container->hasDefinition('monolog.logger')); + $this->assertTrue($container->hasDefinition('monolog.handler.custom')); + + $logger = $container->getDefinition('monolog.logger'); + $this->assertDICDefinitionMethodCallAt(0, $logger, 'pushHandler', array(new Reference('monolog.handler.custom'))); + + $handler = $container->getDefinition('monolog.handler.custom'); + $this->assertDICDefinitionClass($handler, '%monolog.handler.stream.class%'); + $this->assertDICConstructorArguments($handler, array('/tmp/symfony.log', \Monolog\Logger::ERROR, false)); + } + + public function testLoadWithSeveralHandlers() + { + $container = $this->getContainer('multiple_handlers'); + + $this->assertTrue($container->hasDefinition('monolog.logger')); + $this->assertTrue($container->hasDefinition('monolog.handler.custom')); + $this->assertTrue($container->hasDefinition('monolog.handler.main')); + $this->assertTrue($container->hasDefinition('monolog.handler.nested')); + + $logger = $container->getDefinition('monolog.logger'); + $this->assertDICDefinitionMethodCallAt(1, $logger, 'pushHandler', array(new Reference('monolog.handler.custom'))); + $this->assertDICDefinitionMethodCallAt(0, $logger, 'pushHandler', array(new Reference('monolog.handler.main'))); + + $handler = $container->getDefinition('monolog.handler.custom'); + $this->assertDICDefinitionClass($handler, '%monolog.handler.stream.class%'); + $this->assertDICConstructorArguments($handler, array('/tmp/symfony.log', \Monolog\Logger::ERROR, false)); + + $handler = $container->getDefinition('monolog.handler.main'); + $this->assertDICDefinitionClass($handler, '%monolog.handler.fingers_crossed.class%'); + $this->assertDICConstructorArguments($handler, array(new Reference('monolog.handler.nested'), \Monolog\Logger::ERROR, 0, true, true)); + } + + public function testLoadWithOverwriting() + { + $container = $this->getContainer('overwriting'); + + $this->assertTrue($container->hasDefinition('monolog.logger')); + $this->assertTrue($container->hasDefinition('monolog.handler.custom')); + $this->assertTrue($container->hasDefinition('monolog.handler.main')); + $this->assertTrue($container->hasDefinition('monolog.handler.nested')); + + $logger = $container->getDefinition('monolog.logger'); + $this->assertDICDefinitionMethodCallAt(1, $logger, 'pushHandler', array(new Reference('monolog.handler.custom'))); + $this->assertDICDefinitionMethodCallAt(0, $logger, 'pushHandler', array(new Reference('monolog.handler.main'))); + + $handler = $container->getDefinition('monolog.handler.custom'); + $this->assertDICDefinitionClass($handler, '%monolog.handler.stream.class%'); + $this->assertDICConstructorArguments($handler, array('/tmp/symfony.log', \Monolog\Logger::WARNING, true)); + + $handler = $container->getDefinition('monolog.handler.main'); + $this->assertDICDefinitionClass($handler, '%monolog.handler.fingers_crossed.class%'); + $this->assertDICConstructorArguments($handler, array(new Reference('monolog.handler.nested'), \Monolog\Logger::ERROR, 0, true, true)); + } + + public function testLoadWithNewAtEnd() + { + $container = $this->getContainer('new_at_end'); + + $this->assertTrue($container->hasDefinition('monolog.logger')); + $this->assertTrue($container->hasDefinition('monolog.handler.custom')); + $this->assertTrue($container->hasDefinition('monolog.handler.main')); + $this->assertTrue($container->hasDefinition('monolog.handler.nested')); + $this->assertTrue($container->hasDefinition('monolog.handler.new')); + + $logger = $container->getDefinition('monolog.logger'); + $this->assertDICDefinitionMethodCallAt(2, $logger, 'pushHandler', array(new Reference('monolog.handler.new'))); + $this->assertDICDefinitionMethodCallAt(1, $logger, 'pushHandler', array(new Reference('monolog.handler.custom'))); + $this->assertDICDefinitionMethodCallAt(0, $logger, 'pushHandler', array(new Reference('monolog.handler.main'))); + + $handler = $container->getDefinition('monolog.handler.new'); + $this->assertDICDefinitionClass($handler, '%monolog.handler.stream.class%'); + $this->assertDICConstructorArguments($handler, array('/tmp/monolog.log', \Monolog\Logger::ERROR, true)); + } + + public function testLoadWithNewAndPriority() + { + $container = $this->getContainer('new_and_priority'); + + $this->assertTrue($container->hasDefinition('monolog.logger')); + $this->assertTrue($container->hasDefinition('monolog.handler.custom')); + $this->assertTrue($container->hasDefinition('monolog.handler.main')); + $this->assertTrue($container->hasDefinition('monolog.handler.nested')); + $this->assertTrue($container->hasDefinition('monolog.handler.first')); + $this->assertTrue($container->hasDefinition('monolog.handler.last')); + + $logger = $container->getDefinition('monolog.logger'); + $this->assertDICDefinitionMethodCallAt(2, $logger, 'pushHandler', array(new Reference('monolog.handler.last'))); + $this->assertDICDefinitionMethodCallAt(1, $logger, 'pushHandler', array(new Reference('monolog.handler.custom'))); + $this->assertDICDefinitionMethodCallAt(0, $logger, 'pushHandler', array(new Reference('monolog.handler.main'))); + $this->assertDICDefinitionMethodCallAt(2, $logger, 'pushHandler', array(new Reference('monolog.handler.first'))); + + $handler = $container->getDefinition('monolog.handler.main'); + $this->assertDICDefinitionClass($handler, '%monolog.handler.buffer.class%'); + $this->assertDICConstructorArguments($handler, array(new Reference('monolog.handler.nested'), 0, \Monolog\Logger::INFO, true)); + + $handler = $container->getDefinition('monolog.handler.first'); + $this->assertDICDefinitionClass($handler, '%monolog.handler.rotating_file.class%'); + $this->assertDICConstructorArguments($handler, array('/tmp/monolog.log', 0, \Monolog\Logger::ERROR, true)); + + $handler = $container->getDefinition('monolog.handler.last'); + $this->assertDICDefinitionClass($handler, '%monolog.handler.stream.class%'); + $this->assertDICConstructorArguments($handler, array('/tmp/last.log', \Monolog\Logger::ERROR, true)); + } + + public function testHandlersWithChannels() + { + $container = $this->getContainer('handlers_with_channels'); + + $this->assertEquals( + array( + 'monolog.handler.custom' => array('type' => 'inclusive', 'elements' => array('foo')), + 'monolog.handler.main' => array('type' => 'exclusive', 'elements' => array('foo', 'bar')), + 'monolog.handler.extra' => null, + 'monolog.handler.more' => array('type' => 'inclusive', 'elements' => array('security', 'doctrine')), + ), + $container->getParameter('monolog.handlers_to_channels') + ); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testExceptionWhenInvalidHandler() + { + $container = new ContainerBuilder(); + $loader = new MonologExtension(); + + $loader->load(array(array('handlers' => array('main' => array('type' => 'invalid_handler')))), $container); + } + + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + */ + public function testExceptionWhenUsingFingerscrossedWithoutHandler() + { + $container = new ContainerBuilder(); + $loader = new MonologExtension(); + + $loader->load(array(array('handlers' => array('main' => array('type' => 'fingers_crossed')))), $container); + } + + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + */ + public function testExceptionWhenUsingBufferWithoutHandler() + { + $container = new ContainerBuilder(); + $loader = new MonologExtension(); + + $loader->load(array(array('handlers' => array('main' => array('type' => 'buffer')))), $container); + } + + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + */ + public function testExceptionWhenUsingGelfWithoutPublisher() + { + $container = new ContainerBuilder(); + $loader = new MonologExtension(); + + $loader->load(array(array('handlers' => array('gelf' => array('type' => 'gelf')))), $container); + } + + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + */ + public function testExceptionWhenUsingGelfWithoutPublisherHostname() + { + $container = new ContainerBuilder(); + $loader = new MonologExtension(); + + $loader->load(array(array('handlers' => array('gelf' => array('type' => 'gelf', 'publisher' => array())))), $container); + } + + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + */ + public function testExceptionWhenUsingServiceWithoutId() + { + $container = new ContainerBuilder(); + $loader = new MonologExtension(); + + $loader->load(array(array('handlers' => array('main' => array('type' => 'service')))), $container); + } + + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + */ + public function testExceptionWhenUsingDebugName() + { + // logger + $container = new ContainerBuilder(); + $loader = new MonologExtension(); + + $loader->load(array(array('handlers' => array('debug' => array('type' => 'stream')))), $container); + } + + protected function getContainer($fixture) + { + $container = new ContainerBuilder(); + $container->registerExtension(new MonologExtension()); + + $this->loadFixture($container, $fixture); + + $container->getCompilerPassConfig()->setOptimizationPasses(array()); + $container->getCompilerPassConfig()->setRemovingPasses(array()); + $container->compile(); + + return $container; + } + + abstract protected function loadFixture(ContainerBuilder $container, $fixture); + + /** + * Assertion on the Class of a DIC Service Definition. + * + * @param \Symfony\Component\DependencyInjection\Definition $definition + * @param string $expectedClass + */ + protected function assertDICDefinitionClass($definition, $expectedClass) + { + $this->assertEquals($expectedClass, $definition->getClass(), "Expected Class of the DIC Container Service Definition is wrong."); + } + + protected function assertDICConstructorArguments($definition, $args) + { + $this->assertEquals($args, $definition->getArguments(), "Expected and actual DIC Service constructor arguments of definition '".$definition->getClass()."' don't match."); + } + + protected function assertDICDefinitionMethodCallAt($pos, $definition, $methodName, array $params = null) + { + $calls = $definition->getMethodCalls(); + if (isset($calls[$pos][0])) { + $this->assertEquals($methodName, $calls[$pos][0], "Method '".$methodName."' is expected to be called at position $pos."); + + if ($params !== null) { + $this->assertEquals($params, $calls[$pos][1], "Expected parameters to methods '".$methodName."' do not match the actual parameters."); + } + } + } +} diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/XmlMonologExtensionTest.php b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/XmlMonologExtensionTest.php new file mode 100644 index 0000000..f269939 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/XmlMonologExtensionTest.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\Bundle\MonologBundle\Tests\DependencyInjection; + +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; + +class XmlMonologExtensionTest extends MonologExtensionTest +{ + protected function loadFixture(ContainerBuilder $container, $fixture) + { + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/Fixtures/xml')); + $loader->load($fixture.'.xml'); + } +} diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/YamlMonologExtensionTest.php b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/YamlMonologExtensionTest.php new file mode 100644 index 0000000..8758801 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/YamlMonologExtensionTest.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\Bundle\MonologBundle\Tests\DependencyInjection; + +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; + +class YamlMonologExtensionTest extends MonologExtensionTest +{ + protected function loadFixture(ContainerBuilder $container, $fixture) + { + $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/Fixtures/yml')); + $loader->load($fixture.'.yml'); + } +} diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/TestCase.php b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/TestCase.php new file mode 100644 index 0000000..06e4589 --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/TestCase.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\Bundle\MonologBundle\Tests; + +class TestCase extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Monolog\\Logger')) { + $this->markTestSkipped('Monolog is not available.'); + } + } +} diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/bootstrap.php b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/bootstrap.php new file mode 100644 index 0000000..7b6d65b --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/Tests/bootstrap.php @@ -0,0 +1,19 @@ +=5.3.2", + "symfony/monolog-bridge": "2.1.*", + "symfony/dependency-injection": "2.1.*", + "symfony/config": "2.1.*", + "monolog/monolog": "1.*" + }, + "require-dev": { + "symfony/yaml": "2.1.*" + }, + "autoload": { + "psr-0": { "Symfony\\Bundle\\MonologBundle": "" } + }, + "target-dir": "Symfony/Bundle/MonologBundle", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + } +} diff --git a/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/phpunit.xml.dist b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/phpunit.xml.dist new file mode 100644 index 0000000..d6936ac --- /dev/null +++ b/vendor/symfony/monolog-bundle/Symfony/Bundle/MonologBundle/phpunit.xml.dist @@ -0,0 +1,20 @@ + + + + + + ./Tests + + + + + + . + + ./Resources + ./Tests + ./vendor + + + + diff --git a/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Command/SendEmailCommand.php b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Command/SendEmailCommand.php new file mode 100644 index 0000000..f680414 --- /dev/null +++ b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Command/SendEmailCommand.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\Bundle\SwiftmailerBundle\Command; + +use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Input\InputOption; + +/** + * Send Emails from the spool. + * + * @author Fabien Potencier + * @author Clément JOBEILI + */ +class SendEmailCommand extends ContainerAwareCommand +{ + /** + * @see Command + */ + protected function configure() + { + $this + ->setName('swiftmailer:spool:send') + ->setDescription('Sends emails from the spool') + ->addOption('message-limit', 0, InputOption::VALUE_OPTIONAL, 'The maximum number of messages to send.') + ->addOption('time-limit', 0, InputOption::VALUE_OPTIONAL, 'The time limit for sending messages (in seconds).') + ->addOption('recover-timeout', 0, InputOption::VALUE_OPTIONAL, 'The timeout for recovering messages that have taken too long to send (in seconds).') + ->setHelp(<<swiftmailer:spool:send command sends all emails from the spool. + +php app/console swiftmailer:spool:send --message-limit=10 --time-limit=10 --recover-timeout=900 + +EOF + ) + ; + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $mailer = $this->getContainer()->get('mailer'); + $transport = $mailer->getTransport(); + + if ($transport instanceof \Swift_Transport_SpoolTransport) { + $spool = $transport->getSpool(); + if ($spool instanceof \Swift_ConfigurableSpool) { + $spool->setMessageLimit($input->getOption('message-limit')); + $spool->setTimeLimit($input->getOption('time-limit')); + } + if ($spool instanceof \Swift_FileSpool) { + if (null !== $input->getOption('recover-timeout')) { + $spool->recover($input->getOption('recover-timeout')); + } else { + $spool->recover(); + } + } + $sent = $spool->flushQueue($this->getContainer()->get('swiftmailer.transport.real')); + + $output->writeln(sprintf('sent %s emails', $sent)); + } + } +} diff --git a/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/Compiler/RegisterPluginsPass.php b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/Compiler/RegisterPluginsPass.php new file mode 100644 index 0000000..63a12dc --- /dev/null +++ b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/Compiler/RegisterPluginsPass.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\Bundle\SwiftmailerBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * RegisterPluginsPass registers Swiftmailer plugins. + * + * @author Fabien Potencier + */ +class RegisterPluginsPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('swiftmailer.mailer')) { + return; + } + + $definition = $container->findDefinition('swiftmailer.transport'); + foreach ($container->findTaggedServiceIds('swiftmailer.plugin') as $id => $args) { + $definition->addMethodCall('registerPlugin', array(new Reference($id))); + } + } +} diff --git a/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/Configuration.php b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/Configuration.php new file mode 100644 index 0000000..c4c12d1 --- /dev/null +++ b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/Configuration.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\Bundle\SwiftmailerBundle\DependencyInjection; + +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; + +/** + * This class contains the configuration information for the bundle + * + * This information is solely responsible for how the different configuration + * sections are normalized, and merged. + * + * @author Christophe Coevoet + */ +class Configuration implements ConfigurationInterface +{ + private $debug; + + /** + * Constructor. + * + * @param Boolean $debug The kernel.debug value + */ + public function __construct($debug) + { + $this->debug = (Boolean) $debug; + } + + /** + * Generates the configuration tree builder. + * + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder + */ + public function getConfigTreeBuilder() + { + $treeBuilder = new TreeBuilder(); + $rootNode = $treeBuilder->root('swiftmailer'); + + $rootNode + ->children() + ->scalarNode('transport')->defaultValue('smtp')->end() + ->scalarNode('username')->defaultNull()->end() + ->scalarNode('password')->defaultNull()->end() + ->scalarNode('host')->defaultValue('localhost')->end() + ->scalarNode('port')->defaultFalse()->end() + ->scalarNode('encryption') + ->defaultNull() + ->validate() + ->ifNotInArray(array('tls', 'ssl', null)) + ->thenInvalid('The %s encryption is not supported') + ->end() + ->end() + ->scalarNode('auth_mode') + ->defaultNull() + ->validate() + ->ifNotInArray(array('plain', 'login', 'cram-md5', null)) + ->thenInvalid('The %s authentication mode is not supported') + ->end() + ->end() + ->arrayNode('spool') + ->children() + ->scalarNode('type')->defaultValue('file')->end() + ->scalarNode('path')->defaultValue('%kernel.cache_dir%/swiftmailer/spool')->end() + ->end() + ->end() + ->scalarNode('sender_address')->end() + ->arrayNode('antiflood') + ->children() + ->scalarNode('threshold')->defaultValue(99)->end() + ->scalarNode('sleep')->defaultValue(0)->end() + ->end() + ->end() + ->scalarNode('delivery_address')->end() + ->booleanNode('disable_delivery')->end() + ->booleanNode('logging')->defaultValue($this->debug)->end() + ->end() + ; + + return $treeBuilder; + } +} diff --git a/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/SwiftmailerExtension.php b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/SwiftmailerExtension.php new file mode 100644 index 0000000..86e0b29 --- /dev/null +++ b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/SwiftmailerExtension.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\Bundle\SwiftmailerBundle\DependencyInjection; + +use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Config\FileLocator; + +/** + * SwiftmailerExtension is an extension for the SwiftMailer library. + * + * @author Fabien Potencier + */ +class SwiftmailerExtension extends Extension +{ + /** + * Loads the Swift Mailer configuration. + * + * Usage example: + * + * + * fabien + * xxxxx + * + * + * + * @param array $configs An array of configuration settings + * @param ContainerBuilder $container A ContainerBuilder instance + */ + public function load(array $configs, ContainerBuilder $container) + { + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('swiftmailer.xml'); + $container->setAlias('mailer', 'swiftmailer.mailer'); + + $configuration = $this->getConfiguration($configs, $container); + $config = $this->processConfiguration($configuration, $configs); + + if (null === $config['transport']) { + $transport = 'null'; + } elseif ('gmail' === $config['transport']) { + $config['encryption'] = 'ssl'; + $config['auth_mode'] = 'login'; + $config['host'] = 'smtp.gmail.com'; + $transport = 'smtp'; + } else { + $transport = $config['transport']; + } + + if (isset($config['disable_delivery']) && $config['disable_delivery']) { + $transport = 'null'; + } + + if ('smtp' === $transport) { + $loader->load('smtp.xml'); + } + + if (in_array($transport, array('smtp', 'mail', 'sendmail', 'null'))) { + // built-in transport + $transport = 'swiftmailer.transport.'.$transport; + } + + $container->setAlias('swiftmailer.transport', $transport); + + if (false === $config['port']) { + $config['port'] = 'ssl' === $config['encryption'] ? 465 : 25; + } + + foreach (array('encryption', 'port', 'host', 'username', 'password', 'auth_mode') as $key) { + $container->setParameter('swiftmailer.transport.smtp.'.$key, $config[$key]); + } + + // spool? + if (isset($config['spool'])) { + $type = $config['spool']['type']; + + $loader->load('spool.xml'); + if ($type === 'file') { + $loader->load('spool_file.xml'); + } elseif ($type === 'memory') { + $loader->load('spool_memory.xml'); + } + $container->setAlias('swiftmailer.transport.real', $transport); + $container->setAlias('swiftmailer.transport', 'swiftmailer.transport.spool'); + $container->setAlias('swiftmailer.spool', 'swiftmailer.spool.'.$type); + + foreach (array('path') as $key) { + $container->setParameter('swiftmailer.spool.'.$type.'.'.$key, $config['spool'][$key]); + } + } + $container->setParameter('swiftmailer.spool.enabled', isset($config['spool'])); + + // antiflood? + if (isset($config['antiflood'])) { + $container->setParameter('swiftmailer.plugin.antiflood.threshold', $config['antiflood']['threshold']); + $container->setParameter('swiftmailer.plugin.antiflood.sleep', $config['antiflood']['sleep']); + + $container->getDefinition('swiftmailer.plugin.antiflood')->addTag('swiftmailer.plugin'); + } + + if ($config['logging']) { + $container->getDefinition('swiftmailer.plugin.messagelogger')->addTag('swiftmailer.plugin'); + $container->findDefinition('swiftmailer.data_collector')->addTag('data_collector', array('template' => 'SwiftmailerBundle:Collector:swiftmailer', 'id' => 'swiftmailer')); + } + + if (isset($config['sender_address']) && $config['sender_address']) { + $container->setParameter('swiftmailer.sender_address', $config['sender_address']); + $container->getDefinition('swiftmailer.plugin.impersonate')->addTag('swiftmailer.plugin'); + } else { + $container->setParameter('swiftmailer.sender_address', null); + } + + if (isset($config['delivery_address']) && $config['delivery_address']) { + $container->setParameter('swiftmailer.single_address', $config['delivery_address']); + $container->getDefinition('swiftmailer.plugin.redirecting')->addTag('swiftmailer.plugin'); + } else { + $container->setParameter('swiftmailer.single_address', null); + } + } + + /** + * Returns the base path for the XSD files. + * + * @return string The XSD base path + */ + public function getXsdValidationBasePath() + { + return __DIR__.'/../Resources/config/schema'; + } + + /** + * Returns the namespace to be used for this extension (XML namespace). + * + * @return string The XML namespace + */ + public function getNamespace() + { + return 'http://symfony.com/schema/dic/swiftmailer'; + } + + public function getConfiguration(array $config, ContainerBuilder $container) + { + return new Configuration($container->getParameter('kernel.debug')); + } +} diff --git a/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/EventListener/EmailSenderListener.php b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/EventListener/EmailSenderListener.php new file mode 100644 index 0000000..dcc8fbe --- /dev/null +++ b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/EventListener/EmailSenderListener.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\Bundle\SwiftmailerBundle\EventListener; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\IntrospectableContainerInterface; +use Symfony\Component\HttpKernel\Event\PostResponseEvent; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * Sends emails for the memory spool. + * + * Emails are sent on the kernel.terminate event. + * + * @author Fabien Potencier + */ +class EmailSenderListener implements EventSubscriberInterface +{ + private $container; + + public function __construct(ContainerInterface $container, $autoStart = false) + { + $this->container = $container; + } + + public function onKernelTerminate(PostResponseEvent $event) + { + if ($this->container instanceof IntrospectableContainerInterface && !$this->container->initialized('mailer')) { + return; + } + + $transport = $this->container->get('mailer')->getTransport(); + if (!$transport instanceof \Swift_Transport_SpoolTransport) { + return; + } + + $spool = $transport->getSpool(); + if (!$spool instanceof \Swift_MemorySpool) { + return; + } + + $spool->flushQueue($this->container->get('swiftmailer.transport.real')); + } + + static public function getSubscribedEvents() + { + return array(KernelEvents::TERMINATE => 'onKernelTerminate'); + } +} diff --git a/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/LICENSE b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/LICENSE new file mode 100644 index 0000000..cdffe7a --- /dev/null +++ b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 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/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/schema/swiftmailer-1.0.xsd b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/schema/swiftmailer-1.0.xsd new file mode 100644 index 0000000..cc896d0 --- /dev/null +++ b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/schema/swiftmailer-1.0.xsd @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/smtp.xml b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/smtp.xml new file mode 100644 index 0000000..7100f47 --- /dev/null +++ b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/smtp.xml @@ -0,0 +1,27 @@ + + + + + + Swift_Transport_EsmtpTransport + + + + + + + + + + + %swiftmailer.transport.smtp.host% + %swiftmailer.transport.smtp.port% + %swiftmailer.transport.smtp.encryption% + %swiftmailer.transport.smtp.username% + %swiftmailer.transport.smtp.password% + %swiftmailer.transport.smtp.auth_mode% + + + diff --git a/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/spool.xml b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/spool.xml new file mode 100644 index 0000000..d9009d7 --- /dev/null +++ b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/spool.xml @@ -0,0 +1,18 @@ + + + + + + Swift_Plugins_RedirectingPlugin + Swift_Plugins_BlackholePlugin + + + + + + + + + diff --git a/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/spool_file.xml b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/spool_file.xml new file mode 100644 index 0000000..b452553 --- /dev/null +++ b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/spool_file.xml @@ -0,0 +1,16 @@ + + + + + + Swift_FileSpool + + + + + %swiftmailer.spool.file.path% + + + diff --git a/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/spool_memory.xml b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/spool_memory.xml new file mode 100644 index 0000000..eefe660 --- /dev/null +++ b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/spool_memory.xml @@ -0,0 +1,20 @@ + + + + + + Swift_MemorySpool + Symfony\Bundle\SwiftmailerBundle\EventListener\EmailSenderListener + + + + + + + + + + + diff --git a/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/swiftmailer.xml b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/swiftmailer.xml new file mode 100644 index 0000000..57753bf --- /dev/null +++ b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/config/swiftmailer.xml @@ -0,0 +1,86 @@ + + + + + + Swift_Mailer + + Swift_Transport_SendmailTransport + Swift_Transport_MailTransport + + Swift_Transport_FailoverTransport + + Swift_Plugins_RedirectingPlugin + Swift_Plugins_ImpersonatePlugin + Swift_Plugins_MessageLogger + Swift_Plugins_AntiFloodPlugin + 99 + 0 + + Symfony\Bridge\Swiftmailer\DataCollector\MessageDataCollector + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %swiftmailer.single_address% + + + + %swiftmailer.plugin.antiflood.threshold% + %swiftmailer.plugin.antiflood.sleep% + + + + %swiftmailer.sender_address% + + + + + + + %swiftmailer.spool.enabled% + + + + + diff --git a/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/views/Collector/swiftmailer.html.twig b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/views/Collector/swiftmailer.html.twig new file mode 100644 index 0000000..3c575c9 --- /dev/null +++ b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Resources/views/Collector/swiftmailer.html.twig @@ -0,0 +1,53 @@ +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} + +{% block toolbar %} + {% if collector.messagecount %} + {% set icon %} + Swiftmailer + {{ collector.messageCount }} + {% endset %} + {% set text %} +
    + Messages + {{ collector.messageCount }} +
    +
    + Is spooled ? + {{ collector.isSpool ? 'yes' : 'no' }} +
    + {% endset %} + {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %} + {% endif %} +{% endblock %} + +{% block menu %} + + Configuration + E-Mails + + {{ collector.messagecount }} + + +{% endblock %} + +{% block panel %} +

    Messages {{ collector.isSpool ? 'spooled' : 'sent' }}

    + + {% if not collector.messages %} +

    + No message sent. +

    + {% else %} + {% for i, message in collector.messages %} +

    Message {{ i + 1 }} / {{ collector.messagecount }}

    + + {% for header in message.headers.all %} +
    {{ header }}
    + {% endfor %} + +

    +

    {{ message.body|e('html', message.charset)|convert_encoding('UTF-8', message.charset) }}
    +

    + {% endfor %} + {% endif %} +{% endblock %} diff --git a/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/SwiftmailerBundle.php b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/SwiftmailerBundle.php new file mode 100644 index 0000000..8456bbf --- /dev/null +++ b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/SwiftmailerBundle.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\Bundle\SwiftmailerBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Bundle\SwiftmailerBundle\DependencyInjection\Compiler\RegisterPluginsPass; + +/** + * Bundle. + * + * @author Fabien Potencier + */ +class SwiftmailerBundle extends Bundle +{ + public function build(ContainerBuilder $container) + { + parent::build($container); + + $container->addCompilerPass(new RegisterPluginsPass()); + } +} diff --git a/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Tests/DependencyInjection/SwiftmailerExtensionTest.php b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Tests/DependencyInjection/SwiftmailerExtensionTest.php new file mode 100644 index 0000000..9d72ddf --- /dev/null +++ b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Tests/DependencyInjection/SwiftmailerExtensionTest.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\Bundle\SwiftmailerBundle\Tests\DependencyInjection; + +use Symfony\Bundle\SwiftmailerBundle\Tests\TestCase; +use Symfony\Bundle\SwiftmailerBundle\DependencyInjection\SwiftmailerExtension; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +class SwiftmailerExtensionTest extends TestCase +{ + public function testConfigLoad() + { + $container = new ContainerBuilder(); + $container->setParameter('kernel.debug', false); + $loader = new SwiftmailerExtension(); + + $loader->load(array(array()), $container); + $this->assertEquals('Swift_Mailer', $container->getParameter('swiftmailer.class'), '->load() loads the swiftmailer.xml file if not already loaded'); + + $loader->load(array(array('transport' => 'sendmail')), $container); + $this->assertEquals('swiftmailer.transport.sendmail', (string) $container->getAlias('swiftmailer.transport')); + + $loader->load(array(array()), $container); + $this->assertEquals('swiftmailer.transport.smtp', (string) $container->getAlias('swiftmailer.transport')); + } + + public function testNullTransport() + { + $container = new ContainerBuilder(); + $container->setParameter('kernel.debug', false); + $loader = new SwiftmailerExtension(); + + $loader->load(array(array('transport' => null)), $container); + $this->assertEquals('swiftmailer.transport.null', (string) $container->getAlias('swiftmailer.transport')); + } + + public function testSpool() + { + $container = new ContainerBuilder(); + $container->setParameter('kernel.debug', false); + $loader = new SwiftmailerExtension(); + + $loader->load(array(array('spool' => array())), $container); + $this->assertEquals('swiftmailer.transport.spool', (string) $container->getAlias('swiftmailer.transport')); + $this->assertEquals('swiftmailer.transport.smtp', (string) $container->getAlias('swiftmailer.transport.real')); + } + +} diff --git a/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Tests/TestCase.php b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Tests/TestCase.php new file mode 100644 index 0000000..b65b64a --- /dev/null +++ b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/Tests/TestCase.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\Bundle\SwiftmailerBundle\Tests; + +class TestCase extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Swift_Mailer')) { + $this->markTestSkipped('Swiftmailer is not available.'); + } + } +} diff --git a/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/composer.json b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/composer.json new file mode 100644 index 0000000..3c17b6f --- /dev/null +++ b/vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/composer.json @@ -0,0 +1,33 @@ +{ + "name": "symfony/swiftmailer-bundle", + "type": "symfony-bundle", + "description": "Symfony SwiftmailerBundle", + "keywords": [], + "homepage": "http://symfony.com", + "version": "2.1.0", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "require": { + "php": ">=5.3.2", + "swiftmailer/swiftmailer": ">=4.1.8,<4.2-dev", + "symfony/swiftmailer-bridge": "self.version" + }, + "autoload": { + "psr-0": { "Symfony\\Bundle\\SwiftmailerBundle": "" } + }, + "target-dir": "Symfony/Bundle/SwiftmailerBundle", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + } +} diff --git a/vendor/symfony/symfony/.editorconfig b/vendor/symfony/symfony/.editorconfig new file mode 100644 index 0000000..153cf3e --- /dev/null +++ b/vendor/symfony/symfony/.editorconfig @@ -0,0 +1,10 @@ +; top-most EditorConfig file +root = true + +; Unix-style newlines +[*] +end_of_line = LF + +[*.php] +indent_style = space +indent_size = 4 diff --git a/vendor/symfony/symfony/.travis.yml b/vendor/symfony/symfony/.travis.yml new file mode 100644 index 0000000..94afb77 --- /dev/null +++ b/vendor/symfony/symfony/.travis.yml @@ -0,0 +1,10 @@ +language: php + +php: + - 5.3.3 + - 5.3 + - 5.4 + +before_script: + - curl -s http://getcomposer.org/installer | php + - COMPOSER_ROOT_VERSION=dev-master php composer.phar --dev install diff --git a/vendor/symfony/symfony/CHANGELOG-2.0.md b/vendor/symfony/symfony/CHANGELOG-2.0.md new file mode 100644 index 0000000..b028537 --- /dev/null +++ b/vendor/symfony/symfony/CHANGELOG-2.0.md @@ -0,0 +1,341 @@ +CHANGELOG for 2.0.x +=================== + +This changelog references the relevant changes (bug and security fixes) done +in 2.0 minor versions. + +To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash +To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v2.0.0...v2.0.1 + +* 2.0.14 (2012-05-17) + + * d1c831d: Change must-proxy-revalidate by proxy-revalidate + * 445fd2f: In console terms columns are width and rows are height + * 926ac98: [Finder] replaced static by self on a private variable + * 47605f6: [Form][DataMapper] Do not update form to data when form is read only + * c642a5e: [CssSelector] ignored an optional whitespace after a combinator + * cbc3ed3: [HttpKernel] added some constant for better forward compatibility + * 906f6f6: [DependencyInjection] fixed private services removal when used as configurators (closes #3758) + * 970d0b4: [BrowserKit] Check class existence only when required. + * 1ed8b72: Autoloader should not throw exception because PHP will continue to call other registered autoloaders. + * 7fe236a: [Security] Configure ports in RetryAuthenticationEntryPoint according to router settings + +* 2.0.13 (2012-04-30) + + * 5b92b9e: [Console] Selectively output to STDOUT or OUTPUT stream + * c89f3d3: [HttpKernel] Added DEPRECATED errors + * 689a40d: [MonologBridge] Fixed the WebProcessor + * 2e7d3b1: http_build_query fix + * de73de0: http_build_query fix + * 3b7ee9a: http_build_query fix + * 14b3b05: [TwigBundle] added missing entry in the XSD schema + * 7ddc8cb: [FrameworkBundle] Monitor added/removed translations files in dev (fix #3653) + * 686653a: [HttpKernel] Fixed wache vary write (fixes #3896). + * 45ada32: Add Support for boolean as to string into yaml extension + * cd783fb: [HttpKernel] Fixed cache vary lookup (fixes #3896). + * 3939c90: [FrameworkBundle] Fix TraceableEventDispatcher unable to trace static class callables + * e4cbbf3: [Locale] fixed StubNumberFormatter::format() to behave like the NumberFormatter::parse() regarding to error flagging + * f16ff89: [Locale] fixed StubNumberFormatter::parse() to behave like the NumberFormatter::parse() regarding to error flagging + * 0a60664: [Locale] updated StubIntlDateFormatter::format() exception message when timestamp argument is an array for PHP >= 5.3.4 + * 6f9c05d: [Locale] Complete Stub with intl_error_name + * 312a5a4: [Locale] fixed StubIntlDateFormatter::format() to set the right error for PHP >= 5.3.4 and to behave like the intl when formatting successfully + * bb61e09: [Locale] use the correct way for Intl error + * 01fcb08: [HttpKernel] Fix the ProfilerListener (fix #3620) + * 3ae826a: Fix issue #3251: Check attribute type of service tags + * 57dd914: [EventDispatcher] Fixed E_NOTICES with multiple eventnames per subscriber with mixed priorities + * 77185e0: [Routing] Allow spaces in the script name for the apache dumper + * 6465a69: [Routing] Fixes to handle spaces in route pattern + * 31dde14: [Locale] updated StubIntlDateFormatter::format() behavior for PHP >= 5.3.4 + * 8a2b115: [Console] Mock terminal size to prevent formatting errors on small terminals + * 595cc11: [Console] Wrap exception messages to the terminal width to avoid ugly output + * 97f7b29: [Console] Avoid outputing \r's in exception messages + * 04ae7cc: [Routing] fixed exception message. + * f7647f9: [Routing] improved exception message when giving an invalid route name. + * 0024ddc: Fix for using route name as check_path. + * fc41d4f: [Security] [HttpDigest] Fixes a configuration error caused by an invalid 'key' child node configuration + * 24a0d0a: [DependencyInjection] Support Yaml calls without arguments + * 15dd17e: Simplified CONTENT_ headers retrieval + * 86a3512: [FrameworkBundle] Add support for full URLs to redirect controller + * 068e859: [TwigBundle] Changed getAndCleanOutputBuffering() handling of systems where ob_get_level() never returns 0 + * efa807a: [HttpKernel] fixed sub-request which should be always a GET (refs #3657) + * c1206c3: [FrameworkBundle] Subrequests should always use GET method + * 0c9b2d4: use SecurityContextInterface instead of SecurityContext + +* 2.0.12 (2012-03-19) + + * 54b2413: Webprofiler ipv6 search fix + * 8642473: Changed instances of \DateTimeZone::UTC to 'UTC' as the constant is not valid a produces this error when DateTimeZone is instantiated: DateTimeZone::__construct() [datetimezone.--construct]: Unknown or bad timezone (1024) + * fbed9ff: Update src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php + * 1b395f5: Revert "Throw exception when "date_widget" option is not equal to "time_widget"" + * ed218bb: Fixed an "Array to string conversion" warning when using PHP 5.4. Also affects Symfony2 master. + * 50cb486: Fixed proxy generation in the DoctrineBundle when using Doctrine >= 2.2.0 + * 93cc9ef: [Validator] Remove a race condition in the ClassMetaDataFactory (fix #3217) + * 878c239: Fixed autoloader leakage in tests + * 17c3482: fixed timezone bug in DateTimeToTimestampTransformer + * 705e460: provided unmerged definition for correct help generation + * 45bbb5b: added getNativeDefinition() to allow specifying an alternate InputDefinition for help generation + * aa53b88: Sets _format attribute only if it wasn't set previously by the user + * a827375: [CssSelector] fixed CssSelector::toXPath() when the CSS selector is an empty string + * ad07a95: [BrowserKit] Fixed Client->back/forward/reload() not keeping all request attributes + * eee5065: [TwigBundle] Workaround a flaw in the design of the configuration (normalization) + * 7aad478: [Locale] Prevent empty bundle + * a894431: [DependencyInjection] Allow parsing of parameters near escaped percent signs + * f758884: [FrameworkBundle] ContainerAwareEventDispatcher::removeListener() (closes #3115) + * 8fe6ee3: [Console] fixed help command when used from the shell (closes #3480) + * caa44ae: Only work with the cli sapi + * e2fc3cd: [Process] PHP_BINARY return the current process + * dc2d5a0: [HttpFoundation][Session] Fix bug in PDO Session Storage with SQLSRV making assumptions about parameters with length being OUTPUT not INPUT parameters. + * e8281cf: SqliteProfilerStorage fix + +* 2.0.11 (2012-02-24) + + * 3e64d36: [Serializer] Fix XML decoding attack vector through external entities + * 66d0d3d: [FrameworkBundle] Fix a bug in the RedirectableUrlMatcher + * 24a3cd3: Finder - allow sorting when searching in multiple directories + * 6e75fd1: Resolves issue with spl_autoload_register creating new copies of the container and passing that into the closure. + * d02ca25: [MonologBundle] Fixed a bug when adding a processor on a service handler + * 2434552: [Translation] Fixed fallback location if location is longer than three characters (possibly by mistake). + * ec7fb0b: [Routing] added a proper exception when a route pattern references the same variable more than once (closes #3344) + * beb4fc0: [WIP][Locale] StubIntlDateFormatter::parse was throwing exception instead of returning Boolean false like intl implementation + +* 2.0.10 (2012-02-06) + + * 8e13095: Fixed the unescaping of parameters to handle arrays + * c3f0ec7: Make DoctrineBundle fowards compatible with Doctrine 2.2 + * e814d27: [FormType] Fixed broken MoneyType regexp for JPY + * 7f96c8a: [HttpKernel] Prevent php script execution in cached ESI pages using HttpCache + * 959614b: Use reflection to determaine the correct path for component validation.xml file + * cacc880: [Bugfix][Locale] Fixed incomplete Locale data loading + * d67d419: [HttpFoundation] added missing trustProxy condition + * efce640: [Yaml][Parser] throw an exception if not readable + * aa58330: [Form] fixed flawed condition + * 253eeba: [BugFix][Validator] Fix for PHP incosistent behaviour of ArrayAccess + * 0507840: Prevent parameters from overwriting the template filename. + * 9bc41d0: [HttpFoundation] Fixed #3053 + * 9441c46: [DependencyInjection] PhpDumper, fixes #2730 + +* 2.0.9 (2012-01-06) + + * 0492290: [Console] added a missing method (closes #3043) + * e09b523: updated Twig to 1.5.1 to fix a regression + * 261325d: Cast $query['params'] to array to ensure it is a valid argument for the foreach. + * 85ca8e3: ParameterBag no longer resolves parameters that have spaces. + * aacb2de: use the forward compat version in the Filesystem service + * 41950a6: [WebProfilerBundle] add margin-bottom to caption + +* 2.0.8 (2011-12-26) + + * adea589: [Twig] made code compatible with Twig 1.5 + * 6e98730: added forwards compatibility for the Filesystem component + * 1b4aaa2: [HttpFoundation] fixed ApacheRequest + * 8235848: [HttpFoundation][File] Add flv file default extension + * 5a6c989: FrameworkBundle: Adding test-attribute in xsd-schema to write functional-tests if using xml-configurations + * 649fa52: [DoctrineBridge] Fixed the entity provider to support proxies + * e417153: [BugFix][Console] Fix type hint for output formatter + * d1fa8cc: [WebProfiler] Fix some design glitches (closes #2867) + * 662fdc3: [DoctrineBundle] Fixed incorrectly shown params + * 9e38d6a: [SwiftmailerBundle] fixed the send email command when the queue does not extends Swift_ConfigurableSpool + * 5c41ec9: [HttpKernel][Client] Only simple (name=value without any other params) cookies can be stored in same line, so lets add every as standalone to be compliant with rfc6265 + * 8069ea6: [Form] Added missing use statements (closes #2880) + * d5a1343: [Console] Improve input definition output for Boolean defaults + * 62f3dc4: [SecurityBundle] Changed environment to something unique. + * 0900ecc: #2688: Entities are generated in wrong folder (doctrine:generate:entities Namespace) + * f3e92c4: [TwigBundle] Fix the exception message escaping + * 4d64d90: Allow empty result; change default *choices* value to **null** instead of **array()**. - added *testEmptyChoicesAreManaged* test - `null` as default value for choices. - is_array() used to test if choices are user-defined. - `null` as default value in __construct too. - `null` as default value for choices in EntityType. + * ec7eec5: [DependencyInjection] fixed espacing issue (close #2819) + * 6548354: fixed data-url + * d97d7e9: Added a check to see if the type is a string if it's not a FormTypeInterface + * 7827f72: Fixes #2817: ensure that the base loader is correctly initialised + * 9c1fbb8: [DoctrineBridge] fixed the refreshing of the user for invalid users + * 45bba7b: Added a hint about a possible cause for why no mime type guesser is be available + * 3759ff0: [Locale] StubNumberFormatter allow to parse 64bit number in 64bit mode + * db2d773: [FrameworkBundle] Improve the TemplateLocator exception message + * 2c3e9ad: [DependencyInjection] Made the reference case insensitive + * 4535abe: [DoctrineBridge] Fixed attempt to serialize non-serializable values + +* 2.0.7 (2011-12-08) + + * b7fd519: [Security] fixed cast + * acbbe8a: [Process] introduced usage of PHP_BINARY (available as of PHP 5.4) + * 03ed770: [Validator] The current class isn't set in execution context when doing validateProperty() + * 7cfc392: check for session before trying to authentication details + * 3c83b89: [DoctrineBridge] Catch user-error when the identifier is not serialized with the User entity. + * 769c17b: Throw exceptions in case someone forgot to set method name in call. + * 4a8f101b: Fixed problem with multiple occurences of a given namespace. fix #2688 + * 63e2a99: [CssSelector] Fixed Issue for XPathExprOr: missing prefix in string conversion + * 36c7d03: Fixed GH-2720 - Fix disabled atrribute handling for radio form elements + * 17dc605: [FrameworkBundle] Checks that the template is readable before checking its modification time + * 61e0bde: [HttpKernel] ControllerResolver arguments reflection for Closure object. + * e06cea9: [HttpFoundation] Cookie values should not be restricted + * a931e21: get correct client IP from X-forwarded-for header + * 78e9b2f: [Form] Fixed textarea_widget (W3C standards) + * 36cebf0: Fix infinite loop on circular reference in form factory + * 79ae3fc: [Form] fixed radio and checkbox when data is not bool + * c1426ba: added locale handling forward compatibility + * 10eed30: added MessageDataCollector forward compatibility + * 57e1aeb: Fixed undefined index notice in readProperty() method (PropertyPath) + +* 2.0.6 (2011-11-16) + + * f7c5bf1: [HttpKernel] fixed Content-Length header when using ESI tags (closes #2623) + * d67fbe9: [HttpFoundation] added an exception to MimeTypeGuesser::guess() when no guesser are available (closes #2636) + * 0462a89: [Security] fixed HttpUtils::checkRequestPath() to not catch all exceptions (closes #2637) + * 24dcd0f: [DoctrineBundle] added missing default parameters, needed to setup and use DBAL without ORM + * 462580c: [Form] Check for normal integers. refs 0427b126c15a0a27cd7033375e30371ae6a4e516 + * bb5fb79: changed the way we store the current ob level (refs #2617) + * fb0fffe: [Validator] fixed a unit test for PHP 5.4 (closes #2585) + * 7cba0a0: Also identify FirePHP by the X-FirePHP-Version header + * ed1a6c2: [TwigBundle] Do not clean output buffering below initial level + * e83e00a: Fixed rendering of FileType (value is not a valid attribute for input[type=file]) + * 8351a11: Added check for array fields to be integers in reverseTransform method. This prevents checkdate from getting strings as arguments and throwing incorrect ErrorException when submitting form with malformed (string) data in, for example, Date field. #2609 + * 45b218e: [Translation] added detection for circular references when adding a fallback catalogue + * a245e15: [DomCrawler] trim URI in getURI + * 9d2ab9c: [Doctrine] fixed security user reloading when the user has been changed via a form with validation errors (closes #2033) + * d789f94: Serializer#normalize gives precedence to objects that support normalization + * 57b7daf: [Security] Fix checkRequestPath doc; closes #2323 + * b33198f: fixed CodeHelper::formatFileFromText() method to allow " as a file wrapper (it occurs for the main exception message) + * c31c512: [FrameworkBundle] fixed output buffering when an error occurs in a sub-request + * 380c67e: [FrameworkBundle] fixed HttpKernel when the app is stateless + * 95a1902: [Finder] bypassed some code when possible + * 957690c: fixing WebTastCase when kernel is not found and improving exception message + * dbba796: [Yaml] fixed dumper for floats when the locale separator is not a dot + * f9befb6: Remove only the security token instead of the session cookie. + * 348bccb: Clear session cookie if user was deleted, is disabled or locked to prevent infinite redirect loops to the login path (fixes #1798). + * 89cd64a: Set error code when number cannot be parsed. Fixes #2389 + * c9d05d7: Let NumberFormatter handle integer type casting + + +* 2.0.5 (2011-11-02) + + * c5e2def: Fix ternary operator usage in RequestMatcher::checkIpv6() + * 43ce425: [HttpKernel] added missing accessor + * 80f0b98: [DependencyInjection] Fix DefinitionDecorator::getArgument() for replacements + * 4bd340d: [Security] Fix typo in init:acl command name + * 3043fa0: [HttpFoundation] fixed PHP 5.4 regression + * 8dcde3c: [DependencyInjection] fixed int casting for XML files (based on what is done in the YAML component) + * 6c2f093: [HttpFoundation] removed superfluous query call (closes #2469) + * 6343bef: [HttpKernel] Updated mirror method to check for symlinks before dirs and files + * 27d0809: [MonologBridge] Adjust for Monolog 1.0.2 + * 808088a: added the ability to use dot and single quotes in the keys and values + * cbb4bba: [Routing] fixed side-effect in the PHP matcher dumper + * 1a43505: [FrameworkBundle] fixed priority to be consistent with 2.1 + * 6b872cf: Check if cache_warmer service is available before doing the actual cache warmup + * e81c710: Increased the priority of the profiler request listener + * 2b0af5e: [HttpKernel] fixed profile parent/children for deep-nested requests + * 9d8046e: [Doctrine] GH-1635 - UniqueValidator now works with associations + * 3426c83: [BrowserKit] fixed cookie updates from Response (the URI here is not the base URI, so it should not be used to determine the default values missing in the cookie, closes #2309) + * c0f5b8a: [HttpKernel] fixed profile saving when it has children + * 3d7510e: [HttpKernel] fixed missing init for Profile children property + * 00cbd39: [BrowserKit] Fixed cookie expiry discard when attribute contains capitals + * edfa29b: session data needs to be encoded because it can contain non binary safe characters e.g null. Fixes #2067 + * c00ba4d: [Console] fixed typo (closes #2358) + * 2270a4d: [Bridge][Doctrine] Adding a catch for when a developer uses the EntityType with multiple=false but on a "hasMany" relationship + * 2877883: anything in front of ;q= is part of the mime type, anything after may be ignored + * d2d849c: Added translations for "hy" + * ae0685a: [Translation] Loader should only load local files + * 8bd0e42: [Form] Use proper parent (text) for EmailType and TextareaType + * 95049ef: [Form] Added type check to `ScalarToChoiceTransformer` + * a74ae9d: [HttpFoundation] made X_REWRITE_URL only available on Windows platforms + * 828b18f: [Form] Fixed lacking attributes in DateTimeType + +* 2.0.4 (2011-10-04) + + * cf4a91e: [ClassLoader] fixed usage of trait_exists() + * 8d6add6: [DoctrineBridge] fixed directory reference when the directory cannot be created + * 5419638: [HttpKernel] Show the actual directory needing to be created. + * 5c8a2fb: [Routing] fixed route overriden mechanism when using embedded collections (closes #2139) + * e70c884: [Bridge/Monolog] Fix WebProcessor to accept a Request object. + * 600b8ef: [Validator] added support for grapheme_strlen when mbstring is not installed but intl is installed + * d429594: removed separator of choice widget when the separator is null + * 17af138: fixed usage of LIBXML_COMPACT as it is not always available + * b12ce94: [HttpFoundation] fix #2142 PathInfo parsing/checking + * b402835: [HttpFoundation] standardized cookie paths (an empty path is equivalent to /) + * 1284681: [BrowserKit] standardized cookie paths (an empty path is equivalent to /) + * 1e7e6ba: [HttpFoundation] removed the possibility for a cookie path to set it to null (as this is equivalent to /) + * 2db24c2: removed time limit for the vendors script (closes #2282) + * c13b4e2: fixed fallback catalogue mechanism in Framework bundle + * 369f181: [FrameworkBundle] Add request scope to assets helper only if needed + * d6b915a: [FrameworkBundle] Assets templating helper does not need request scope + * ed02aa9: Fix console: list 'namespace' command display all available commands + * 85ed5c6: [ClassLoader] Fixed state when trait_exists doesn't exists + * e866a67: [DoctrineBundle] Tries to auto-generate the missing proxy files on the autoloader + * 908a7a3: [HttpFoundation] Fix bug in clearCookie/removeCookie not clearing cookies set with a default '/' path, unless it was explicitly specified + +* 2.0.3 (2011-09-25) + + * 49c585e: Revert "merged branch stealth35/ini_bool (PR #2235)" + +* 2.0.2 (2011-09-25) + + * ae3aded: Added PCRE_DOTALL modifier to RouteCompiler to allow urlencoded linefeed in route parameters. + * e5a23db: [ClassLoader] added support for PHP 5.4 traits + * 11c4412: [DependencyInjection] fix 2219 IniFileLoader accept Boolean + * 64d44fb: [Translator] fixed recursion when using a fallback that is the same as the locale + * bca551e: [DomCrawler] ChoiceFormField should take the content when value is unavailable + * b635dca: [Translator] fixed non-loaded locale + * ab8e760: Fixed the creation of the subrequests + * 8e2cbe6: fixes usage of mb_* + * fd4d241: Profiler session import fixed. + * 9fb15c7: [Process] workaround a faulty implementation of is_executable on Windows + * 43b55ef: [Locale] Fix #2179 StubIntlDateFormatter support yy format + * 9ffd8ca: [Translation] renamed hasStrict() to defines() + * 79710ed: [Translation] added a MessageCatalogue::hasStrict() method to check if a string has a translation (but without taking into account the fallback mechanism) + * c50a3a1: [Translation] fixed transchoice when used with a fallback + * c985ffa: [Translation] fixed message selector when the message is empty (closes #2144) + * 27ba003: [HttpFoundation] changed the strategy introduced in a5ccda47b4406518ee75929ce2e690b6998c021b to fix functional tests and still allow to call save more than once for a Session + * ff99d80: Changed the behavior of Session::regenerate to destroy the session when it invalidates it. + * 73c8d2b: [Form] fixed error bubbling for Date and Time types when rendering as multiple choices (closes #2062) + * 95dc7e1: Fixed fourth argument of Filesystem->mirror() + * ae52303: [HttpFoundation] Fixed duplicate of request + * cd40ed4: Added missing method to HTTP Digest entry point + * 3a7e038: [FrameworkBundle] sanitize target arg in asset:install command + * 8d50c16: few optimisations for XliffFileLoader and XmlFileLoader + * 639513a: Per the documentation, the `NotBlank` constraint should be using the `empty` language construct, otherwise it will not trigger on, for example, a boolean false from an unchecked checkbox field. + * d19f1d7: [Doctrine] Fix UniqueEntityValidator reporting a false positive by ignoring multiple query results + * 0224a34: Fixes typo on ACL Doctrine cache. + * 6bd1749: Fixed a bug when multiple expanded choices would render unchecked because of the Form Framework's strict type checking. + * f448029: [HttpKernel] Tweaked SQLite to speed up SqliteProfilerStorage + * 2cfa22c: Fix Method ContainerAwareEventDispatcher::hasListeners + * f4c133e: removed trailing dot to make it consistent with other validator messages + * a6670c2: [Routing] fixed a caching issue when annotations are used on a base class used by more than one concrete class + * 946ccb6: [Routing] fixed annotation loaders for abstract classes, added more unit tests + * 723cb71: [Translation] Add compatibility to PCRE 6.6.0 for explicit interval pluralization + * 24bacdc: Ignore VCS files in assets:install command (closes #2025) + * 020fa51: [RedirectResponse] Added missing `doctype` and `title` tag + +* 2.0.1 (2011-08-26) + + * 1c7694f: [HttpFoundation] added a missing exception + * 84c1719: [FrameworkBundle] Avoid listener key conflicts in ContainerAwareEventDispatcher + * 536538f: [DoctrineBundle] removed an unused and confusing parameter (the connection class can be changed via the wrapper_class setting of a connection) + * d7f0789: [FrameworkBundle] fixed duplicated RequestContext instances + * 89f477e: [WebProfilerBundle] Throw exception if a collector template isn't found + * 6ca72cf: [WebProfilerBundle] Allow .html.twig in collector template names + * 39fabab: [EventDispatcher] Fix removeSubscriber() to work with priority syntax + * 3380f2a: [DomCrawler] fixed disabled fields in forms (they are available in the DOM, but their values are not submitted -- whereas before, they were simply removed from the DOM) + * 2b1bb2c: [Form] added missing DelegatingValidator registration in the Form Extension class (used when using the Form component outside a Symfony2 project where the validation.xml is used instead) + * fdd2e7a: [Form] Fixing a bug where setting empty_value to false caused a variable to not be found + * bc7edfe: [FrameworkBundle] changed resource filename of Japanese validator translation + * c29fa9d: [Form] Fix for treatment zero as empty data. Closes #1986 + * 6e7c375: [FrameworkBundle] Cleanup schema file + * b6ee1a6: fixes a bug when overriding method via the X-HTTP-METHOD-OVERRIDE header + * 80d1718: [Fix] Email() constraints now guess as 'email' field type + * 3a64b08: Search in others user providers when a user is not found in the first user provider and throws the right exception. + * 805a267: Remove Content-Length header adding for now. Fixes #1846. + * ae55a98: Added $format in serialize() method, to keep consistence and give a hint to the normalizer. + * 7ec533e: got an if-condition out of unnecessary loops in Symfony\Component\ClassLoader\UniversalClassLoader + * 34a1b53: [HttpFoundation] Do not save session in Session::__destroy() when saved already + * 81fb8e1: [DomCrawler] fix finding charset in addContent + * 4f9d229: The trace argument value could be string ("*DEEP NESTED ARRAY*") + * be031f5: [HttpKernel] fixed ControllerResolver when the controller is a class name with an __invoke() method + * 275da0d: [Validator] changed 'self' to 'static' for child class to override pattern constant + * e78bc32: Fixed: Notice: Undefined index: enable_annotations in ... + * 86f888f: fix https default port check + * 8a980bd: $node->hasAttribute('disabled') sf2 should not create disagreement between implementation and practice for a crawler. If sahi real browser can find an element that is disabled, then sf2 should too. https://github.com/Behat/Mink/pull/58#issuecomment-1712459 + * 1087792: -- fix use of STDIN + * ee5b9ce: [SwiftmailerBundle] Allow non-file spools + * d880db2: [Form] Test covered fix for invalid date (13 month/31.02.2011 etc.) send to transformer. Closes #1755 + * df74f49: Patched src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php to throw an exception when an invalid date is passed for transformation (e.g. 31st February) + * 8519967: Calling supportsClass from vote to find out if we can vote + +* 2.0.0 (2011-07-28) diff --git a/vendor/symfony/symfony/CONTRIBUTORS.md b/vendor/symfony/symfony/CONTRIBUTORS.md new file mode 100644 index 0000000..5f51233 --- /dev/null +++ b/vendor/symfony/symfony/CONTRIBUTORS.md @@ -0,0 +1,457 @@ +CONTRIBUTORS +============ + +Symfony2 is the result of the work of many people who made the code better +(see http://symfony.com/contributors for more information): + + - Fabien Potencier (fabpot) + - Bernhard Schussek (bschussek) + - Victor Berchet (vicb) + - Jordi Boggiano (Seldaek) + - Johannes (schmittjoh) + - Kris Wallsmith (kriswallsmith) + - Christophe Coevoet (stof) + - Drak (drak) + - Lukas Kahwe Smith (lsmith77) + - Ryan Weaver (weaverryan) + - Jeremy Mikola (jmikola) + - Pascal Borreli (pborreli) + - Benjamin Eberlei (beberlei) + - Joseph Bielawski (stloyd) + - Igor Wiedler (igorw) + - Hugo Hamon (hhamon) + - William DURAND (willdurand) + - Eriksen Costa (eriksencosta) + - Alexandre Salomé (alexandresalome) + - stealth35 (stealth35) + - Jonathan H. Wage (jwage) + - Thibault Duplessis (ornicar) + - Jakub Zalas (jakzal) + - Eric Clemmons (ericclemmons) + - Martin Hasoň (hason) + - Henrik Westphal (snc) + - Dariusz Górecki (canni) + - Tobias Schultze (Tobion) + - Miha Vrhovnik (mvrhov) + - Bulat Shakirzyanov (avalanche123) + - Henrik Bjørnskov (henrikbjorn) + - Andrej Hudec (pulzarraider) + - Francis Besset (francisbesset) + - Kevin Bond (kbond) + - Deni (yethee) + - Arnout Boks (aboks) + - Jordan Alliot (jalliot) + - Marc Weistroff (marcw) + - Konstantin Kudryashov (everzet) + - Toni Uebernickel (havvg) + - Sebastian Hörl (blogsh) + - Excel Web Zone (excelwebzone) + - Brandon Turner (blt04) + - Hidenori Goto (hidenorigoto) + - Brikou CARRE (brikou) + - Lenar Lõhmus (lenar) + - John Wards (johnwards) + - Jean-François Simon (jfsimon) + - Daniel Holmes (danielholmes) + - Antoine Hérault (Herzult) + - Tigran Azatyan (tigranazatyan) + - Helmer Aaviksoo (helmer) + - Jacob Dreesen (jdreesen) + - umpirsky (umpirsky) + - Pierre Minnieur (pminnieur) + - Michał Pipa (michal-pipa) + - Fabien Pennequin (FabienPennequin) + - Richard Shank (IamPersistent) + - Benjamin Dulau (benjamindulau) + - Douglas Greenshields (shieldo) + - Christian Raue (craue) + - Grégoire Pineau (lyrixx) + - Katsuhiro OGAWA (fivestar) + - Richard Miller (richardmiller) + - Jeremy Mikola + - Bart van den Burg (Burgov) + - blue-eyes (blue-eyes) + - Juti Noppornpitak (shiroyuki) + - Robert Schönthal (digitalkaoz) + - Florin Patan (dlsniper) + - Rafael Dohms (rdohms) + - Tim Nagel (merk) + - Włodzimierz Gajda (gajdaw) + - Michel Weimerskirch (mweimerskirch) + - Javier Eguiluz (javiereguiluz) + - Joseph Rouff (rouffj) + - Marcel Beerta (mazen) + - Daniel Gomes + - Wotre (Wotre) + - Matthieu Vachon (maoueh) + - Amal Raghav (kertz) + - Artur Kotyrba (udat) + - Gustavo Piltcher + - Rui Marinho + - Clément JOBEILI (dator) + - Michael Holm (hollodk) + - dbu + - Julien Brochet (aerialls) + - Thomas (rande) + - Alexander (asm89) + - Gordon Franke (gimler) + - Noel GUILBERT (noelg) + - Alif Rachmawadi (subosito) + - Lars Strojny (lstrojny) + - Martin Schuhfuss (usefulthink) + - Dennis Benkert (denderello) + - Matthieu Bontemps (mbontemps) + - Jonathan Ingram (jonathaningram) + - Alessandro Desantis (alessandro1997) + - Oscar Cubo Medina (ocubom) + - Pablo Godel (pgodel) + - Dustin Whittle (dustinwhittle) + - Jean-François PHILIPPE (jfphilippe) + - Arnaud Le Blanc (arnaud-lb) + - Justin Hileman (bobthecow) + - Danny Berger (dpb587) + - Sven Paulus (subsven) + - Gábor Egyed (1ed) + - Xavier Perez (DuoSRX) + - Joel Wurtz (Brouznouf) + - Joe Lencioni (lencioni) + - brki (brki) + - Francois Zaninotto + - Leszek Prabucki (l3l0) + - Francois Zaninotto (fzaninotto) + - Gyula Sallai (thesalla) + - Xavier Montaña Carreras (xmontana) + - Andreas Hucks (meandmymonkey) + - Arjen Brouwer (arjenjb) + - Jérémie Augustin (jaugustin) + - Boussekeyt Jules (gordonslondon) + - Jan Sorgalla (jsor) + - Daniel Gomes (danielcsgomes) + - Lee McDermott (lmcd) + - Manuel Reinhard (sprain) + - Jeroen Hoek (jdhoek) + - Albert Jessurum (ajessu) + - Ryan Rogers (timewasted) + - flevour (flevour) + - Michel Salib (michelsalib) + - geoffrey + - Kim Hemsø Rasmussen (kimhemsoe) + - Manuel Kiessling (ManuelKiessling) + - Bilal Amarni (bamarni) + - Tobias Naumann (tna) + - Shein Alexey (conf) + - Aurelijus Valeiša (aurelijus) + - Ray (rrehbeindoi) + - Adrian Rudnik (kreischweide) + - Marcin Chylek (SongoQ) + - Pavel Campr (pcampr) + - Josip Kruslin (aubx) + - drak3 (drak3) + - Chris Boden (cboden) + - Dustin Dobervich (dustin10) + - Sebastian Marek (proofek) + - Olivier Dolbeau (odolbeau) + - Michele Orselli (micheleorselli) + - Andréia Bohner (andreia) + - Sebastian Bergmann (sebastianbergmann) + - Miquel Rodríguez Telep (mrtorrent) + - Peter Kokot (maastermedia) + - Jérôme Tamarelle (GromNaN) + - Jérémy Romey (jeremyFreeAgent) + - Yuen-Chi Lian (yclian) + - John Bohn (jjbohn) + - Greg Thornton (xdissent) + - andrewtch (andrewtch) + - Costin Bereveanu (schniper) + - Ondrej Slinták (ondrowan) + - Markus Lanthaler (lanthaler) + - Konstantin Leboev (realmfoo) + - Thomas Adam (tecbot) + - superjavason (superjavason) + - Donald Tyler (Chekote) + - Matthew Lewinski + - Kai + - Sergey Linnik (Partugal) + - Johnny Peck (johnnypeck) + - Laszlo Korte (laszlokorte) + - Hubert LECORCHE (hlecorche) + - Sergey Skopin (grizlik) + - drmonty (drmonty) + - Michael Ridgway (mridgway) + - Anthon Pang (robocoder) + - Stepan Tanasiychuk (stfalcon) + - Bertrand Zuchuat (Garfield-fr) + - Sebastien Armand (khepin) + - Sebastiaan Stok (sstok) + - Jan Schumann (janschumann) + - Asier Illarramendi (doup) + - Shigenobu Nishikawa (shishi) + - Marcin Sikoń (marphi) + - cedric lombardot (cedriclombardot) + - Laurent Bachelier (laurentb) + - Fabian Lange (CodingFabian) + - Yoshio HANAWA + - Pablo Díez (pablodip) + - Fran Moreno (franmomu) + - Manuel de Ruiter (ManuelAC) + - Crell (Crell) + - Benoit Tirmarche (mcbennn) + - Grégoire Passault + - Ismael Ambrosi (iambrosi) + - Tom Klingenberg (ktomk) + - De Cock Xavier (xdecock) + - Cristian González Sánchez (cristiangsp) + - Nils Adermann (naderman) + - Steve Kondik (cyanogen) + - Benjamin Lévêque (benji07) + - Matt Robinson (inanimatt) + - Ivan Rey (ivanrey) + - Ned Schwartz (theinterned) + - Ziumin (Ziumin) + - Aurélien Fredouelle (AurelC2G) + - Marek Kalnik (marekkalnik) + - Adán Lobato (adanlobato) + - Tiago Ribeiro (fixe) + - Geoffrey Tran (geoffreytran) + - Christian Schaefer (caefer) + - Robert Gruendler (pulse00) + - Elliot Anderson (elliot) + - xaav + - Anton Babenko (antonbabenko) + - Martin Hasoň + - José Nahuel Cuesta Luengo (ncuesta) + - Erkhembayar Gantulga (erheme318) + - Rostyslav Kinash + - yktd26 (yktd26) + - Tom Van Looy (tvlooy) + - umpirski (umpirski) + - Neil Katin + - John Kary (johnkary) + - Peter Kokot (peterkokot) + - Hossein Bukhamsin (husinluck) + - Fabrice Bernhard (fabriceb) + - develop + - Hiromi Hishida (77web) + - Klein Florian (docteurklein) + - Stéphane PY (stephpy) + - Joshua Nye (zerosanity) + - markchalloner (markchalloner) + - Mike Lively (mlively) + - Michael Williams (mtotheikle) + - Thomas Chmielowiec (chmielot) + - Casper Valdemar Poulsen (cvaldemar) + - Degory Valentine + - Krzysiek Łabuś (Crozin) + - Thomas Bibb (thomasbibb) + - Ivan Kurnosov + - stloyd + - Jan Prieser (jaypea) + - Thomas Chmielowiec (chmielot) + - Grégoire Paris (greg0ire) + - paulkamer (paulkamer) + - Peter Kruithof (pkruithof) + - alefranz (alefranz) + - frost-nzcr4 (frost-nzcr4) + - Petit Yoann (Abhoryo) + - Fabian Vogler (fabian) + - Maksim Kotlyar + - Artyom Protaskin (gatsu) + - Grégoire Passault (Gregwar) + - Alexander Miehe (Engerim) + - Cyril Quintin (cyqui) + - Gerard van Helden (drm) + - kazusuke sasezaki (sasezaki) + - root + - Kirill chEbba Chebunin (chEbba) + - Julien DIDIER (juliendidier) + - Chris Smith (cs278) + - Derek ROTH (DerekRoth) + - mwsaz + - corphi (corphi) + - Giulio De Donato (liuggio) + - Matthias (mpdude) + - Emil Einarsson (Einarsson) + - Yanick Witschi (Toflar) + - Don Pinkster + - Piotr Błasiak (blahy) + - Saem Ghani (saem) + - Michael Roterman (wtfzdotnet) + - Arno Geurts + - Jörg Rühl (LennyLinux) + - jeanfrancois.simon + - Bernd Matzner (bmatzner) + - Daniel Cestari (dcestari) + - Jesse Cooke (jc00ke) + - jdewit (jdewit) + - Javier López (loalf) + - Magnus Nordlander (magnusnordlander) + - Adam Monsen (meonkeys) + - nervo (nervo) + - Oleg Stepura (olegstepura) + - patrick-mcdougle (patrick-mcdougle) + - Sebastian Busch (sbusch) + - Benoît Merlet (trompette) + - xanido (xanido) + - Xavier HAUSHERR (xkobal) + - Craig Marvelley (craigmarvelley) + - Jan Behrens (deegital) + - Hans (drublic) + - m0ppers (m0ppers) + - Michael Shtukin (mshtukin) + - Teo (teo-sk) + - Tony Piper (tonypiper) + - sensio + - Théophile Helleboid - chtitux (chtitux) + - Matthew Lewinski (lewinski) + - Markus Bachmann (Baachi) + - scoolen (scoolen) + - irmantas (irmantas) + - tero (tero) + - Vadim Tyukov (vatson) + - Stainslav Turza (S0RIEN) + - chispita + - Tobias Sjösten (tobiassjosten) + - Wojciech Sznapka (wowo) + - julien.galenski + - Martijn Evers (martijn4evers) + - Jeremy Bush (zombor) + - Evan Villemez (evillemez) + - Davide Borsatto (davideborsatto) + - kaiwa + - Gustavo Adrian + - Roger Webb + - Nicolas Fabre (nfabre) + - Clément Herreman (clemherreman) + - heccjj (heccjj) + - Ringosan (Ringosan) + - Balázs Benyó (duplabe) + - Sebastian Utz (seut) + - Cédric Lahouste (RapotOR) + - George Giannoulopoulos (dotoree) + - Alberto Pirovano (geezmo) + - Xavier Briand (xavierbriand) + - Romain Geissler (Romain-Geissler) + - Carsten Nielsen (phreaknerd) + - JerikVenture (JerikVenture) + - Evan Kaufman (EvanK) + - meckhardt (meckhardt) + - Sebastian Ionescu + - Dirk Pahl (dirkaholic) + - Konrad Mohrfeldt (kmohrf) + - Nicolas Badey (Nico-B) + - Philipp Scheit (pscheit) + - Bouke Haarsma (Bouke) + - Lars Strojny + - Yrwein (Yrwein) + - pborreli + - Martin Parsiegla + - Christoph Nißle (DerStoffel) + - Luis Muñoz + - Oleg Zinchenko (cystbear) + - Guilherme Blanco (guilhermeblanco) + - Stefano Sala (stewe) + - Sebastian Hörl + - Romain Dorgueil + - Benjamin Zikarsky (bzikarsky) + - pierre + - Andy Stanberry (cranberyxl) + - Alessio (ioalessio) + - Jérôme Macias (jeromemacias) + - Philip Dahlstrøm (phidah) + - Gustavo Falco + - gnat42 (gnat42) + - Alexey Popkov (patashnik) + - devel + - Hiroki HIROCASTER OHTSUKA (hirocaster) + - jpauli (jpauli) + - Kevin McBride (krmcbride) + - Dan Patrick (mdpatrick) + - Drew Butler (nodrew) + - Pierre-Yves LEBECQ (pylebecq) + - Jan Eichhorn (Exeu) + - Alexander Zogheb + - cim-dch (cim-dch) + - Dan Ordille (dordille) + - Martin Mayer (martinmayer) + - Uwe Jäger (uwej711) + - Baptiste Clavié (Taluu) + - Tuxosaurus (Tuxosaurus) + - Hugo Hamon + - Lenar Lõhmus + - Juan M Martínez + - Alex + - agilemedialab (agilemedialab) + - Alan Chen (alan0101c) + - Masao Maeda (brtriver) + - clemens-tolboom (clemens-tolboom) + - Gustavo Falco (comfortablynumb) + - Denis Klementjev (dklementjev) + - Kévin Dunglas (dunglas) + - Gabriel Birke (gbirke) + - Osman Üngür (import) + - Robert Campbell (jayrulez) + - Gábor Fási (maerlyn) + - Matthew Davis (mdavis1982) + - Matt Lehner (mlehner) + - Jimmy Leger (redpanda) + - Nicolas A. Bérard-Nault + - Alexey Popkov + - Arnaud Buathier (arnapou) + - chesteroni (chesteroni) + - Elnur Abdurrakhimov (elnur) + - Beau Simensen (simensen) + - Till Klampaeckel (till) + - Juan Ases García (Ases) + - Eugene Babushkin (EugeneBabushkin) + - Fabien D. (FabienD) + - Matt Drollette (MDrollette) + - Matthieu Moquet (MattKetmo) + - Kornienko Alexander (Skorney) + - Vincent (Vincent-P) + - Drew Butler + - Pierre-Louis LAUNAY + - Sébastien HOUZE + - Sergiy Sokolenko + - Adrien Brault (adrienbrault) + - Vladimir Sazhin (cannie) + - Chris Sedlmayr (catchamonkey) + - Christian Stocker (chregu) + - chx (chx) + - Luis Cordova (cordoval) + - Damien Alexandre (damienalexandre) + - Damon Jones (damonjones) + - ds (dantleech) + - Djama Suemenich (djama) + - Daniel Londero (dlondero) + - Kyle Wild (dorkitude) + - David Soria Parra (dsp) + - Kousuke Ebihara (ebihara) + - ideea (ideea) + - Jérémy CROMBEZ (jcrombez) + - Johannes (johannes85) + - Justin Rainbow (justinrainbow) + - Abdulkadir N. A. (kadeer) + - Krzysztof Menżyk (krymen) + - kwiateusz (kwiateusz) + - Samuel Laulhau (lalop) + - Matt Fitzgerald (matthewfitz) + - Penny Leach (mjollnir) + - Marc Abramowitz (msabramo) + - Michael Schneider (mschneid) + - Oncle Tom (oncletom) + - ouardisoft (ouardisoft) + - Petr Jaroš (petajaros) + - pzwosta (pzwosta) + - Julien 'ruian' Galenski (ruian) + - Ruud Kamphuis (ruudk) + - Markus Tacker (tacker) + - Tyler Stroud (tystr) + - Vyacheslav Slinko (vslinko) + - Josiah (web-dev) + - Gustavo Adrian + - max + - Muharrem Demirci (mdemirci) + - meze (meze) + - Nicolas de Marqué Fromentin (nicodmf) + - Florent Cailhol (ooflorent) + - Pierre (ptheg) diff --git a/vendor/symfony/symfony/LICENSE b/vendor/symfony/symfony/LICENSE new file mode 100644 index 0000000..cdffe7a --- /dev/null +++ b/vendor/symfony/symfony/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 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/symfony/UPGRADE-2.1.md b/vendor/symfony/symfony/UPGRADE-2.1.md new file mode 100644 index 0000000..3389cf0 --- /dev/null +++ b/vendor/symfony/symfony/UPGRADE-2.1.md @@ -0,0 +1,1094 @@ +UPGRADE FROM 2.0 to 2.1 +======================= + +### General + + * The merging strategy for `assets_base_urls` and `base_urls` has changed. + + Unlike most configuration blocks, successive values for `assets_base_urls` + will overwrite each other instead of being merged. This behavior was chosen + because developers will typically define base URL's for each environment. + Given that most projects tend to inherit configurations (e.g. + `config_test.yml` imports `config_dev.yml`) and/or share a common base + configuration (i.e. `config.yml`), merging could yield a set of base URL's + for multiple environments. + +### Doctrine + + * The DoctrineBundle is moved from the Symfony repository to the Doctrine repository. + Therefore you should change the namespace of this bundle in your AppKernel.php: + + Before: `new Symfony\Bundle\DoctrineBundle\DoctrineBundle()` + After: `new Doctrine\Bundle\DoctrineBundle\DoctrineBundle()` + +### HttpFoundation + + * Locale management was moved from the Session class to the Request class. + + ##### Configuring the default locale + + Before: + + ``` + framework: + session: + default_locale: fr + ``` + + After: + + ``` + framework: + default_locale: fr + ``` + + * The methods `getPathInfo()`, `getBaseUrl()` and `getBasePath()` of + a `Request` now all return a raw value (vs a urldecoded value before). Any call + to one of these methods must be checked and wrapped in a `rawurldecode()` if + needed. + + ##### Retrieving the locale from a Twig template + + Before: `{{ app.request.session.locale }}` or `{{ app.session.locale }}` + + After: `{{ app.request.locale }}` + + ##### Retrieving the locale from a PHP template + + Before: `$view['session']->getLocale()` + + After: `$view['request']->getLocale()` + + ##### Retrieving the locale from PHP code + + Before: `$session->getLocale()` + + After: `$request->getLocale()` + +### Security + + * `Symfony\Component\Security\Core\User\UserInterface::equals()` has moved to + `Symfony\Component\Security\Core\User\EquatableInterface::isEqualTo()`. + + You must rename the `equals()` method in your implementation of the `User` + class to `isEqualTo()` and implement `EquatableInterface`. Apart from that, + no other changes are required. + + Alternatively, you may use the default implementation provided by + `AbstractToken::hasUserChanged()` if you have no need of custom comparison + logic. In this case, do not implement `EquatableInterface` and remove your + comparison method. + + Before: + + ``` + class User implements UserInterface + { + // ... + public function equals(UserInterface $user) { /* ... */ } + // ... + } +``` + + After: + + ``` + class User implements UserInterface, EquatableInterface + { + // ... + public function isEqualTo(UserInterface $user) { /* ... */ } + // ... + } + ``` + * The custom factories for the firewall configuration are now + registered during the build method of bundles instead of being registered + by the end-user. This means that you will you need to remove the 'factories' + keys in your security configuration. + + * The Firewall listener is now registered after the Router listener. This + means that specific Firewall URLs (like /login_check and /logout) must now + have proper routes defined in your routing configuration. + + * The user provider configuration has been refactored. The configuration + for the chain provider and the memory provider has been changed: + + Before: + + ``` yaml + security: + providers: + my_chain_provider: + providers: [my_memory_provider, my_doctrine_provider] + my_memory_provider: + users: + toto: { password: foobar, roles: [ROLE_USER] } + foo: { password: bar, roles: [ROLE_USER, ROLE_ADMIN] } + ``` + + After: + + ``` yaml + security: + providers: + my_chain_provider: + chain: + providers: [my_memory_provider, my_doctrine_provider] + my_memory_provider: + memory: + users: + toto: { password: foobar, roles: [ROLE_USER] } + foo: { password: bar, roles: [ROLE_USER, ROLE_ADMIN] } + ``` + + * `MutableAclInterface::setParentAcl` now accepts `null`, review any + implementations of this interface to reflect this change. + + * The `UserPassword` constraint has moved from the Security Bundle to the Security Component: + + Before: + + ``` + use Symfony\Bundle\SecurityBundle\Validator\Constraint\UserPassword; + use Symfony\Bundle\SecurityBundle\Validator\Constraint as SecurityAssert; + ``` + + After: + + ``` + use Symfony\Component\Security\Core\Validator\Constraint\UserPassword; + use Symfony\Component\Security\Core\Validator\Constraint as SecurityAssert; + ``` + +### Form + +#### BC Breaks in Form Types and Options + + * A third argument `$options` was added to the methods `buildView()` and + `buildViewBottomUp()` in `FormTypeInterface` and `FormTypeExtensionInterface`. + Furthermore, `buildViewBottomUp()` was renamed to `finishView()`. At last, + all methods in these types now receive instances of `FormBuilderInterface` + and `FormViewInterface` where they received instances of `FormBuilder` and + `FormView` before. You need to change the method signatures in your + form types and extensions as shown below. + + Before: + + ``` + use Symfony\Component\Form\FormBuilder; + use Symfony\Component\Form\FormView; + + public function buildForm(FormBuilder $builder, array $options) + public function buildView(FormView $view, FormInterface $form) + public function buildViewBottomUp(FormView $view, FormInterface $form) + ``` + + After: + + ``` + use Symfony\Component\Form\FormBuilderInterface; + use Symfony\Component\Form\FormViewInterface; + + public function buildForm(FormBuilderInterface $builder, array $options) + public function buildView(FormViewInterface $view, FormInterface $form, array $options) + public function finishView(FormViewInterface $view, FormInterface $form, array $options) + ``` + + * No options are passed to `getParent()` of `FormTypeInterface` anymore. If + you previously dynamically inherited from `FormType` or `FieldType`, you can now + dynamically set the "compound" option instead. + + Before: + + ``` + public function getParent(array $options) + { + return $options['expanded'] ? 'form' : 'field'; + } + ``` + + After: + + ``` + use Symfony\Component\OptionsResolver\OptionsResolverInterface; + use Symfony\Component\OptionsResolver\Options; + + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $compound = function (Options $options) { + return $options['expanded']; + }; + + $resolver->setDefaults(array( + 'compound' => $compound, + )); + } + + public function getParent() + { + return 'form'; + } + ``` + + The new method `setDefaultOptions` is described in the section "Deprecations". + + * The "data_class" option now *must* be set if a form maps to an object. If + you leave it empty, the form will expect an array, an instance of \ArrayAccess + or a scalar value and fail with a corresponding exception. + + Likewise, if a form maps to an array or an instance of \ArrayAccess, the option + *must* be left null now. + + Form mapped to an instance of `Person`: + + ``` + use Symfony\Component\OptionsResolver\OptionsResolverInterface; + + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $resolver->setDefaults(array( + 'data_class' => 'Acme\Demo\Person', + )); + } + ``` + + * The mapping of property paths to arrays has changed. + + Previously, a property path "street" mapped to both a field `$street` of + a class (or its accessors `getStreet()` and `setStreet()`) and an index + `['street']` of an array or an object implementing `\ArrayAccess`. + + Now, the property path "street" only maps to a class field (or accessors), + while the property path "[street]" only maps to indices. + + If you defined property paths manually in the "property_path" option, you + should revise them and adjust them if necessary. + + Before: + + ``` + $builder->add('name', 'text', array( + 'property_path' => 'address.street', + )); + ``` + + After (if the address object is an array): + + ``` + $builder->add('name', 'text', array( + 'property_path' => 'address[street]', + )); + ``` + + If address is an object in this case, the code given in "Before" + works without changes. + + * The methods in class `FormView` were renamed to match the naming used in + `Form` and `FormBuilder`. The following list shows the old names on the + left and the new names on the right: + + * `set`: `setVar` + * `has`: `hasVar` + * `get`: `getVar` + * `all`: `getVars` + * `addChild`: `add` + * `getChild`: `get` + * `getChildren`: `all` + * `removeChild`: `remove` + * `hasChild`: `has` + + The new method `addVars` was added to make the definition of multiple + variables at once more convenient. + + The method `hasChildren` was deprecated. You should use `count` instead. + + Before: + + ``` + $view->set('help', 'A text longer than six characters'); + $view->set('error_class', 'max_length_error'); + ``` + + After: + + ``` + $view->addVars(array( + 'help' => 'A text longer than six characters', + 'error_class' => 'max_length_error', + )); + ``` + + * Form and field names must now start with a letter, digit or underscore + and only contain letters, digits, underscores, hyphens and colons. + + * In the collection type's template, the default name of the prototype field + has changed from `$$name$$` to `__name__`. + + For custom names, dollar signs are no longer prepended and appended. You are + advised to prepend and append two underscores wherever you specify a value + for the field's "prototype_name" option. + + Before: + + ``` + $builder->add('tags', 'collection', array('prototype' => 'proto')); + + // results in the name "$$proto$$" in the template + ``` + + After: + + ``` + $builder->add('tags', 'collection', array('prototype' => '__proto__')); + + // results in the name "__proto__" in the template + ``` + + * The "read_only" option now renders as `readonly="readonly"`, use + "disabled" instead for `disabled="disabled"`. + + * Child forms are no longer automatically validated. That means that you must + explicitly set the `Valid` constraint in your model if you want to validate + objects modified by child forms. + + If you don't want to set the `Valid` constraint, or if there is no reference + from the data of the parent form to the data of the child form, you can + enable BC behavior by setting the "cascade_validation" option to `true` + on the parent form. + +#### BC Breaks in Themes and HTML + + * FormType and FieldType were merged and require you to adapt your form + themes. + + The block `field_widget` and all references to it should be renamed to + `form_widget_simple`: + + Before: + + ``` + {% block url_widget %} + {% spaceless %} + {% set type = type|default('url') %} + {{ block('field_widget') }} + {% endspaceless %} + {% endblock url_widget %} + ``` + + After: + + ``` + {% block url_widget %} + {% spaceless %} + {% set type = type|default('url') %} + {{ block('form_widget_simple') }} + {% endspaceless %} + {% endblock url_widget %} + ``` + + All other `field_*` blocks and references to them should be renamed to + `form_*`. If you previously defined both a `field_*` and a `form_*` + block, you can merge them into a single `form_*` block and check the new + Boolean variable `compound` instead: + + Before: + + ``` + {% block form_errors %} + {% spaceless %} + ... form code ... + {% endspaceless %} + {% endblock form_errors %} + + {% block field_errors %} + {% spaceless %} + ... field code ... + {% endspaceless %} + {% endblock field_errors %} + ``` + + After: + + ``` + {% block form_errors %} + {% spaceless %} + {% if compound %} + ... form code ... + {% else %} + ... field code ... + {% endif %} + {% endspaceless %} + {% endblock form_errors %} + ``` + + Furthermore, the block `generic_label` was merged into `form_label`. You + should now override `form_label` in order to customize labels. + + Last but not least, the block `widget_choice_options` was renamed to + `choice_widget_options` to be consistent with the rest of the default + theme. + + * The strategy for generating the `id` and `name` HTML attributes for + checkboxes and radio buttons in a choice field has changed. + + Instead of appending the choice value, a generated integer is now appended + by default. Take care if your JavaScript relies on that. If you want to + read the actual choice value, read the `value` attribute instead. + + * In the choice field type's template, the structure of the `choices` variable + has changed. + + The `choices` variable now contains `ChoiceView` objects with two getters, + `getValue()` and `getLabel()`, to access the choice data. + + Before: + + ``` + {% for choice, label in choices %} + + {% endfor %} + ``` + + After: + + ``` + {% for choice in choices %} + + {% endfor %} + ``` + +#### Other BC Breaks + + * The order of the first two arguments of the methods `createNamed` and + `createNamedBuilder` in `FormFactoryInterface` was reversed to be + consistent with the rest of the component. You should scan your code + for occurrences of these methods and reverse the parameters. + + Before: + + ``` + $form = $factory->createNamed('text', 'firstName'); + ``` + + After: + + ``` + $form = $factory->createNamed('firstName', 'text'); + ``` + + * The implementation of `ChoiceList` was changed heavily. As a result, + `ArrayChoiceList` was replaced. If you have custom classes that extend + this class, you must now extend `SimpleChoiceList` and pass choices + to the parent constructor. + + Before: + + ``` + class MyChoiceList extends ArrayChoiceList + { + protected function load() + { + parent::load(); + + // load choices + + $this->choices = $choices; + } + } + ``` + + After: + + ``` + class MyChoiceList extends SimpleChoiceList + { + public function __construct() + { + // load choices + + parent::__construct($choices); + } + } + ``` + + If you need to load the choices lazily -- that is, as soon as they are + accessed for the first time -- you can extend `LazyChoiceList` instead + and load the choices by overriding `loadChoiceList()`. + + ``` + class MyChoiceList extends LazyChoiceList + { + protected function loadChoiceList() + { + // load choices + + return new SimpleChoiceList($choices); + } + } + ``` + + `PaddedChoiceList`, `MonthChoiceList` and `TimezoneChoiceList` were removed. + Their functionality was merged into `DateType`, `TimeType` and `TimezoneType`. + + `EntityChoiceList` was adapted. The methods `getEntities()`, + `getEntitiesByKeys()`, `getIdentifier()` and `getIdentifierValues()` were + removed or made private. Instead of the first two, you can now use + `getChoices()` and `getChoicesByValues()`. For the latter two, no + replacement exists. + + * `EntitiesToArrayTransformer` and `EntityToIdTransformer` were removed. + The former was replaced by `CollectionToArrayTransformer` in combination + with `EntityChoiceList`, the latter is not required in the core anymore. + + * The following transformers were renamed: + + * `ArrayToBooleanChoicesTransformer` to `ChoicesToBooleanArrayTransformer` + * `ScalarToBooleanChoicesTransformer` to `ChoiceToBooleanArrayTransformer` + * `ArrayToChoicesTransformer` to `ChoicesToValuesTransformer` + * `ScalarToChoiceTransformer` to `ChoiceToValueTransformer` + + to be consistent with the naming in `ChoiceListInterface`. + + * `FormUtil::toArrayKey()` and `FormUtil::toArrayKeys()` were removed. + They were merged into ChoiceList and have no public equivalent anymore. + + * The `add()`, `remove()`, `setParent()`, `bind()` and `setData()` methods in + the Form class now throw an exception if the form is already bound. + + If you used these methods on bound forms, you should consider moving your + logic to an event listener that observes `FormEvents::PRE_BIND` or + `FormEvents::BIND`. + +#### Deprecations + + * The following methods of `FormTypeInterface` and `FormTypeExtensionInterface` + are deprecated and will be removed in Symfony 2.3: + + * `getDefaultOptions` + * `getAllowedOptionValues` + + You should use the newly added `setDefaultOptions` instead, which gives you + access to the OptionsResolverInterface instance and with that a lot more power. + + Before: + + ``` + public function getDefaultOptions(array $options) + { + return array( + 'gender' => 'male', + ); + } + + public function getAllowedOptionValues(array $options) + { + return array( + 'gender' => array('male', 'female'), + ); + } + ``` + + After: + + ``` + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $resolver->setDefaults(array( + 'gender' => 'male', + )); + + $resolver->setAllowedValues(array( + 'gender' => array('male', 'female'), + )); + } + ``` + + You can specify options that depend on other options using closures. + + Before: + + ``` + public function getDefaultOptions(array $options) + { + $defaultOptions = array(); + + if ($options['multiple']) { + $defaultOptions['empty_data'] = array(); + } + + return $defaultOptions; + } + ``` + + After: + + ``` + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $resolver->setDefaults(array( + 'empty_data' => function (Options $options, $value) { + return $options['multiple'] ? array() : $value; + } + )); + } + ``` + + The second argument `$value` contains the current default value and + does not have to be specified if not needed. + + * The following methods in `FormBuilder` were deprecated and have a new + equivalent: + + * `prependClientTransformer`: `addViewTransformer`, with `true` as second argument + * `appendClientTransformer`: `addViewTransformer` + * `getClientTransformers`: `getViewTransformers` + * `resetClientTransformers`: `resetViewTransformers` + * `prependNormTransformer`: `addModelTransformer` + * `appendNormTransformer`: `addModelTransformer`, with `true` as second argument + * `getNormTransformers`: `getModelTransformers` + * `resetNormTransformers`: `resetModelTransformers` + + The deprecated methods will be removed in Symfony 2.3. You are advised to + update your application. + + Before: + + ``` + $builder->appendClientTransformer(new MyTransformer()); + ``` + + After: + + ``` + $builder->addViewTransformer(new MyTransformer()); + ``` + + * The following events were deprecated and have a new equivalent: + + * `FormEvents::SET_DATA`: `FormEvents::PRE_SET_DATA` + * `FormEvents::BIND_CLIENT_DATA`: `FormEvents::PRE_BIND` + * `FormEvents::BIND_NORM_DATA`: `FormEvents::BIND` + + The deprecated events will be removed in Symfony 2.3. + + Furthermore, the event classes `DataEvent` and `FilterDataEvent` were + deprecated and replaced by the generic `FormEvent`. You are advised to + code your listeners against the new event now. The deprecated events will + be removed in Symfony 2.3. + + Before: + + ``` + $builder->addListener(FormEvents::BIND_CLIENT_DATA, function (FilterDataEvent $event) { + // ... + }); + ``` + + After: + + ``` + $builder->addListener(FormEvents::PRE_BIND, function (FormEvent $event) { + // ... + }); + ``` + + * The interface `FormValidatorInterface` was deprecated and will be removed + in Symfony 2.3. + + If you implemented custom validators using this interface, you can + substitute them by event listeners listening to the `FormEvents::POST_BIND` + (or any other of the `*BIND` events). In case you used the CallbackValidator + class, you should now pass the callback directly to `addEventListener`. + + * The method `guessMinLength()` of `FormTypeGuesserInterface` was deprecated + and will be removed in Symfony 2.3. You should use the new method + `guessPattern()` instead which may return any regular expression that + is inserted in the HTML5 attribute `pattern`. + + Before: + + ``` + public function guessMinLength($class, $property) + { + if (/* condition */) { + return new ValueGuess($minLength, Guess::LOW_CONFIDENCE); + } + } + ``` + + After: + + ``` + public function guessPattern($class, $property) + { + if (/* condition */) { + return new ValueGuess('.{' . $minLength . ',}', Guess::LOW_CONFIDENCE); + } + } + ``` + + * Setting the option "property_path" to `false` was deprecated and will be unsupported + as of Symfony 2.3. + + You should use the new option "mapped" instead in order to set that you don't want + a field to be mapped to its parent's data. + + Before: + + ``` + $builder->add('termsAccepted', 'checkbox', array( + 'property_path' => false, + )); + ``` + + After: + + ``` + $builder->add('termsAccepted', 'checkbox', array( + 'mapped' => false, + )); + ``` + + * The following methods in `Form` were deprecated and will be removed in + Symfony 2.3: + + * `getTypes` + * `getErrorBubbling` + * `getNormTransformers` + * `getClientTransformers` + * `getAttribute` + * `hasAttribute` + * `getClientData` + * `getChildren` + * `hasChildren` + + Before: + + ``` + $form->getErrorBubbling() + ``` + + After: + + ``` + $form->getConfig()->getErrorBubbling(); + ``` + + The method `getClientData` has a new equivalent that is named `getViewData`. + You can access all other methods on the `FormConfigInterface` object instead. + + Instead of `getChildren` and `hasChildren`, you should now use `all` and + `count`. + + Before: + + ``` + if ($form->hasChildren()) { + ``` + + After: + + ``` + if (count($form) > 0) { + ``` + + * The option "validation_constraint" was deprecated and will be removed + in Symfony 2.3. You should use the option "constraints" instead, + where you can pass one or more constraints for a form. + + Before: + + ``` + $builder->add('name', 'text', array( + 'validation_constraint' => new NotBlank(), + )); + ``` + + After: + + ``` + $builder->add('name', 'text', array( + 'constraints' => new NotBlank(), + )); + ``` + + Unlike previously, you can also pass a list of constraints now: + + ``` + $builder->add('name', 'text', array( + 'constraints' => array( + new NotBlank(), + new MinLength(3), + ), + )); + ``` + +### Validator + + * The methods `setMessage()`, `getMessageTemplate()` and + `getMessageParameters()` in the Constraint class were deprecated and will + be removed in Symfony 2.3. + + If you have implemented custom validators, you should use the + `addViolation()` method on the `ExecutionContext` object instead. + + Before: + + ``` + public function isValid($value, Constraint $constraint) + { + // ... + if (!$valid) { + $this->setMessage($constraint->message, array( + '{{ value }}' => $value, + )); + + return false; + } + } + ``` + + After: + + ``` + public function isValid($value, Constraint $constraint) + { + // ... + if (!$valid) { + $this->context->addViolation($constraint->message, array( + '{{ value }}' => $value, + )); + + return false; + } + } + ``` + + * The method `setPropertyPath()` in the ExecutionContext class + was removed. + + You should use the `addViolationAtSubPath()` method on the + `ExecutionContext` object instead. + + Before: + + ``` + public function isPropertyValid(ExecutionContext $context) + { + // ... + $propertyPath = $context->getPropertyPath() . '.property'; + $context->setPropertyPath($propertyPath); + $context->addViolation('Error Message', array(), null); + } + ``` + + After: + + ``` + public function isPropertyValid(ExecutionContext $context) + { + // ... + $context->addViolationAtSubPath('property', 'Error Message', array(), null); + + } + ``` + + * The method `isValid` of `ConstraintValidatorInterface` was renamed to + `validate` and its return value was dropped. + + `ConstraintValidator` still contains the deprecated `isValid` method and + forwards `validate` calls to `isValid` by default. This BC layer will be + removed in Symfony 2.3. You are advised to rename your methods. You should + also remove the return values, which have never been used by the framework. + + Before: + + ``` + public function isValid($value, Constraint $constraint) + { + // ... + if (!$valid) { + $this->context->addViolation($constraint->message, array( + '{{ value }}' => $value, + )); + + return false; + } + } + ``` + + After: + + ``` + public function validate($value, Constraint $constraint) + { + // ... + if (!$valid) { + $this->context->addViolation($constraint->message, array( + '{{ value }}' => $value, + )); + + return; + } + } + ``` + + * Core translation messages are changed. Dot is added at the end of each message. + Overwritten core translations should be fixed if any. More info here. + + * Collections (arrays or instances of `\Traversable`) in properties + annotated with `Valid` are not traversed recursively by default anymore. + + This means that if a collection contains an entry which is again a + collection, the inner collection won't be traversed anymore as it + happened before. You can set the BC behavior by setting the new property + `deep` of `Valid` to `true`. + + Before: + + ``` + /** @Assert\Valid */ + private $recursiveCollection; + ``` + + After: + + ``` + /** @Assert\Valid(deep = true) */ + private $recursiveCollection; + ``` + +### Session + + * Flash messages now return an array based on their type. The old method is + still available but is now deprecated. + + ##### Retrieving the flash messages from a Twig template + + Before: + + ``` + {% if app.session.hasFlash('notice') %} +
    + {{ app.session.getFlash('notice') }} +
    + {% endif %} + ``` + After: + + ``` + {% for flashMessage in app.session.flashbag.get('notice') %} +
    + {{ flashMessage }} +
    + {% endfor %} + ``` + + You can process all flash messages in a single loop with: + + ``` + {% for type, flashMessages in app.session.flashbag.all() %} + {% for flashMessage in flashMessages %} +
    + {{ flashMessage }} +
    + {% endfor %} + {% endfor %} + ``` + + * Session handler drivers should implement `\SessionHandlerInterface` or extend from + `Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeHandlerInterface` base class and renamed + to `Handler\FooSessionHandler`. E.g. `PdoSessionStorage` becomes `Handler\PdoSessionHandler`. + + * Refactor code using `$session->*flash*()` methods to use `$session->getFlashBag()->*()`. + +### Serializer + + * The key names created by the `GetSetMethodNormalizer` have changed from + from all lowercased to camelCased (e.g. `mypropertyvalue` to `myPropertyValue`). + + * The `item` element is now converted to an array when deserializing XML. + + ``` xml + + + <![CDATA[title1]]><![CDATA[title2]]> + + ``` + + Before: + + Array() + + After: + + Array( + [item] => Array( + [0] => Array( + [title] => title1 + ) + [1] => Array( + [title] => title2 + ) + ) + ) + +### Routing + + * The UrlMatcher urldecodes the route parameters only once, they were + decoded twice before. Note that the `urldecode()` calls have been changed for a + single `rawurldecode()` in order to support `+` for input paths. + +### FrameworkBundle + + * session options: lifetime, path, domain, secure, httponly were deprecated. + Prefixed versions should now be used instead: cookie_lifetime, cookie_path, cookie_domain, cookie_secure, cookie_httponly + + Before: + + ``` + framework: + session: + lifetime: 3600 + path: \ + domain: example.com + secure: true + httponly: true + ``` + + After: + + ``` + framework: + session: + cookie_lifetime: 3600 + cookie_path: \ + cookie_domain: example.com + cookie_secure: true + cookie_httponly: true + ``` + +Added `handler_id`, defaults to `session.handler.native_file`. + + ``` + framework: + session: + storage_id: session.storage.native + handler_id: session.handler.native_file + ``` + +To use mock session storage use the following. `handler_id` is irrelevant in this context. + + ``` + framework: + session: + storage_id: session.storage.mock_file + ``` + +### WebProfilerBundle + + * You must clear old profiles after upgrading to 2.1. If you are using a + database then you will need to remove the table. diff --git a/vendor/symfony/symfony/autoload.php.dist b/vendor/symfony/symfony/autoload.php.dist new file mode 100644 index 0000000..cd8bbc5 --- /dev/null +++ b/vendor/symfony/symfony/autoload.php.dist @@ -0,0 +1,22 @@ +add('IntlDateFormatter', __DIR__.'/src/Symfony/Component/Locale/Resources/stubs'); + $loader->add('Collator', __DIR__.'/src/Symfony/Component/Locale/Resources/stubs'); + $loader->add('Locale', __DIR__.'/src/Symfony/Component/Locale/Resources/stubs'); + $loader->add('NumberFormatter', __DIR__.'/src/Symfony/Component/Locale/Resources/stubs'); +} + +AnnotationRegistry::registerLoader(array($loader, 'loadClass')); +AnnotationRegistry::registerFile(__DIR__.'/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php'); + +if (is_file(__DIR__.'/vendor/swiftmailer/swiftmailer/lib/classes/Swift.php')) { + require_once __DIR__.'/vendor/swiftmailer/swiftmailer/lib/classes/Swift.php'; + Swift::registerAutoload(__DIR__.'/vendor/swiftmailer/swiftmailer/lib/swift_init.php'); +} diff --git a/vendor/symfony/symfony/composer.json b/vendor/symfony/symfony/composer.json new file mode 100644 index 0000000..5ff6c07 --- /dev/null +++ b/vendor/symfony/symfony/composer.json @@ -0,0 +1,75 @@ +{ + "name": "symfony/symfony", + "type": "library", + "description": "The Symfony PHP framework", + "keywords": ["framework"], + "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", + "doctrine/common": ">2.2,<2.4-dev", + "twig/twig": ">=1.8,<2.0-dev" + }, + "replace": { + "symfony/doctrine-bridge": "self.version", + "symfony/monolog-bridge": "self.version", + "symfony/propel1-bridge": "self.version", + "symfony/swiftmailer-bridge": "self.version", + "symfony/twig-bridge": "self.version", + "symfony/framework-bundle": "self.version", + "symfony/security-bundle": "self.version", + "symfony/twig-bundle": "self.version", + "symfony/web-profiler-bundle": "self.version", + "symfony/browser-kit": "self.version", + "symfony/class-loader": "self.version", + "symfony/config": "self.version", + "symfony/console": "self.version", + "symfony/css-selector": "self.version", + "symfony/dependency-injection": "self.version", + "symfony/dom-crawler": "self.version", + "symfony/event-dispatcher": "self.version", + "symfony/filesystem": "self.version", + "symfony/finder": "self.version", + "symfony/form": "self.version", + "symfony/http-foundation": "self.version", + "symfony/http-kernel": "self.version", + "symfony/locale": "self.version", + "symfony/options-resolver": "self.version", + "symfony/process": "self.version", + "symfony/routing": "self.version", + "symfony/security": "self.version", + "symfony/serializer": "self.version", + "symfony/templating": "self.version", + "symfony/translation": "self.version", + "symfony/validator": "self.version", + "symfony/yaml": "self.version" + }, + "require-dev": { + "doctrine/dbal": ">=2.2,<2.4-dev", + "doctrine/orm": ">=2.2,<2.4-dev", + "doctrine/data-fixtures": "1.0.*", + "propel/propel1": "dev-master", + "monolog/monolog": "dev-master" + }, + "autoload": { + "psr-0": { + "Symfony": "src/", + "SessionHandlerInterface": "src/Symfony/Component/HttpFoundation/Resources/stubs" + } + }, + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/CHANGELOG.md b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/CHANGELOG.md new file mode 100644 index 0000000..1a5334e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/CHANGELOG.md @@ -0,0 +1,9 @@ +CHANGELOG +========= + +2.1.0 +----- + + * added a default implementation of the ManagerRegistry + * added a session storage for Doctrine DBAL + * DoctrineOrmTypeGuesser now guesses "collection" for array Doctrine type diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/CacheWarmer/ProxyCacheWarmer.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/CacheWarmer/ProxyCacheWarmer.php new file mode 100644 index 0000000..f57d8fa --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/CacheWarmer/ProxyCacheWarmer.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\Bridge\Doctrine\CacheWarmer; + +use Doctrine\Common\Persistence\ManagerRegistry; +use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface; + +/** + * The proxy generator cache warmer generates all entity proxies. + * + * In the process of generating proxies the cache for all the metadata is primed also, + * since this information is necessary to build the proxies in the first place. + * + * @author Benjamin Eberlei + */ +class ProxyCacheWarmer implements CacheWarmerInterface +{ + private $registry; + + /** + * Constructor. + * + * @param ManagerRegistry $registry A ManagerRegistry instance + */ + public function __construct(ManagerRegistry $registry) + { + $this->registry = $registry; + } + + /** + * This cache warmer is not optional, without proxies fatal error occurs! + * + * @return false + */ + public function isOptional() + { + return false; + } + + public function warmUp($cacheDir) + { + foreach ($this->registry->getManagers() as $em) { + // we need the directory no matter the proxy cache generation strategy + if (!is_dir($proxyCacheDir = $em->getConfiguration()->getProxyDir())) { + if (false === @mkdir($proxyCacheDir, 0777, true)) { + throw new \RuntimeException(sprintf('Unable to create the Doctrine Proxy directory "%s".', $proxyCacheDir)); + } + } elseif (!is_writable($proxyCacheDir)) { + throw new \RuntimeException(sprintf('The Doctrine Proxy directory "%s" is not writeable for the current system user.', $proxyCacheDir)); + } + + // if proxies are autogenerated we don't need to generate them in the cache warmer + if ($em->getConfiguration()->getAutoGenerateProxyClasses()) { + continue; + } + + $classes = $em->getMetadataFactory()->getAllMetadata(); + + $em->getProxyFactory()->generateProxyClasses($classes); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/ContainerAwareEventManager.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/ContainerAwareEventManager.php new file mode 100644 index 0000000..eb0dc05 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/ContainerAwareEventManager.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\Bridge\Doctrine; + +use Doctrine\Common\EventArgs; +use Doctrine\Common\EventManager; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Allows lazy loading of listener services. + * + * @author Johannes M. Schmitt + */ +class ContainerAwareEventManager extends EventManager +{ + /** + * Map of registered listeners. + * => + * + * @var array + */ + private $listeners = array(); + private $initialized = array(); + private $container; + + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + /** + * Dispatches an event to all registered listeners. + * + * @param string $eventName The name of the event to dispatch. The name of the event is + * the name of the method that is invoked on listeners. + * @param EventArgs $eventArgs The event arguments to pass to the event handlers/listeners. + * If not supplied, the single empty EventArgs instance is used. + * @return boolean + */ + public function dispatchEvent($eventName, EventArgs $eventArgs = null) + { + if (isset($this->listeners[$eventName])) { + $eventArgs = $eventArgs === null ? EventArgs::getEmptyInstance() : $eventArgs; + + $initialized = isset($this->initialized[$eventName]); + + foreach ($this->listeners[$eventName] as $hash => $listener) { + if (!$initialized && is_string($listener)) { + $this->listeners[$eventName][$hash] = $listener = $this->container->get($listener); + } + + $listener->$eventName($eventArgs); + } + $this->initialized[$eventName] = true; + } + } + + /** + * Gets the listeners of a specific event or all listeners. + * + * @param string $event The name of the event. + * @return array The event listeners for the specified event, or all event listeners. + */ + public function getListeners($event = null) + { + return $event ? $this->listeners[$event] : $this->listeners; + } + + /** + * Checks whether an event has any registered listeners. + * + * @param string $event + * @return boolean TRUE if the specified event has any listeners, FALSE otherwise. + */ + public function hasListeners($event) + { + return isset($this->listeners[$event]) && $this->listeners[$event]; + } + + /** + * Adds an event listener that listens on the specified events. + * + * @param string|array $events The event(s) to listen on. + * @param object|string $listener The listener object. + */ + public function addEventListener($events, $listener) + { + if (is_string($listener)) { + if ($this->initialized) { + throw new \RuntimeException('Adding lazy-loading listeners after construction is not supported.'); + } + + $hash = '_service_'.$listener; + } else { + // Picks the hash code related to that listener + $hash = spl_object_hash($listener); + } + + foreach ((array) $events as $event) { + // Overrides listener if a previous one was associated already + // Prevents duplicate listeners on same event (same instance only) + $this->listeners[$event][$hash] = $listener; + } + } + + /** + * Removes an event listener from the specified events. + * + * @param string|array $events + * @param object|string $listener + */ + public function removeEventListener($events, $listener) + { + if (is_string($listener)) { + $hash = '_service_'.$listener; + } else { + // Picks the hash code related to that listener + $hash = spl_object_hash($listener); + } + + foreach ((array) $events as $event) { + // Check if actually have this listener associated + if (isset($this->listeners[$event][$hash])) { + unset($this->listeners[$event][$hash]); + } + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php new file mode 100644 index 0000000..35979af --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.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\Bridge\Doctrine\DataCollector; + +use Doctrine\Common\Persistence\ManagerRegistry; +use Doctrine\DBAL\Logging\DebugStack; +use Doctrine\DBAL\Types\Type; +use Symfony\Component\HttpKernel\DataCollector\DataCollector; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +/** + * DoctrineDataCollector. + * + * @author Fabien Potencier + */ +class DoctrineDataCollector extends DataCollector +{ + private $registry; + private $connections; + private $managers; + private $loggers = array(); + + public function __construct(ManagerRegistry $registry) + { + $this->registry = $registry; + $this->connections = $registry->getConnectionNames(); + $this->managers = $registry->getManagerNames(); + } + + /** + * Adds the stack logger for a connection. + * + * @param string $name + * @param DebugStack $logger + */ + public function addLogger($name, DebugStack $logger) + { + $this->loggers[$name] = $logger; + } + + /** + * {@inheritdoc} + */ + public function collect(Request $request, Response $response, \Exception $exception = null) + { + $queries = array(); + foreach ($this->loggers as $name => $logger) { + $queries[$name] = $this->sanitizeQueries($name, $logger->queries); + } + + $this->data = array( + 'queries' => $queries, + 'connections' => $this->connections, + 'managers' => $this->managers, + ); + } + + public function getManagers() + { + return $this->data['managers']; + } + + public function getConnections() + { + return $this->data['connections']; + } + + public function getQueryCount() + { + return array_sum(array_map('count', $this->data['queries'])); + } + + public function getQueries() + { + return $this->data['queries']; + } + + public function getTime() + { + $time = 0; + foreach ($this->data['queries'] as $queries) { + foreach ($queries as $query) { + $time += $query['executionMS']; + } + } + + return $time; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'db'; + } + + private function sanitizeQueries($connectionName, $queries) + { + foreach ($queries as $i => $query) { + $queries[$i] = $this->sanitizeQuery($connectionName, $query); + } + + return $queries; + } + + private function sanitizeQuery($connectionName, $query) + { + $query['explainable'] = true; + $query['params'] = (array) $query['params']; + foreach ($query['params'] as $j => &$param) { + if (isset($query['types'][$j])) { + // Transform the param according to the type + $type = $query['types'][$j]; + if (is_string($type)) { + $type = Type::getType($type); + } + if ($type instanceof Type) { + $query['types'][$j] = $type->getBindingType(); + $param = $type->convertToDatabaseValue($param, $this->registry->getConnection($connectionName)->getDatabasePlatform()); + } + } + + list($param, $explainable) = $this->sanitizeParam($param); + if (!$explainable) { + $query['explainable'] = false; + } + } + + return $query; + } + + /** + * Sanitizes a param. + * + * The return value is an array with the sanitized value and a boolean + * indicating if the original value was kept (allowing to use the sanitized + * value to explain the query). + * + * @param mixed $var + * @return array + */ + private function sanitizeParam($var) + { + if (is_object($var)) { + return array(sprintf('Object(%s)', get_class($var)), false); + } + + if (is_array($var)) { + $a = array(); + $original = true; + foreach ($var as $k => $v) { + list($value, $orig) = $this->sanitizeParam($v); + $original = $original && $orig; + $a[$k] = $value; + } + + return array($a, $original); + } + + if (is_resource($var)) { + return array(sprintf('Resource(%s)', get_resource_type($var)), false); + } + + return array($var, true); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DataFixtures/ContainerAwareLoader.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DataFixtures/ContainerAwareLoader.php new file mode 100644 index 0000000..0b10527 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DataFixtures/ContainerAwareLoader.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\Bridge\Doctrine\DataFixtures; + +use Doctrine\Common\DataFixtures\FixtureInterface; +use Doctrine\Common\DataFixtures\Loader; +use Symfony\Component\DependencyInjection\ContainerAwareInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Doctrine data fixtures loader that injects the service container into + * fixture objects that implement ContainerAwareInterface. + * + * Note: Use of this class requires the Doctrine data fixtures extension, which + * is a suggested dependency for Symfony. + */ +class ContainerAwareLoader extends Loader +{ + /** + * @var ContainerInterface + */ + private $container; + + /** + * Constructor. + * + * @param ContainerInterface $container A ContainerInterface instance + */ + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + /** + * {@inheritdoc} + */ + public function addFixture(FixtureInterface $fixture) + { + if ($fixture instanceof ContainerAwareInterface) { + $fixture->setContainer($this->container); + } + + parent::addFixture($fixture); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php new file mode 100644 index 0000000..e9294f9 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php @@ -0,0 +1,383 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\DependencyInjection; + +use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\Config\Resource\FileResource; + +/** + * This abstract classes groups common code that Doctrine Object Manager extensions (ORM, MongoDB, CouchDB) need. + * + * @author Benjamin Eberlei + */ +abstract class AbstractDoctrineExtension extends Extension +{ + /** + * Used inside metadata driver method to simplify aggregation of data. + * + * @var array + */ + protected $aliasMap = array(); + + /** + * Used inside metadata driver method to simplify aggregation of data. + * + * @var array + */ + protected $drivers = array(); + + /** + * @param array $objectManager A configured object manager. + * @param ContainerBuilder $container A ContainerBuilder instance + */ + protected function loadMappingInformation(array $objectManager, ContainerBuilder $container) + { + if ($objectManager['auto_mapping']) { + // automatically register bundle mappings + foreach (array_keys($container->getParameter('kernel.bundles')) as $bundle) { + if (!isset($objectManager['mappings'][$bundle])) { + $objectManager['mappings'][$bundle] = null; + } + } + } + + foreach ($objectManager['mappings'] as $mappingName => $mappingConfig) { + if (null !== $mappingConfig && false === $mappingConfig['mapping']) { + continue; + } + + $mappingConfig = array_replace(array( + 'dir' => false, + 'type' => false, + 'prefix' => false, + ), (array) $mappingConfig); + + $mappingConfig['dir'] = $container->getParameterBag()->resolveValue($mappingConfig['dir']); + // a bundle configuration is detected by realizing that the specified dir is not absolute and existing + if (!isset($mappingConfig['is_bundle'])) { + $mappingConfig['is_bundle'] = !is_dir($mappingConfig['dir']); + } + + if ($mappingConfig['is_bundle']) { + $bundle = null; + foreach ($container->getParameter('kernel.bundles') as $name => $class) { + if ($mappingName === $name) { + $bundle = new \ReflectionClass($class); + + break; + } + } + + if (null === $bundle) { + throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled.', $mappingName)); + } + + $mappingConfig = $this->getMappingDriverBundleConfigDefaults($mappingConfig, $bundle, $container); + if (!$mappingConfig) { + continue; + } + } + + $this->assertValidMappingConfiguration($mappingConfig, $objectManager['name']); + $this->setMappingDriverConfig($mappingConfig, $mappingName); + $this->setMappingDriverAlias($mappingConfig, $mappingName); + } + } + + /** + * Register the alias for this mapping driver. + * + * Aliases can be used in the Query languages of all the Doctrine object managers to simplify writing tasks. + * + * @param array $mappingConfig + * @param string $mappingName + */ + protected function setMappingDriverAlias($mappingConfig, $mappingName) + { + if (isset($mappingConfig['alias'])) { + $this->aliasMap[$mappingConfig['alias']] = $mappingConfig['prefix']; + } else { + $this->aliasMap[$mappingName] = $mappingConfig['prefix']; + } + } + + /** + * Register the mapping driver configuration for later use with the object managers metadata driver chain. + * + * @param array $mappingConfig + * @param string $mappingName + */ + protected function setMappingDriverConfig(array $mappingConfig, $mappingName) + { + if (is_dir($mappingConfig['dir'])) { + $this->drivers[$mappingConfig['type']][$mappingConfig['prefix']] = realpath($mappingConfig['dir']); + } else { + throw new \InvalidArgumentException(sprintf('Invalid Doctrine mapping path given. Cannot load Doctrine mapping/bundle named "%s".', $mappingName)); + } + } + + /** + * If this is a bundle controlled mapping all the missing information can be autodetected by this method. + * + * Returns false when autodetection failed, an array of the completed information otherwise. + * + * @param array $bundleConfig + * @param \ReflectionClass $bundle + * @param ContainerBuilder $container A ContainerBuilder instance + * + * @return array|false + */ + protected function getMappingDriverBundleConfigDefaults(array $bundleConfig, \ReflectionClass $bundle, ContainerBuilder $container) + { + $bundleDir = dirname($bundle->getFilename()); + + if (!$bundleConfig['type']) { + $bundleConfig['type'] = $this->detectMetadataDriver($bundleDir, $container); + } + + if (!$bundleConfig['type']) { + // skip this bundle, no mapping information was found. + return false; + } + + if (!$bundleConfig['dir']) { + if (in_array($bundleConfig['type'], array('annotation', 'staticphp'))) { + $bundleConfig['dir'] = $bundleDir.'/'.$this->getMappingObjectDefaultName(); + } else { + $bundleConfig['dir'] = $bundleDir.'/'.$this->getMappingResourceConfigDirectory(); + } + } else { + $bundleConfig['dir'] = $bundleDir.'/'.$bundleConfig['dir']; + } + + if (!$bundleConfig['prefix']) { + $bundleConfig['prefix'] = $bundle->getNamespaceName().'\\'.$this->getMappingObjectDefaultName(); + } + + return $bundleConfig; + } + + /** + * Register all the collected mapping information with the object manager by registering the appropriate mapping drivers. + * + * @param array $objectManager + * @param ContainerBuilder $container A ContainerBuilder instance + */ + protected function registerMappingDrivers($objectManager, ContainerBuilder $container) + { + // configure metadata driver for each bundle based on the type of mapping files found + if ($container->hasDefinition($this->getObjectManagerElementName($objectManager['name'].'_metadata_driver'))) { + $chainDriverDef = $container->getDefinition($this->getObjectManagerElementName($objectManager['name'].'_metadata_driver')); + } else { + $chainDriverDef = new Definition('%'.$this->getObjectManagerElementName('metadata.driver_chain.class%')); + $chainDriverDef->setPublic(false); + } + + foreach ($this->drivers as $driverType => $driverPaths) { + $mappingService = $this->getObjectManagerElementName($objectManager['name'].'_'.$driverType.'_metadata_driver'); + if ($container->hasDefinition($mappingService)) { + $mappingDriverDef = $container->getDefinition($mappingService); + $args = $mappingDriverDef->getArguments(); + if ($driverType == 'annotation') { + $args[1] = array_merge(array_values($driverPaths), $args[1]); + } else { + $args[0] = array_merge(array_values($driverPaths), $args[0]); + } + $mappingDriverDef->setArguments($args); + } elseif ($driverType == 'annotation') { + $mappingDriverDef = new Definition('%'.$this->getObjectManagerElementName('metadata.'.$driverType.'.class%'), array( + new Reference($this->getObjectManagerElementName('metadata.annotation_reader')), + array_values($driverPaths) + )); + } else { + $mappingDriverDef = new Definition('%'.$this->getObjectManagerElementName('metadata.'.$driverType.'.class%'), array( + array_values($driverPaths) + )); + } + $mappingDriverDef->setPublic(false); + if (false !== strpos($mappingDriverDef->getClass(), 'yml') || false !== strpos($mappingDriverDef->getClass(), 'xml')) { + $mappingDriverDef->setArguments(array(array_flip($driverPaths))); + $mappingDriverDef->addMethodCall('setGlobalBasename', array('mapping')); + } + + $container->setDefinition($mappingService, $mappingDriverDef); + + foreach ($driverPaths as $prefix => $driverPath) { + $chainDriverDef->addMethodCall('addDriver', array(new Reference($mappingService), $prefix)); + } + } + + $container->setDefinition($this->getObjectManagerElementName($objectManager['name'].'_metadata_driver'), $chainDriverDef); + } + + /** + * Assertion if the specified mapping information is valid. + * + * @param array $mappingConfig + * @param string $objectManagerName + */ + protected function assertValidMappingConfiguration(array $mappingConfig, $objectManagerName) + { + if (!$mappingConfig['type'] || !$mappingConfig['dir'] || !$mappingConfig['prefix']) { + throw new \InvalidArgumentException(sprintf('Mapping definitions for Doctrine manager "%s" require at least the "type", "dir" and "prefix" options.', $objectManagerName)); + } + + if (!is_dir($mappingConfig['dir'])) { + throw new \InvalidArgumentException(sprintf('Specified non-existing directory "%s" as Doctrine mapping source.', $mappingConfig['dir'])); + } + + if (!in_array($mappingConfig['type'], array('xml', 'yml', 'annotation', 'php', 'staticphp'))) { + throw new \InvalidArgumentException(sprintf('Can only configure "xml", "yml", "annotation", "php" or '. + '"staticphp" through the DoctrineBundle. Use your own bundle to configure other metadata drivers. '. + 'You can register them by adding a a new driver to the '. + '"%s" service definition.', $this->getObjectManagerElementName($objectManagerName.'.metadata_driver') + )); + } + } + + /** + * Detects what metadata driver to use for the supplied directory. + * + * @param string $dir A directory path + * @param ContainerBuilder $container A ContainerBuilder instance + * + * @return string|null A metadata driver short name, if one can be detected + */ + protected function detectMetadataDriver($dir, ContainerBuilder $container) + { + // add the closest existing directory as a resource + $configPath = $this->getMappingResourceConfigDirectory(); + $resource = $dir.'/'.$configPath; + while (!is_dir($resource)) { + $resource = dirname($resource); + } + + $container->addResource(new FileResource($resource)); + + $extension = $this->getMappingResourceExtension(); + if (($files = glob($dir.'/'.$configPath.'/*.'.$extension.'.xml')) && count($files)) { + return 'xml'; + } elseif (($files = glob($dir.'/'.$configPath.'/*.'.$extension.'.yml')) && count($files)) { + return 'yml'; + } elseif (($files = glob($dir.'/'.$configPath.'/*.'.$extension.'.php')) && count($files)) { + return 'php'; + } + + // add the directory itself as a resource + $container->addResource(new FileResource($dir)); + + if (is_dir($dir.'/'.$this->getMappingObjectDefaultName())) { + return 'annotation'; + } + + return null; + } + + /** + * Loads a configured object manager metadata, query or result cache driver. + * + * @param array $objectManager A configured object manager. + * @param ContainerBuilder $container A ContainerBuilder instance. + * @param string $cacheName + * + * @throws \InvalidArgumentException In case of unknown driver type. + */ + protected function loadObjectManagerCacheDriver(array $objectManager, ContainerBuilder $container, $cacheName) + { + $cacheDriver = $objectManager[$cacheName.'_driver']; + $cacheDriverService = $this->getObjectManagerElementName($objectManager['name'] . '_' . $cacheName); + + switch ($cacheDriver['type']) { + case 'service': + $container->setAlias($cacheDriverService, new Alias($cacheDriver['id'], false)); + + return; + case 'memcache': + $memcacheClass = !empty($cacheDriver['class']) ? $cacheDriver['class'] : '%'.$this->getObjectManagerElementName('cache.memcache.class').'%'; + $memcacheInstanceClass = !empty($cacheDriver['instance_class']) ? $cacheDriver['instance_class'] : '%'.$this->getObjectManagerElementName('cache.memcache_instance.class').'%'; + $memcacheHost = !empty($cacheDriver['host']) ? $cacheDriver['host'] : '%'.$this->getObjectManagerElementName('cache.memcache_host').'%'; + $memcachePort = !empty($cacheDriver['port']) ? $cacheDriver['port'] : '%'.$this->getObjectManagerElementName('cache.memcache_port').'%'; + $cacheDef = new Definition($memcacheClass); + $memcacheInstance = new Definition($memcacheInstanceClass); + $memcacheInstance->addMethodCall('connect', array( + $memcacheHost, $memcachePort + )); + $container->setDefinition($this->getObjectManagerElementName(sprintf('%s_memcache_instance', $objectManager['name'])), $memcacheInstance); + $cacheDef->addMethodCall('setMemcache', array(new Reference($this->getObjectManagerElementName(sprintf('%s_memcache_instance', $objectManager['name']))))); + break; + case 'memcached': + $memcachedClass = !empty($cacheDriver['class']) ? $cacheDriver['class'] : '%'.$this->getObjectManagerElementName('cache.memcached.class').'%'; + $memcachedInstanceClass = !empty($cacheDriver['instance_class']) ? $cacheDriver['instance_class'] : '%'.$this->getObjectManagerElementName('cache.memcached_instance.class').'%'; + $memcachedHost = !empty($cacheDriver['host']) ? $cacheDriver['host'] : '%'.$this->getObjectManagerElementName('cache.memcached_host').'%'; + $memcachedPort = !empty($cacheDriver['port']) ? $cacheDriver['port'] : '%'.$this->getObjectManagerElementName('cache.memcached_port').'%'; + $cacheDef = new Definition($memcachedClass); + $memcachedInstance = new Definition($memcachedInstanceClass); + $memcachedInstance->addMethodCall('addServer', array( + $memcachedHost, $memcachedPort + )); + $container->setDefinition($this->getObjectManagerElementName(sprintf('%s_memcached_instance', $objectManager['name'])), $memcachedInstance); + $cacheDef->addMethodCall('setMemcached', array(new Reference($this->getObjectManagerElementName(sprintf('%s_memcached_instance', $objectManager['name']))))); + break; + case 'apc': + case 'array': + case 'xcache': + $cacheDef = new Definition('%'.$this->getObjectManagerElementName(sprintf('cache.%s.class', $cacheDriver['type'])).'%'); + break; + default: + throw new \InvalidArgumentException(sprintf('"%s" is an unrecognized Doctrine cache driver.', $cacheDriver['type'])); + } + + $cacheDef->setPublic(false); + // generate a unique namespace for the given application + $namespace = 'sf2'.$this->getMappingResourceExtension().'_'.$objectManager['name'].'_'.md5($container->getParameter('kernel.root_dir').$container->getParameter('kernel.environment')); + $cacheDef->addMethodCall('setNamespace', array($namespace)); + + $container->setDefinition($cacheDriverService, $cacheDef); + } + + /** + * Prefixes the relative dependency injection container path with the object manager prefix. + * + * @example $name is 'entity_manager' then the result would be 'doctrine.orm.entity_manager' + * + * @param string $name + * @return string + */ + abstract protected function getObjectManagerElementName($name); + + /** + * Noun that describes the mapped objects such as Entity or Document. + * + * Will be used for autodetection of persistent objects directory. + * + * @return string + */ + abstract protected function getMappingObjectDefaultName(); + + /** + * Relative path from the bundle root to the directory where mapping files reside. + * + * @return string + */ + abstract protected function getMappingResourceConfigDirectory(); + + /** + * Extension used by the mapping files. + * + * @return string + */ + abstract protected function getMappingResourceExtension(); +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/DoctrineValidationPass.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/DoctrineValidationPass.php new file mode 100644 index 0000000..756b790 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/DoctrineValidationPass.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\Bridge\Doctrine\DependencyInjection\CompilerPass; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\Config\Resource\FileResource; + +/** + * Registers additional validators + * + * @author Benjamin Eberlei + */ +class DoctrineValidationPass implements CompilerPassInterface +{ + /** + * @var string + */ + private $managerType; + + public function __construct($managerType) + { + $this->managerType = $managerType; + } + + /** + * {@inheritDoc} + */ + public function process(ContainerBuilder $container) + { + $this->updateValidatorMappingFiles($container, 'xml', 'xml'); + $this->updateValidatorMappingFiles($container, 'yaml', 'yml'); + } + + /** + * Gets the validation mapping files for the format and extends them with + * files matching a doctrine search pattern (Resources/config/validation.orm.xml) + * + * @param ContainerBuilder $container + * @param string $mapping + * @param type $extension + */ + private function updateValidatorMappingFiles(ContainerBuilder $container, $mapping, $extension) + { + if ( ! $container->hasParameter('validator.mapping.loader.' . $mapping . '_files_loader.mapping_files')) { + return; + } + + $files = $container->getParameter('validator.mapping.loader.' . $mapping . '_files_loader.mapping_files'); + $validationPath = 'Resources/config/validation.' . $this->managerType . '.' . $extension; + + foreach ($container->getParameter('kernel.bundles') as $bundle) { + $reflection = new \ReflectionClass($bundle); + if (is_file($file = dirname($reflection->getFilename()) . '/' . $validationPath)) { + $files[] = realpath($file); + $container->addResource(new FileResource($file)); + } + } + + $container->setParameter('validator.mapping.loader.' . $mapping . '_files_loader.mapping_files', $files); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php new file mode 100644 index 0000000..389ca83 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.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\Bridge\Doctrine\DependencyInjection\CompilerPass; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +class RegisterEventListenersAndSubscribersPass implements CompilerPassInterface +{ + private $connections; + private $container; + private $eventManagers; + private $managerTemplate; + private $tagPrefix; + + /** + * Constructor. + * + * @param string $connections Parameter ID for connections + * @param string $managerTemplate sprintf() template for generating the event + * manager's service ID for a connection name + * @param string $tagPrefix Tag prefix for listeners and subscribers + */ + public function __construct($connections, $managerTemplate, $tagPrefix) + { + $this->connections = $connections; + $this->managerTemplate = $managerTemplate; + $this->tagPrefix = $tagPrefix; + } + + public function process(ContainerBuilder $container) + { + if (!$container->hasParameter($this->connections)) { + return; + } + + $this->container = $container; + $this->connections = $container->getParameter($this->connections); + $sortFunc = function($a, $b) { + $a = isset($a['priority']) ? $a['priority'] : 0; + $b = isset($b['priority']) ? $b['priority'] : 0; + + return $a > $b ? -1 : 1; + }; + + $subscribersPerCon = $this->groupByConnection($container->findTaggedServiceIds($this->tagPrefix.'.event_subscriber')); + foreach ($subscribersPerCon as $con => $subscribers) { + $em = $this->getEventManager($con); + + uasort($subscribers, $sortFunc); + foreach ($subscribers as $id => $instance) { + $em->addMethodCall('addEventSubscriber', array(new Reference($id))); + } + } + + $listenersPerCon = $this->groupByConnection($container->findTaggedServiceIds($this->tagPrefix.'.event_listener'), true); + foreach ($listenersPerCon as $con => $listeners) { + $em = $this->getEventManager($con); + + uasort($listeners, $sortFunc); + foreach ($listeners as $id => $instance) { + $em->addMethodCall('addEventListener', array( + array_unique($instance['event']), + isset($instance['lazy']) && $instance['lazy'] ? $id : new Reference($id), + )); + } + } + } + + private function groupByConnection(array $services, $isListener = false) + { + $grouped = array(); + foreach (array_keys($this->connections) as $con) { + $grouped[$con] = array(); + } + + foreach ($services as $id => $instances) { + foreach ($instances as $instance) { + $cons = isset($instance['connection']) ? array($instance['connection']) : array_keys($this->connections); + foreach ($cons as $con) { + if (!isset($grouped[$con])) { + throw new \RuntimeException(sprintf('The Doctrine connection "%s" referenced in service "%s" does not exist. Available connections names: %s', $con, $id, implode(', ', array_keys($this->connections)))); + } + + if ($isListener) { + if (!isset($instance['event'])) { + throw new \InvalidArgumentException(sprintf('Doctrine event listener "%s" must specify the "event" attribute.', $id)); + } + $instance['event'] = array($instance['event']); + + if (isset($instance['lazy']) && $instance['lazy']) { + $this->container->getDefinition($id)->setPublic(true); + } + + if (isset($grouped[$con][$id])) { + $grouped[$con][$id]['event'] = array_merge($grouped[$con][$id]['event'], $instance['event']); + continue; + } + } + + $grouped[$con][$id] = $instance; + } + } + } + + return $grouped; + } + + private function getEventManager($name) + { + if (null === $this->eventManagers) { + $this->eventManagers = array(); + foreach ($this->connections as $n => $id) { + $this->eventManagers[$n] = $this->container->getDefinition(sprintf($this->managerTemplate, $n)); + } + } + + return $this->eventManagers[$name]; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DependencyInjection/Security/UserProvider/EntityFactory.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DependencyInjection/Security/UserProvider/EntityFactory.php new file mode 100644 index 0000000..421fd44 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/DependencyInjection/Security/UserProvider/EntityFactory.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\Bridge\Doctrine\DependencyInjection\Security\UserProvider; + +use Symfony\Component\Config\Definition\Builder\NodeDefinition; + +use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\UserProviderFactoryInterface; +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * EntityFactory creates services for Doctrine user provider. + * + * @author Fabien Potencier + * @author Christophe Coevoet + */ +class EntityFactory implements UserProviderFactoryInterface +{ + private $key; + private $providerId; + + public function __construct($key, $providerId) + { + $this->key = $key; + $this->providerId = $providerId; + } + + public function create(ContainerBuilder $container, $id, $config) + { + $container + ->setDefinition($id, new DefinitionDecorator($this->providerId)) + ->addArgument($config['class']) + ->addArgument($config['property']) + ->addArgument($config['manager_name']) + ; + } + + public function getKey() + { + return $this->key; + } + + public function addConfiguration(NodeDefinition $node) + { + $node + ->children() + ->scalarNode('class')->isRequired()->cannotBeEmpty()->end() + ->scalarNode('property')->defaultNull()->end() + ->scalarNode('manager_name')->defaultNull()->end() + ->end() + ; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php new file mode 100644 index 0000000..cde6542 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php @@ -0,0 +1,394 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Form\ChoiceList; + +use Symfony\Component\Form\Exception\FormException; +use Symfony\Component\Form\Exception\StringCastException; +use Symfony\Component\Form\Extension\Core\ChoiceList\ObjectChoiceList; +use Doctrine\Common\Persistence\ObjectManager; + +/** + * A choice list presenting a list of Doctrine entities as choices + * + * @author Bernhard Schussek + */ +class EntityChoiceList extends ObjectChoiceList +{ + /** + * @var ObjectManager + */ + private $em; + + /** + * @var string + */ + private $class; + + /** + * @var \Doctrine\Common\Persistence\Mapping\ClassMetadata + */ + private $classMetadata; + + /** + * Contains the query builder that builds the query for fetching the + * entities + * + * This property should only be accessed through queryBuilder. + * + * @var EntityLoaderInterface + */ + private $entityLoader; + + /** + * The identifier field, if the identifier is not composite + * + * @var array + */ + private $idField = null; + + /** + * Whether to use the identifier for index generation + * + * @var Boolean + */ + private $idAsIndex = false; + + /** + * Whether to use the identifier for value generation + * + * @var Boolean + */ + private $idAsValue = false; + + /** + * Whether the entities have already been loaded. + * + * @var Boolean + */ + private $loaded = false; + + /** + * Creates a new entity choice list. + * + * @param ObjectManager $manager An EntityManager instance + * @param string $class The class name + * @param string $labelPath The property path used for the label + * @param EntityLoaderInterface $entityLoader An optional query builder + * @param array $entities An array of choices + * @param string $groupPath A property path pointing to the property used + * to group the choices. Only allowed if + * the choices are given as flat array. + */ + public function __construct(ObjectManager $manager, $class, $labelPath = null, EntityLoaderInterface $entityLoader = null, $entities = null, $groupPath = null) + { + $this->em = $manager; + $this->entityLoader = $entityLoader; + $this->classMetadata = $manager->getClassMetadata($class); + $this->class = $this->classMetadata->getName(); + $this->loaded = is_array($entities) || $entities instanceof \Traversable; + + $identifier = $this->classMetadata->getIdentifierFieldNames(); + + if (1 === count($identifier)) { + $this->idField = $identifier[0]; + $this->idAsValue = true; + + if ('integer' === $this->classMetadata->getTypeOfField($this->idField)) { + $this->idAsIndex = true; + } + } + + if (!$this->loaded) { + // Make sure the constraints of the parent constructor are + // fulfilled + $entities = array(); + } + + parent::__construct($entities, $labelPath, array(), $groupPath); + } + + /** + * Returns the list of entities + * + * @return array + * + * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + public function getChoices() + { + if (!$this->loaded) { + $this->load(); + } + + return parent::getChoices(); + } + + /** + * Returns the values for the entities + * + * @return array + * + * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + public function getValues() + { + if (!$this->loaded) { + $this->load(); + } + + return parent::getValues(); + } + + /** + * Returns the choice views of the preferred choices as nested array with + * the choice groups as top-level keys. + * + * @return array + * + * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + public function getPreferredViews() + { + if (!$this->loaded) { + $this->load(); + } + + return parent::getPreferredViews(); + } + + /** + * Returns the choice views of the choices that are not preferred as nested + * array with the choice groups as top-level keys. + * + * @return array + * + * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + public function getRemainingViews() + { + if (!$this->loaded) { + $this->load(); + } + + return parent::getRemainingViews(); + } + + /** + * Returns the entities corresponding to the given values. + * + * @param array $values + * + * @return array + * + * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + public function getChoicesForValues(array $values) + { + if (!$this->loaded) { + // Optimize performance in case we have an entity loader and + // a single-field identifier + if ($this->idAsValue && $this->entityLoader) { + if (empty($values)) { + return array(); + } + + return $this->entityLoader->getEntitiesByIds($this->idField, $values); + } + + $this->load(); + } + + return parent::getChoicesForValues($values); + } + + /** + * Returns the values corresponding to the given entities. + * + * @param array $entities + * + * @return array + * + * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + public function getValuesForChoices(array $entities) + { + if (!$this->loaded) { + // Optimize performance for single-field identifiers. We already + // know that the IDs are used as values + + // Attention: This optimization does not check choices for existence + if ($this->idAsValue) { + $values = array(); + + foreach ($entities as $entity) { + if ($entity instanceof $this->class) { + // Make sure to convert to the right format + $values[] = $this->fixValue(current($this->getIdentifierValues($entity))); + } + } + + return $values; + } + + $this->load(); + } + + return parent::getValuesForChoices($entities); + } + + /** + * Returns the indices corresponding to the given entities. + * + * @param array $entities + * + * @return array + * + * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + public function getIndicesForChoices(array $entities) + { + if (!$this->loaded) { + // Optimize performance for single-field identifiers. We already + // know that the IDs are used as indices + + // Attention: This optimization does not check choices for existence + if ($this->idAsIndex) { + $indices = array(); + + foreach ($entities as $entity) { + if ($entity instanceof $this->class) { + // Make sure to convert to the right format + $indices[] = $this->fixIndex(current($this->getIdentifierValues($entity))); + } + } + + return $indices; + } + + $this->load(); + } + + return parent::getIndicesForChoices($entities); + } + + /** + * Returns the entities corresponding to the given values. + * + * @param array $values + * + * @return array + * + * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + public function getIndicesForValues(array $values) + { + if (!$this->loaded) { + // Optimize performance for single-field identifiers. + + // Attention: This optimization does not check values for existence + if ($this->idAsIndex && $this->idAsValue) { + return $this->fixIndices($values); + } + + $this->load(); + } + + return parent::getIndicesForValues($values); + } + + /** + * Creates a new unique index for this entity. + * + * If the entity has a single-field identifier, this identifier is used. + * + * Otherwise a new integer is generated. + * + * @param mixed $choice The choice to create an index for + * + * @return integer|string A unique index containing only ASCII letters, + * digits and underscores. + */ + protected function createIndex($entity) + { + if ($this->idAsIndex) { + return current($this->getIdentifierValues($entity)); + } + + return parent::createIndex($entity); + } + + /** + * Creates a new unique value for this entity. + * + * If the entity has a single-field identifier, this identifier is used. + * + * Otherwise a new integer is generated. + * + * @param mixed $choice The choice to create a value for + * + * @return integer|string A unique value without character limitations. + */ + protected function createValue($entity) + { + if ($this->idAsValue) { + return (string) current($this->getIdentifierValues($entity)); + } + + return parent::createValue($entity); + } + + /** + * Loads the list with entities. + */ + private function load() + { + if ($this->entityLoader) { + $entities = $this->entityLoader->getEntities(); + } else { + $entities = $this->em->getRepository($this->class)->findAll(); + } + + try { + // The second parameter $labels is ignored by ObjectChoiceList + // The third parameter $preferredChoices is currently not supported + parent::initialize($entities, array(), array()); + } catch (StringCastException $e) { + throw new StringCastException(str_replace('argument $labelPath', 'option "property"', $e->getMessage()), null, $e); + } + + $this->loaded = true; + } + + /** + * Returns the values of the identifier fields of an entity. + * + * Doctrine must know about this entity, that is, the entity must already + * be persisted or added to the identity map before. Otherwise an + * exception is thrown. + * + * @param object $entity The entity for which to get the identifier + * + * @return array The identifier values + * + * @throws FormException If the entity does not exist in Doctrine's identity map + */ + private function getIdentifierValues($entity) + { + if (!$this->em->contains($entity)) { + throw new FormException('Entities passed to the choice field must be managed'); + } + + $this->em->initializeObject($entity); + + return $this->classMetadata->getIdentifierValues($entity); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityLoaderInterface.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityLoaderInterface.php new file mode 100644 index 0000000..3b9fab2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityLoaderInterface.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\Bridge\Doctrine\Form\ChoiceList; + +/** + * Custom loader for entities in the choice list. + * + * @author Benjamin Eberlei + */ +interface EntityLoaderInterface +{ + /** + * Returns an array of entities that are valid choices in the corresponding choice list. + * + * @return array The entities. + */ + function getEntities(); + + /** + * Returns an array of entities matching the given identifiers. + * + * @param string $identifier The identifier field of the object. This method + * is not applicable for fields with multiple + * identifiers. + * @param array $values The values of the identifiers. + * + * @return array The entities. + */ + function getEntitiesByIds($identifier, array $values); +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php new file mode 100644 index 0000000..5d9b5e2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.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\Bridge\Doctrine\Form\ChoiceList; + +use Symfony\Component\Form\Exception\UnexpectedTypeException; +use Doctrine\ORM\QueryBuilder; +use Doctrine\DBAL\Connection; + +/** + * Getting Entities through the ORM QueryBuilder + */ +class ORMQueryBuilderLoader implements EntityLoaderInterface +{ + /** + * Contains the query builder that builds the query for fetching the + * entities + * + * This property should only be accessed through queryBuilder. + * + * @var Doctrine\ORM\QueryBuilder + */ + private $queryBuilder; + + /** + * Construct an ORM Query Builder Loader + * + * @param QueryBuilder $queryBuilder + * @param EntityManager $manager + * @param string $class + */ + public function __construct($queryBuilder, $manager = null, $class = null) + { + // If a query builder was passed, it must be a closure or QueryBuilder + // instance + if (!($queryBuilder instanceof QueryBuilder || $queryBuilder instanceof \Closure)) { + throw new UnexpectedTypeException($queryBuilder, 'Doctrine\ORM\QueryBuilder or \Closure'); + } + + if ($queryBuilder instanceof \Closure) { + $queryBuilder = $queryBuilder($manager->getRepository($class)); + + if (!$queryBuilder instanceof QueryBuilder) { + throw new UnexpectedTypeException($queryBuilder, 'Doctrine\ORM\QueryBuilder'); + } + } + + $this->queryBuilder = $queryBuilder; + } + + /** + * {@inheritDoc} + */ + public function getEntities() + { + return $this->queryBuilder->getQuery()->execute(); + } + + /** + * {@inheritDoc} + */ + public function getEntitiesByIds($identifier, array $values) + { + $qb = clone ($this->queryBuilder); + $alias = current($qb->getRootAliases()); + $parameter = 'ORMQueryBuilderLoader_getEntitiesByIds_'.$identifier; + $where = $qb->expr()->in($alias.'.'.$identifier, ':'.$parameter); + + return $qb->andWhere($where) + ->getQuery() + ->setParameter($parameter, $values, Connection::PARAM_STR_ARRAY) + ->getResult(); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/DataTransformer/CollectionToArrayTransformer.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/DataTransformer/CollectionToArrayTransformer.php new file mode 100644 index 0000000..2c1e7fe --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/DataTransformer/CollectionToArrayTransformer.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\Bridge\Doctrine\Form\DataTransformer; + +use Symfony\Component\Form\Exception\UnexpectedTypeException; +use Symfony\Component\Form\DataTransformerInterface; +use Doctrine\Common\Collections\Collection; +use Doctrine\Common\Collections\ArrayCollection; + +/** + * @author Bernhard Schussek + */ +class CollectionToArrayTransformer implements DataTransformerInterface +{ + /** + * Transforms a collection into an array. + * + * @param Collection $collection A collection of entities + * + * @return mixed An array of entities + */ + public function transform($collection) + { + if (null === $collection) { + return array(); + } + + if (!$collection instanceof Collection) { + throw new UnexpectedTypeException($collection, 'Doctrine\Common\Collections\Collection'); + } + + return $collection->toArray(); + } + + /** + * Transforms choice keys into entities. + * + * @param mixed $array An array of entities + * + * @return Collection A collection of entities + */ + public function reverseTransform($array) + { + if ('' === $array || null === $array) { + $array = array(); + } else { + $array = (array) $array; + } + + return new ArrayCollection($array); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmExtension.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmExtension.php new file mode 100644 index 0000000..7c9941c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmExtension.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\Bridge\Doctrine\Form; + +use Doctrine\Common\Persistence\ManagerRegistry; +use Symfony\Component\Form\AbstractExtension; + +class DoctrineOrmExtension extends AbstractExtension +{ + protected $registry; + + public function __construct(ManagerRegistry $registry) + { + $this->registry = $registry; + } + + protected function loadTypes() + { + return array( + new Type\EntityType($this->registry), + ); + } + + protected function loadTypeGuesser() + { + return new DoctrineOrmTypeGuesser($this->registry); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php new file mode 100644 index 0000000..07a37d5 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php @@ -0,0 +1,151 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Form; + +use Doctrine\Common\Persistence\ManagerRegistry; +use Symfony\Component\Form\FormTypeGuesserInterface; +use Symfony\Component\Form\Guess\Guess; +use Symfony\Component\Form\Guess\TypeGuess; +use Symfony\Component\Form\Guess\ValueGuess; +use Doctrine\ORM\Mapping\MappingException; + +class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface +{ + protected $registry; + + private $cache; + + public function __construct(ManagerRegistry $registry) + { + $this->registry = $registry; + $this->cache = array(); + } + + /** + * {@inheritDoc} + */ + public function guessType($class, $property) + { + if (!$ret = $this->getMetadata($class)) { + return new TypeGuess('text', array(), Guess::LOW_CONFIDENCE); + } + + list($metadata, $name) = $ret; + + if ($metadata->hasAssociation($property)) { + $multiple = $metadata->isCollectionValuedAssociation($property); + $mapping = $metadata->getAssociationMapping($property); + + return new TypeGuess('entity', array('em' => $name, 'class' => $mapping['targetEntity'], 'multiple' => $multiple), Guess::HIGH_CONFIDENCE); + } + + switch ($metadata->getTypeOfField($property)) { + case 'array': + return new TypeGuess('collection', array(), Guess::MEDIUM_CONFIDENCE); + case 'boolean': + return new TypeGuess('checkbox', array(), Guess::HIGH_CONFIDENCE); + case 'datetime': + case 'vardatetime': + case 'datetimetz': + return new TypeGuess('datetime', array(), Guess::HIGH_CONFIDENCE); + case 'date': + return new TypeGuess('date', array(), Guess::HIGH_CONFIDENCE); + case 'time': + return new TypeGuess('time', array(), Guess::HIGH_CONFIDENCE); + case 'decimal': + case 'float': + return new TypeGuess('number', array(), Guess::MEDIUM_CONFIDENCE); + case 'integer': + case 'bigint': + case 'smallint': + return new TypeGuess('integer', array(), Guess::MEDIUM_CONFIDENCE); + case 'string': + return new TypeGuess('text', array(), Guess::MEDIUM_CONFIDENCE); + case 'text': + return new TypeGuess('textarea', array(), Guess::MEDIUM_CONFIDENCE); + default: + return new TypeGuess('text', array(), Guess::LOW_CONFIDENCE); + } + } + + /** + * {@inheritDoc} + */ + public function guessRequired($class, $property) + { + $ret = $this->getMetadata($class); + if ($ret && $ret[0]->hasField($property)) { + if (!$ret[0]->isNullable($property)) { + return new ValueGuess(true, Guess::HIGH_CONFIDENCE); + } + + return new ValueGuess(false, Guess::MEDIUM_CONFIDENCE); + } + } + + /** + * {@inheritDoc} + */ + public function guessMaxLength($class, $property) + { + $ret = $this->getMetadata($class); + if ($ret && $ret[0]->hasField($property) && !$ret[0]->hasAssociation($property)) { + $mapping = $ret[0]->getFieldMapping($property); + + if (isset($mapping['length'])) { + return new ValueGuess($mapping['length'], Guess::HIGH_CONFIDENCE); + } + + if (in_array($ret[0]->getTypeOfField($property), array('decimal', 'float'))) { + return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE); + } + } + } + + /** + * {@inheritDoc} + */ + public function guessMinLength($class, $property) + { + } + + /** + * {@inheritDoc} + */ + public function guessPattern($class, $property) + { + $ret = $this->getMetadata($class); + if ($ret && $ret[0]->hasField($property) && !$ret[0]->hasAssociation($property)) { + $mapping = $ret[0]->getFieldMapping($property); + + if (in_array($ret[0]->getTypeOfField($property), array('decimal', 'float'))) { + return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE); + } + } + } + + protected function getMetadata($class) + { + if (array_key_exists($class, $this->cache)) { + return $this->cache[$class]; + } + + $this->cache[$class] = null; + foreach ($this->registry->getManagers() as $name => $em) { + try { + return $this->cache[$class] = array($em->getClassMetadata($class), $name); + } catch (MappingException $e) { + // not an entity or mapped super class + } + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/EventListener/MergeDoctrineCollectionListener.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/EventListener/MergeDoctrineCollectionListener.php new file mode 100644 index 0000000..69a4d3d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/EventListener/MergeDoctrineCollectionListener.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\Bridge\Doctrine\Form\EventListener; + +use Symfony\Component\Form\FormEvents; +use Symfony\Component\Form\FormEvent; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * Merge changes from the request to a Doctrine\Common\Collections\Collection instance. + * + * This works with ORM, MongoDB and CouchDB instances of the collection interface. + * + * @author Bernhard Schussek + * + * @see Doctrine\Common\Collections\Collection + */ +class MergeDoctrineCollectionListener implements EventSubscriberInterface +{ + static public function getSubscribedEvents() + { + // Higher priority than core MergeCollectionListener so that this one + // is called before + return array(FormEvents::BIND => array('onBind', 10)); + } + + public function onBind(FormEvent $event) + { + $collection = $event->getForm()->getData(); + $data = $event->getData(); + + // If all items were removed, call clear which has a higher + // performance on persistent collections + if ($collection && count($data) === 0) { + $collection->clear(); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php new file mode 100644 index 0000000..f94e10e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.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\Bridge\Doctrine\Form\Type; + +use Doctrine\Common\Persistence\ManagerRegistry; +use Doctrine\Common\Persistence\ObjectManager; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList; +use Symfony\Bridge\Doctrine\Form\ChoiceList\EntityLoaderInterface; +use Symfony\Bridge\Doctrine\Form\EventListener\MergeDoctrineCollectionListener; +use Symfony\Bridge\Doctrine\Form\DataTransformer\CollectionToArrayTransformer; +use Symfony\Component\Form\AbstractType; +use Symfony\Component\OptionsResolver\Options; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; + +abstract class DoctrineType extends AbstractType +{ + /** + * @var ManagerRegistry + */ + protected $registry; + + public function __construct(ManagerRegistry $registry) + { + $this->registry = $registry; + } + + public function buildForm(FormBuilderInterface $builder, array $options) + { + if ($options['multiple']) { + $builder + ->addEventSubscriber(new MergeDoctrineCollectionListener()) + ->addViewTransformer(new CollectionToArrayTransformer(), true) + ; + } + } + + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $registry = $this->registry; + $type = $this; + + $loader = function (Options $options) use ($type, $registry) { + if (null !== $options['query_builder']) { + $manager = $registry->getManager($options['em']); + + return $type->getLoader($manager, $options['query_builder'], $options['class']); + } + + return null; + }; + + $choiceList = function (Options $options) use ($registry) { + $manager = $registry->getManager($options['em']); + + return new EntityChoiceList( + $manager, + $options['class'], + $options['property'], + $options['loader'], + $options['choices'], + $options['group_by'] + ); + }; + + $resolver->setDefaults(array( + 'em' => null, + 'class' => null, + 'property' => null, + 'query_builder' => null, + 'loader' => $loader, + 'choices' => null, + 'choice_list' => $choiceList, + 'group_by' => null, + )); + } + + /** + * Return the default loader object. + * + * @param ObjectManager $manager + * @param mixed $queryBuilder + * @param string $class + * @return EntityLoaderInterface + */ + abstract public function getLoader(ObjectManager $manager, $queryBuilder, $class); + + public function getParent() + { + return 'choice'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/Type/EntityType.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/Type/EntityType.php new file mode 100644 index 0000000..51b47be --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/Type/EntityType.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\Bridge\Doctrine\Form\Type; + +use Doctrine\Common\Persistence\ObjectManager; +use Symfony\Bridge\Doctrine\Form\ChoiceList\ORMQueryBuilderLoader; + +class EntityType extends DoctrineType +{ + /** + * Return the default loader object. + * + * @param ObjectManager $manager + * @param mixed $queryBuilder + * @param string $class + * @return ORMQueryBuilderLoader + */ + public function getLoader(ObjectManager $manager, $queryBuilder, $class) + { + return new ORMQueryBuilderLoader( + $queryBuilder, + $manager, + $class + ); + } + + public function getName() + { + return 'entity'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/HttpFoundation/DbalSessionHandler.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/HttpFoundation/DbalSessionHandler.php new file mode 100644 index 0000000..9a41efb --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/HttpFoundation/DbalSessionHandler.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\Bridge\Doctrine\HttpFoundation; + +use Doctrine\DBAL\Platforms\MySqlPlatform; +use Doctrine\DBAL\Driver\Connection; + +/** + * DBAL based session storage. + * + * @author Fabien Potencier + * @author Johannes M. Schmitt + */ +class DbalSessionHandler implements \SessionHandlerInterface +{ + /** + * @var Connection + */ + private $con; + + /** + * @var string + */ + private $tableName; + + /** + * Constructor. + * + * @param Connection $con An instance of Connection. + * @param string $tableName Table name. + */ + public function __construct(Connection $con, $tableName = 'sessions') + { + $this->con = $con; + $this->tableName = $tableName; + } + + /** + * {@inheritdoc} + */ + public function open($path = null, $name = null) + { + return true; + } + + /** + * {@inheritdoc} + */ + public function close() + { + // do nothing + return true; + } + + /** + * {@inheritdoc} + */ + public function destroy($id) + { + try { + $this->con->executeQuery("DELETE FROM {$this->tableName} WHERE sess_id = :id", array( + 'id' => $id, + )); + } catch (\PDOException $e) { + throw new \RuntimeException(sprintf('PDOException was thrown when trying to manipulate session data: %s', $e->getMessage()), 0, $e); + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function gc($lifetime) + { + try { + $this->con->executeQuery("DELETE FROM {$this->tableName} WHERE sess_time < :time", array( + 'time' => time() - $lifetime, + )); + } catch (\PDOException $e) { + throw new \RuntimeException(sprintf('PDOException was thrown when trying to manipulate session data: %s', $e->getMessage()), 0, $e); + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function read($id) + { + try { + $data = $this->con->executeQuery("SELECT sess_data FROM {$this->tableName} WHERE sess_id = :id", array( + 'id' => $id, + ))->fetchColumn(); + + if (false !== $data) { + return base64_decode($data); + } + + // session does not exist, create it + $this->createNewSession($id); + + return ''; + } catch (\PDOException $e) { + throw new \RuntimeException(sprintf('PDOException was thrown when trying to read the session data: %s', $e->getMessage()), 0, $e); + } + } + + /** + * {@inheritdoc} + */ + public function write($id, $data) + { + $platform = $this->con->getDatabasePlatform(); + + // this should maybe be abstracted in Doctrine DBAL + if ($platform instanceof MySqlPlatform) { + $sql = "INSERT INTO {$this->tableName} (sess_id, sess_data, sess_time) VALUES (%1\$s, %2\$s, %3\$d) " + ."ON DUPLICATE KEY UPDATE sess_data = VALUES(sess_data), sess_time = CASE WHEN sess_time = %3\$d THEN (VALUES(sess_time) + 1) ELSE VALUES(sess_time) END"; + } else { + $sql = "UPDATE {$this->tableName} SET sess_data = %2\$s, sess_time = %3\$d WHERE sess_id = %1\$s"; + } + + try { + $rowCount = $this->con->exec(sprintf( + $sql, + $this->con->quote($id), + //session data can contain non binary safe characters so we need to encode it + $this->con->quote(base64_encode($data)), + time() + )); + + if (!$rowCount) { + // No session exists in the database to update. This happens when we have called + // session_regenerate_id() + $this->createNewSession($id, $data); + } + } catch (\PDOException $e) { + throw new \RuntimeException(sprintf('PDOException was thrown when trying to write the session data: %s', $e->getMessage()), 0, $e); + } + + return true; + } + + /** + * Creates a new session with the given $id and $data + * + * @param string $id + * @param string $data + */ + private function createNewSession($id, $data = '') + { + $this->con->exec(sprintf("INSERT INTO {$this->tableName} (sess_id, sess_data, sess_time) VALUES (%s, %s, %d)", + $this->con->quote($id), + //session data can contain non binary safe characters so we need to encode it + $this->con->quote(base64_encode($data)), + time() + )); + + return true; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/HttpFoundation/DbalSessionHandlerSchema.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/HttpFoundation/DbalSessionHandlerSchema.php new file mode 100644 index 0000000..b7b4b91 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/HttpFoundation/DbalSessionHandlerSchema.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\Bridge\Doctrine\HttpFoundation; + +use Doctrine\DBAL\Schema\Schema; + +/** + * DBAL Session Storage Schema. + * + * @author Johannes M. Schmitt + */ +final class DbalSessionHandlerSchema extends Schema +{ + private $tableName; + + public function __construct($tableName = 'sessions') + { + parent::__construct(); + + $this->tableName = $tableName; + $this->addSessionTable(); + } + + public function addToSchema(Schema $schema) + { + foreach ($this->getTables() as $table) { + $schema->_addTable($table); + } + } + + private function addSessionTable() + { + $table = $this->createTable($this->tableName); + $table->addColumn('sess_id', 'string'); + $table->addColumn('sess_data', 'text')->setNotNull(true); + $table->addColumn('sess_time', 'integer')->setNotNull(true)->setUnsigned(true); + $table->setPrimaryKey(array('sess_id')); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/LICENSE b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/LICENSE new file mode 100644 index 0000000..cdffe7a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 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/symfony/src/Symfony/Bridge/Doctrine/Logger/DbalLogger.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Logger/DbalLogger.php new file mode 100644 index 0000000..066ff8a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Logger/DbalLogger.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\Bridge\Doctrine\Logger; + +use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Symfony\Component\HttpKernel\Debug\Stopwatch; +use Doctrine\DBAL\Logging\SQLLogger; + +/** + * DbalLogger. + * + * @author Fabien Potencier + */ +class DbalLogger implements SQLLogger +{ + protected $logger; + protected $stopwatch; + + /** + * Constructor. + * + * @param LoggerInterface $logger A LoggerInterface instance + * @param Stopwatch $stopwatch A Stopwatch instance + */ + public function __construct(LoggerInterface $logger = null, Stopwatch $stopwatch = null) + { + $this->logger = $logger; + $this->stopwatch = $stopwatch; + } + + /** + * {@inheritdoc} + */ + public function startQuery($sql, array $params = null, array $types = null) + { + if (null !== $this->stopwatch) { + $this->stopwatch->start('doctrine', 'doctrine'); + } + + if (null !== $this->logger) { + $this->log($sql.' ('.json_encode($params).')'); + } + } + + /** + * {@inheritdoc} + */ + public function stopQuery() + { + if (null !== $this->stopwatch) { + $this->stopwatch->stop('doctrine'); + } + } + + /** + * Logs a message. + * + * @param string $message A message to log + */ + public function log($message) + { + $this->logger->debug($message); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/ManagerRegistry.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/ManagerRegistry.php new file mode 100644 index 0000000..80eeb37 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/ManagerRegistry.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\Bridge\Doctrine; + +use Symfony\Component\DependencyInjection\ContainerAwareInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Doctrine\Common\Persistence\AbstractManagerRegistry; + +/** + * References Doctrine connections and entity/document managers. + * + * @author Lukas Kahwe Smith + */ +abstract class ManagerRegistry extends AbstractManagerRegistry implements ContainerAwareInterface +{ + /** + * @var ContainerInterface + */ + protected $container; + + /** + * @inheritdoc + */ + protected function getService($name) + { + return $this->container->get($name); + } + + /** + * @inheritdoc + */ + protected function resetService($name) + { + $this->container->set($name, null); + } + + /** + * @inheritdoc + */ + public function setContainer(ContainerInterface $container = null) + { + $this->container = $container; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/README.md b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/README.md new file mode 100644 index 0000000..211eb7f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/README.md @@ -0,0 +1,28 @@ +Doctrine Bridge +=============== + +Provides integration for [Doctrine](http://www.doctrine-project.org/) with +various Symfony2 components. + +Resources +--------- + +You can run the unit tests with the following command: + + phpunit -c src/Symfony/Bridge/Doctrine/ + +If you also want to run the unit tests that depend on other Symfony +Components, declare the following environment variables before running +PHPUnit: + + export DOCTRINE_COMMON=../path/to/doctrine-common + export DOCTRINE_DBAL=../path/to/doctrine-dbal + export DOCTRINE_ORM=../path/to/doctrine + export DOCTRINE_FIXTURES=../path/to/doctrine-fixtures + export SYMFONY_HTTP_FOUNDATION=../path/to/HttpFoundation + export SYMFONY_DEPENDENCY_INJECTION=../path/to/DependencyInjection + export SYMFONY_FORM=../path/to/Form + export SYMFONY_SECURITY=../path/to/Security + export SYMFONY_VALIDATOR=../path/to/Validator + export SYMFONY_HTTP_KERNEL=../path/to/HttpKernel + export SYMFONY_EVENT_DISPATCHER=../path/to/EventDispatcher diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/RegistryInterface.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/RegistryInterface.php new file mode 100644 index 0000000..f941d2f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/RegistryInterface.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\Bridge\Doctrine; + +use Doctrine\Common\Persistence\ManagerRegistry as ManagerRegistryInterface; +use Doctrine\ORM\Configuration; + +/** + * References Doctrine connections and entity managers. + * + * @author Fabien Potencier + */ +interface RegistryInterface extends ManagerRegistryInterface +{ + /** + * Gets the default entity manager name. + * + * @return string The default entity manager name + */ + function getDefaultEntityManagerName(); + + /** + * Gets a named entity manager. + * + * @param string $name The entity manager name (null for the default one) + * + * @return EntityManager + */ + function getEntityManager($name = null); + + /** + * Gets an array of all registered entity managers + * + * @return array An array of EntityManager instances + */ + function getEntityManagers(); + + /** + * Resets a named entity manager. + * + * This method is useful when an entity manager has been closed + * because of a rollbacked transaction AND when you think that + * it makes sense to get a new one to replace the closed one. + * + * Be warned that you will get a brand new entity manager as + * the existing one is not useable anymore. This means that any + * other object with a dependency on this entity manager will + * hold an obsolete reference. You can inject the registry instead + * to avoid this problem. + * + * @param string $name The entity manager name (null for the default one) + * + * @return EntityManager + */ + function resetEntityManager($name = null); + + /** + * Resolves a registered namespace alias to the full namespace. + * + * This method looks for the alias in all registered entity managers. + * + * @param string $alias The alias + * + * @return string The full namespace + * + * @see Configuration::getEntityNamespace + */ + function getEntityNamespace($alias); + + /** + * Gets all connection names. + * + * @return array An array of connection names + */ + function getEntityManagerNames(); + + /** + * Gets the entity manager associated with a given class. + * + * @param string $class A Doctrine Entity class name + * + * @return EntityManager|null + */ + function getEntityManagerForClass($class); +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php new file mode 100644 index 0000000..487b1d6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.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\Bridge\Doctrine\Security\User; + +use Doctrine\Common\Persistence\ManagerRegistry; +use Symfony\Component\Security\Core\Exception\UnsupportedUserException; +use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; +use Symfony\Component\Security\Core\User\UserProviderInterface; +use Symfony\Component\Security\Core\User\UserInterface; + +/** + * Wrapper around a Doctrine ObjectManager. + * + * Provides easy to use provisioning for Doctrine entity users. + * + * @author Fabien Potencier + * @author Johannes M. Schmitt + */ +class EntityUserProvider implements UserProviderInterface +{ + private $class; + private $repository; + private $property; + private $metadata; + + public function __construct(ManagerRegistry $registry, $class, $property = null, $managerName = null) + { + $em = $registry->getManager($managerName); + $this->class = $class; + $this->metadata = $em->getClassMetadata($class); + + if (false !== strpos($this->class, ':')) { + $this->class = $this->metadata->getName(); + } + + $this->repository = $em->getRepository($class); + $this->property = $property; + } + + /** + * {@inheritdoc} + */ + public function loadUserByUsername($username) + { + if (null !== $this->property) { + $user = $this->repository->findOneBy(array($this->property => $username)); + } else { + if (!$this->repository instanceof UserProviderInterface) { + throw new \InvalidArgumentException(sprintf('The Doctrine repository "%s" must implement UserProviderInterface.', get_class($this->repository))); + } + + $user = $this->repository->loadUserByUsername($username); + } + + if (null === $user) { + throw new UsernameNotFoundException(sprintf('User "%s" not found.', $username)); + } + + return $user; + } + + /** + * {@inheritDoc} + */ + public function refreshUser(UserInterface $user) + { + if (!$user instanceof $this->class) { + throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user))); + } + + if ($this->repository instanceof UserProviderInterface) { + $refreshedUser = $this->repository->refreshUser($user); + } else { + // The user must be reloaded via the primary key as all other data + // might have changed without proper persistence in the database. + // That's the case when the user has been changed by a form with + // validation errors. + if (!$id = $this->metadata->getIdentifierValues($user)) { + throw new \InvalidArgumentException("You cannot refresh a user ". + "from the EntityUserProvider that does not contain an identifier. ". + "The user object has to be serialized with its own identifier " . + "mapped by Doctrine." + ); + } + + if (null === $refreshedUser = $this->repository->find($id)) { + throw new UsernameNotFoundException(sprintf('User with id %s not found', json_encode($id))); + } + } + + return $refreshedUser; + } + + /** + * {@inheritDoc} + */ + public function supportsClass($class) + { + return $class === $this->class || is_subclass_of($class, $this->class); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/ContainerAwareEventManagerTest.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/ContainerAwareEventManagerTest.php new file mode 100644 index 0000000..b5985ca --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/ContainerAwareEventManagerTest.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\Bridge\Doctrine\Tests; + +use Symfony\Bridge\Doctrine\ContainerAwareEventManager; +use Symfony\Component\DependencyInjection\Container; + +class ContainerAwareEventManagerTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\DependencyInjection\Container')) { + $this->markTestSkipped('The "DependencyInjection" component is not available'); + } + + $this->container = new Container(); + $this->evm = new ContainerAwareEventManager($this->container); + } + + public function testDispatchEvent() + { + $this->container->set('foobar', $listener1 = new MyListener()); + $this->evm->addEventListener('foo', 'foobar'); + $this->evm->addEventListener('foo', $listener2 = new MyListener()); + + $this->evm->dispatchEvent('foo'); + + $this->assertTrue($listener1->called); + $this->assertTrue($listener2->called); + } + + public function testRemoveEventListener() + { + $this->evm->addEventListener('foo', 'bar'); + $this->evm->addEventListener('foo', $listener = new MyListener()); + + $listeners = array('foo' => array('_service_bar' => 'bar', spl_object_hash($listener) => $listener)); + $this->assertSame($listeners, $this->evm->getListeners()); + $this->assertSame($listeners['foo'], $this->evm->getListeners('foo')); + + $this->evm->removeEventListener('foo', $listener); + $this->assertSame(array('_service_bar' => 'bar'), $this->evm->getListeners('foo')); + + $this->evm->removeEventListener('foo', 'bar'); + $this->assertSame(array(), $this->evm->getListeners('foo')); + } +} + +class MyListener +{ + public $called = false; + + public function foo() + { + $this->called = true; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/DataCollector/DoctrineDataCollectorTest.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/DataCollector/DoctrineDataCollectorTest.php new file mode 100644 index 0000000..0679356 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/DataCollector/DoctrineDataCollectorTest.php @@ -0,0 +1,158 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\DataCollector; + +use Doctrine\DBAL\Platforms\MySqlPlatform; +use Symfony\Bridge\Doctrine\DataCollector\DoctrineDataCollector; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +class DoctrineDataCollectorTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Doctrine\DBAL\Platforms\MySqlPlatform')) { + $this->markTestSkipped('Doctrine DBAL is not available.'); + } + + if (!class_exists('Symfony\Component\HttpKernel\HttpKernel')) { + $this->markTestSkipped('The "HttpKernel" component is not available'); + } + } + + public function testCollectConnections() + { + $c = $this->createCollector(array()); + $c->collect(new Request(), new Response()); + $this->assertEquals(array('default' => 'doctrine.dbal.default_connection'), $c->getConnections()); + } + + public function testCollectManagers() + { + $c = $this->createCollector(array()); + $c->collect(new Request(), new Response()); + $this->assertEquals(array('default' => 'doctrine.orm.default_entity_manager'), $c->getManagers()); + } + + public function testCollectQueryCount() + { + $c = $this->createCollector(array()); + $c->collect(new Request(), new Response()); + $this->assertEquals(0, $c->getQueryCount()); + + $queries = array( + array('sql' => "SELECT * FROM table1", 'params' => array(), 'types' => array(), 'executionMS' => 0) + ); + $c = $this->createCollector($queries); + $c->collect(new Request(), new Response()); + $this->assertEquals(1, $c->getQueryCount()); + } + + public function testCollectTime() + { + $c = $this->createCollector(array()); + $c->collect(new Request(), new Response()); + $this->assertEquals(0, $c->getTime()); + + $queries = array( + array('sql' => "SELECT * FROM table1", 'params' => array(), 'types' => array(), 'executionMS' => 1) + ); + $c = $this->createCollector($queries); + $c->collect(new Request(), new Response()); + $this->assertEquals(1, $c->getTime()); + + $queries = array( + array('sql' => "SELECT * FROM table1", 'params' => array(), 'types' => array(), 'executionMS' => 1), + array('sql' => "SELECT * FROM table2", 'params' => array(), 'types' => array(), 'executionMS' => 2) + ); + $c = $this->createCollector($queries); + $c->collect(new Request(), new Response()); + $this->assertEquals(3, $c->getTime()); + } + + /** + * @dataProvider paramProvider + */ + public function testCollectQueries($param, $types, $expected, $explainable) + { + $queries = array( + array('sql' => "SELECT * FROM table1 WHERE field1 = ?1", 'params' => array($param), 'types' => $types, 'executionMS' => 1) + ); + $c = $this->createCollector($queries); + $c->collect(new Request(), new Response()); + + $collected_queries = $c->getQueries(); + $this->assertEquals($expected, $collected_queries['default'][0]['params'][0]); + $this->assertEquals($explainable, $collected_queries['default'][0]['explainable']); + } + + /** + * @dataProvider paramProvider + */ + public function testSerialization($param, $types, $expected, $explainable) + { + $queries = array( + array('sql' => "SELECT * FROM table1 WHERE field1 = ?1", 'params' => array($param), 'types' => $types, 'executionMS' => 1) + ); + $c = $this->createCollector($queries); + $c->collect(new Request(), new Response()); + $c = unserialize(serialize($c)); + + $collected_queries = $c->getQueries(); + $this->assertEquals($expected, $collected_queries['default'][0]['params'][0]); + $this->assertEquals($explainable, $collected_queries['default'][0]['explainable']); + } + + public function paramProvider() + { + return array( + array('some value', array(), 'some value', true), + array(1, array(), 1, true), + array(true, array(), true, true), + array(null, array(), null, true), + array(new \DateTime('2011-09-11'), array('date'), '2011-09-11', true), + array(fopen(__FILE__, 'r'), array(), 'Resource(stream)', false), + array(new \SplFileInfo(__FILE__), array(), 'Object(SplFileInfo)', false), + ); + } + + private function createCollector($queries) + { + $connection = $this->getMockBuilder('Doctrine\DBAL\Connection') + ->disableOriginalConstructor() + ->getMock(); + $connection->expects($this->any()) + ->method('getDatabasePlatform') + ->will($this->returnValue(new MySqlPlatform())); + + $registry = $this->getMock('Doctrine\Common\Persistence\ManagerRegistry'); + $registry + ->expects($this->any()) + ->method('getConnectionNames') + ->will($this->returnValue(array('default' => 'doctrine.dbal.default_connection'))); + $registry + ->expects($this->any()) + ->method('getManagerNames') + ->will($this->returnValue(array('default' => 'doctrine.orm.default_entity_manager'))); + $registry->expects($this->any()) + ->method('getConnection') + ->will($this->returnValue($connection)); + + $logger = $this->getMock('Doctrine\DBAL\Logging\DebugStack'); + $logger->queries = $queries; + + $collector = new DoctrineDataCollector($registry); + $collector->addLogger('default', $logger); + + return $collector; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/DataFixtures/ContainerAwareLoaderTest.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/DataFixtures/ContainerAwareLoaderTest.php new file mode 100644 index 0000000..52d653b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/DataFixtures/ContainerAwareLoaderTest.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\Bridge\Doctrine\Tests\DataFixtures; + +use Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader; +use Symfony\Bridge\Doctrine\Tests\Fixtures\ContainerAwareFixture; + +class ContainerAwareLoaderTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\DependencyInjection\Container')) { + $this->markTestSkipped('The "DependencyInjection" component is not available'); + } + + if (!class_exists('Doctrine\Common\DataFixtures\Loader')) { + $this->markTestSkipped('Doctrine Data Fixtures is not available.'); + } + } + + public function testShouldSetContainerOnContainerAwareFixture() + { + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $loader = new ContainerAwareLoader($container); + $fixture = new ContainerAwareFixture(); + + $loader->addFixture($fixture); + + $this->assertSame($container, $fixture->container); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPassTest.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPassTest.php new file mode 100644 index 0000000..5c72fbf --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPassTest.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\Bridge\Doctrine\Tests\DependencyInjection\Compiler; + +use Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass\RegisterEventListenersAndSubscribersPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +class RegisterEventListenersAndSubscribersPassTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\DependencyInjection\Container')) { + $this->markTestSkipped('The "DependencyInjection" component is not available'); + } + } + + public function testProcessEventListenersWithPriorities() + { + $container = $this->createBuilder(); + + $container + ->register('a', 'stdClass') + ->addTag('doctrine.event_listener', array( + 'event' => 'foo', + 'priority' => -5, + )) + ->addTag('doctrine.event_listener', array( + 'event' => 'bar', + )) + ; + $container + ->register('b', 'stdClass') + ->addTag('doctrine.event_listener', array( + 'event' => 'foo', + )) + ; + + $this->process($container); + $this->assertEquals(array('b', 'a'), $this->getServiceOrder($container, 'addEventListener')); + + $calls = $container->getDefinition('doctrine.dbal.default_connection.event_manager')->getMethodCalls(); + $this->assertEquals(array('foo', 'bar'), $calls[1][1][0]); + } + + public function testProcessEventSubscribersWithPriorities() + { + $container = $this->createBuilder(); + + $container + ->register('a', 'stdClass') + ->addTag('doctrine.event_subscriber') + ; + $container + ->register('b', 'stdClass') + ->addTag('doctrine.event_subscriber', array( + 'priority' => 5, + )) + ; + $container + ->register('c', 'stdClass') + ->addTag('doctrine.event_subscriber', array( + 'priority' => 10, + )) + ; + $container + ->register('d', 'stdClass') + ->addTag('doctrine.event_subscriber', array( + 'priority' => 10, + )) + ; + $container + ->register('e', 'stdClass') + ->addTag('doctrine.event_subscriber', array( + 'priority' => 10, + )) + ; + + $this->process($container); + $this->assertEquals(array('c', 'd', 'e', 'b', 'a'), $this->getServiceOrder($container, 'addEventSubscriber')); + } + + private function process(ContainerBuilder $container) + { + $pass = new RegisterEventListenersAndSubscribersPass('doctrine.connections', 'doctrine.dbal.%s_connection.event_manager', 'doctrine'); + $pass->process($container); + } + + private function getServiceOrder(ContainerBuilder $container, $method) + { + $order = array(); + foreach ($container->getDefinition('doctrine.dbal.default_connection.event_manager')->getMethodCalls() as $call) { + list($name, $arguments) = $call; + if ($method !== $name) { + continue; + } + + if ('addEventListener' === $name) { + $order[] = (string) $arguments[1]; + continue; + } + + $order[] = (string) $arguments[0]; + } + + return $order; + } + + private function createBuilder() + { + $container = new ContainerBuilder(); + $container->register('doctrine.dbal.default_connection.event_manager', 'stdClass'); + $container->register('doctrine.dbal.default_connection', 'stdClass'); + $container->setParameter('doctrine.connections', array('default' => 'doctrine.dbal.default_connection')); + + return $container; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/DoctrineOrmTestCase.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/DoctrineOrmTestCase.php new file mode 100644 index 0000000..44c42c5 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/DoctrineOrmTestCase.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\Bridge\Doctrine\Tests; + +use Doctrine\Common\Annotations\AnnotationReader; +use Doctrine\ORM\Mapping\Driver\AnnotationDriver; +use Doctrine\ORM\EntityManager; + +abstract class DoctrineOrmTestCase extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Doctrine\Common\Version')) { + $this->markTestSkipped('Doctrine Common is not available.'); + } + + if (!class_exists('Doctrine\DBAL\Platforms\MySqlPlatform')) { + $this->markTestSkipped('Doctrine DBAL is not available.'); + } + + if (!class_exists('Doctrine\ORM\EntityManager')) { + $this->markTestSkipped('Doctrine ORM is not available.'); + } + } + + /** + * @return EntityManager + */ + static public function createTestEntityManager($paths = array()) + { + if (!class_exists('PDO') || !in_array('sqlite', \PDO::getAvailableDrivers())) { + self::markTestSkipped('This test requires SQLite support in your environment'); + } + $config = new \Doctrine\ORM\Configuration(); + $config->setEntityNamespaces(array('SymfonyTestsDoctrine' => 'Symfony\Bridge\Doctrine\Tests\Fixtures')); + $config->setAutoGenerateProxyClasses(true); + $config->setProxyDir(\sys_get_temp_dir()); + $config->setProxyNamespace('SymfonyTests\Doctrine'); + $config->setMetadataDriverImpl(new AnnotationDriver(new AnnotationReader())); + $config->setQueryCacheImpl(new \Doctrine\Common\Cache\ArrayCache()); + $config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache()); + + $params = array( + 'driver' => 'pdo_sqlite', + 'memory' => true, + ); + + return EntityManager::create($params, $config); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/AssociationEntity.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/AssociationEntity.php new file mode 100644 index 0000000..0fe3d14 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/AssociationEntity.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\Bridge\Doctrine\Tests\Fixtures; + +use Doctrine\ORM\Mapping AS ORM; + +/** + * @ORM\Entity + */ +class AssociationEntity +{ + /** + * @var int + * @ORM\Id @ORM\GeneratedValue + * @ORM\Column(type="integer") + */ + private $id; + + /** + * @ORM\ManyToOne(targetEntity="SingleIdentEntity") + * @var \Symfony\Bridge\Doctrine\Tests\Form\Fixtures\SingleIdentEntity + */ + public $single; + + /** + * @ORM\ManyToOne(targetEntity="CompositeIdentEntity") + * @ORM\JoinColumns({ + * @ORM\JoinColumn(name="composite_id1", referencedColumnName="id1"), + * @ORM\JoinColumn(name="composite_id2", referencedColumnName="id2") + * }) + * @var \Symfony\Bridge\Doctrine\Tests\Form\Fixtures\CompositeIdentEntity + */ + public $composite; +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/CompositeIdentEntity.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/CompositeIdentEntity.php new file mode 100644 index 0000000..9d26314 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/CompositeIdentEntity.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\Bridge\Doctrine\Tests\Fixtures; + +use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Entity; +use Symfony\Component\Security\Core\User\UserInterface; + +/** @Entity */ +class CompositeIdentEntity implements UserInterface +{ + /** @Id @Column(type="integer") */ + protected $id1; + + /** @Id @Column(type="integer") */ + protected $id2; + + /** @Column(type="string") */ + public $name; + + public function __construct($id1, $id2, $name) + { + $this->id1 = $id1; + $this->id2 = $id2; + $this->name = $name; + } + + public function getRoles() + { + } + + public function getPassword() + { + } + + public function getSalt() + { + } + + public function getUsername() + { + return $this->name; + } + + public function eraseCredentials() + { + } + + public function equals(UserInterface $user) + { + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/CompositeStringIdentEntity.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/CompositeStringIdentEntity.php new file mode 100644 index 0000000..43c71f6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/CompositeStringIdentEntity.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\Bridge\Doctrine\Tests\Fixtures; + +use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Entity; + +/** @Entity */ +class CompositeStringIdentEntity +{ + /** @Id @Column(type="string") */ + protected $id1; + + /** @Id @Column(type="string") */ + protected $id2; + + /** @Column(type="string") */ + public $name; + + public function __construct($id1, $id2, $name) + { + $this->id1 = $id1; + $this->id2 = $id2; + $this->name = $name; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/ContainerAwareFixture.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/ContainerAwareFixture.php new file mode 100644 index 0000000..5141e16 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/ContainerAwareFixture.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\Bridge\Doctrine\Tests\Fixtures; + +use Doctrine\Common\DataFixtures\FixtureInterface; +use Doctrine\Common\Persistence\ObjectManager; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\ContainerAwareInterface; + +class ContainerAwareFixture implements FixtureInterface, ContainerAwareInterface +{ + public $container; + + public function setContainer(ContainerInterface $container = null) + { + $this->container = $container; + } + + public function load(ObjectManager $manager) + { + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/ItemGroupEntity.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/ItemGroupEntity.php new file mode 100644 index 0000000..04d2ddf --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/ItemGroupEntity.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\Bridge\Doctrine\Tests\Fixtures; + +use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Entity; + +/** @Entity */ +class ItemGroupEntity +{ + /** @Id @Column(type="integer") */ + protected $id; + + /** @Column(type="string", nullable=true) */ + public $name; + + /** @Column(type="string", nullable=true) */ + public $groupName; + + public function __construct($id, $name, $groupName) + { + $this->id = $id; + $this->name = $name; + $this->groupName = $groupName; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/NoToStringSingleIdentEntity.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/NoToStringSingleIdentEntity.php new file mode 100644 index 0000000..a5ecb3d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/NoToStringSingleIdentEntity.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\Bridge\Doctrine\Tests\Fixtures; + +use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Entity; + +/** @Entity */ +class NoToStringSingleIdentEntity +{ + /** @Id @Column(type="integer") */ + protected $id; + + /** @Column(type="string", nullable=true) */ + public $name; + + public function __construct($id, $name) + { + $this->id = $id; + $this->name = $name; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleIdentEntity.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleIdentEntity.php new file mode 100644 index 0000000..6eab851 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleIdentEntity.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\Bridge\Doctrine\Tests\Fixtures; + +use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Entity; + +/** @Entity */ +class SingleIdentEntity +{ + /** @Id @Column(type="integer") */ + protected $id; + + /** @Column(type="string", nullable=true) */ + public $name; + + public function __construct($id, $name) + { + $this->id = $id; + $this->name = $name; + } + + public function __toString() + { + return (string)$this->name; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleStringIdentEntity.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleStringIdentEntity.php new file mode 100644 index 0000000..50f53b7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleStringIdentEntity.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\Bridge\Doctrine\Tests\Fixtures; + +use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Entity; + +/** @Entity */ +class SingleStringIdentEntity +{ + /** @Id @Column(type="string") */ + protected $id; + + /** @Column(type="string") */ + public $name; + + public function __construct($id, $name) + { + $this->id = $id; + $this->name = $name; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/EntityChoiceListTest.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/EntityChoiceListTest.php new file mode 100644 index 0000000..2d8aeed --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/EntityChoiceListTest.php @@ -0,0 +1,311 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Form\ChoiceList; + +use Symfony\Bridge\Doctrine\Form\ChoiceList\ORMQueryBuilderLoader; +use Symfony\Bridge\Doctrine\Tests\DoctrineOrmTestCase; +use Symfony\Bridge\Doctrine\Tests\Fixtures\ItemGroupEntity; +use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity; +use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdentEntity; +use Symfony\Bridge\Doctrine\Tests\Fixtures\NoToStringSingleIdentEntity; +use Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList; +use Symfony\Component\Form\Extension\Core\View\ChoiceView; +use Doctrine\ORM\Tools\SchemaTool; + +class EntityChoiceListTest extends DoctrineOrmTestCase +{ + const ITEM_GROUP_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\ItemGroupEntity'; + + const SINGLE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity'; + + const SINGLE_STRING_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdentEntity'; + + const COMPOSITE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity'; + + private $em; + + protected function setUp() + { + if (!class_exists('Symfony\Component\Form\Form')) { + $this->markTestSkipped('The "Form" component is not available'); + } + + parent::setUp(); + + $this->em = $this->createTestEntityManager(); + + $schemaTool = new SchemaTool($this->em); + $classes = array( + $this->em->getClassMetadata(self::ITEM_GROUP_CLASS), + $this->em->getClassMetadata(self::SINGLE_IDENT_CLASS), + $this->em->getClassMetadata(self::SINGLE_STRING_IDENT_CLASS), + $this->em->getClassMetadata(self::COMPOSITE_IDENT_CLASS), + ); + + try { + $schemaTool->dropSchema($classes); + } catch (\Exception $e) { + } + + try { + $schemaTool->createSchema($classes); + } catch (\Exception $e) { + } + } + + protected function tearDown() + { + parent::tearDown(); + + $this->em = null; + } + + /** + * @expectedException Symfony\Component\Form\Exception\FormException + * @expectedMessage Entity "Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity" passed to the choice field must have a "__toString()" method defined (or you can also override the "property" option). + */ + public function testEntitesMustHaveAToStringMethod() + { + $entity1 = new NoToStringSingleIdentEntity(1, 'Foo'); + $entity2 = new NoToStringSingleIdentEntity(2, 'Bar'); + + // Persist for managed state + $this->em->persist($entity1); + $this->em->persist($entity2); + + $choiceList = new EntityChoiceList( + $this->em, + self::SINGLE_IDENT_CLASS, + null, + null, + array( + $entity1, + $entity2, + ) + ); + + $choiceList->getValues(); + } + + /** + * @expectedException Symfony\Component\Form\Exception\FormException + */ + public function testChoicesMustBeManaged() + { + $entity1 = new SingleIdentEntity(1, 'Foo'); + $entity2 = new SingleIdentEntity(2, 'Bar'); + + // no persist here! + + $choiceList = new EntityChoiceList( + $this->em, + self::SINGLE_IDENT_CLASS, + 'name', + null, + array( + $entity1, + $entity2, + ) + ); + + // triggers loading -> exception + $choiceList->getChoices(); + } + + public function testFlattenedChoicesAreManaged() + { + $entity1 = new SingleIdentEntity(1, 'Foo'); + $entity2 = new SingleIdentEntity(2, 'Bar'); + + // Persist for managed state + $this->em->persist($entity1); + $this->em->persist($entity2); + + $choiceList = new EntityChoiceList( + $this->em, + self::SINGLE_IDENT_CLASS, + 'name', + null, + array( + $entity1, + $entity2, + ) + ); + + $this->assertSame(array(1 => $entity1, 2 => $entity2), $choiceList->getChoices()); + } + + public function testEmptyChoicesAreManaged() + { + $entity1 = new SingleIdentEntity(1, 'Foo'); + $entity2 = new SingleIdentEntity(2, 'Bar'); + + // Persist for managed state + $this->em->persist($entity1); + $this->em->persist($entity2); + + $choiceList = new EntityChoiceList( + $this->em, + self::SINGLE_IDENT_CLASS, + 'name', + null, + array() + ); + + $this->assertSame(array(), $choiceList->getChoices()); + } + + public function testNestedChoicesAreManaged() + { + $entity1 = new SingleIdentEntity(1, 'Foo'); + $entity2 = new SingleIdentEntity(2, 'Bar'); + + // Oh yeah, we're persisting with fire now! + $this->em->persist($entity1); + $this->em->persist($entity2); + + $choiceList = new EntityChoiceList( + $this->em, + self::SINGLE_IDENT_CLASS, + 'name', + null, + array( + 'group1' => array($entity1), + 'group2' => array($entity2), + ) + ); + + $this->assertSame(array(1 => $entity1, 2 => $entity2), $choiceList->getChoices()); + $this->assertEquals(array( + 'group1' => array(1 => new ChoiceView('1', 'Foo')), + 'group2' => array(2 => new ChoiceView('2', 'Bar')) + ), $choiceList->getRemainingViews()); + } + + public function testGroupBySupportsString() + { + $item1 = new ItemGroupEntity(1, 'Foo', 'Group1'); + $item2 = new ItemGroupEntity(2, 'Bar', 'Group1'); + $item3 = new ItemGroupEntity(3, 'Baz', 'Group2'); + $item4 = new ItemGroupEntity(4, 'Boo!', null); + + $this->em->persist($item1); + $this->em->persist($item2); + $this->em->persist($item3); + $this->em->persist($item4); + + $choiceList = new EntityChoiceList( + $this->em, + self::ITEM_GROUP_CLASS, + 'name', + null, + array( + $item1, + $item2, + $item3, + $item4, + ), + 'groupName' + ); + + $this->assertEquals(array(1 => $item1, 2 => $item2, 3 => $item3, 4 => $item4), $choiceList->getChoices()); + $this->assertEquals(array( + 'Group1' => array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')), + 'Group2' => array(3 => new ChoiceView('3', 'Baz')), + 4 => new ChoiceView('4', 'Boo!') + ), $choiceList->getRemainingViews()); + } + + public function testGroupByInvalidPropertyPathReturnsFlatChoices() + { + $item1 = new ItemGroupEntity(1, 'Foo', 'Group1'); + $item2 = new ItemGroupEntity(2, 'Bar', 'Group1'); + + $this->em->persist($item1); + $this->em->persist($item2); + + $choiceList = new EntityChoiceList( + $this->em, + self::ITEM_GROUP_CLASS, + 'name', + null, + array( + $item1, + $item2, + ), + 'child.that.does.not.exist' + ); + + $this->assertEquals(array( + 1 => $item1, + 2 => $item2 + ), $choiceList->getChoices()); + } + + public function testPossibleToProvideShorthandEntityName() + { + $shorthandName = 'SymfonyTestsDoctrine:SingleIdentEntity'; + + $item1 = new SingleIdentEntity(1, 'Foo'); + $item2 = new SingleIdentEntity(2, 'Bar'); + + $this->em->persist($item1); + $this->em->persist($item2); + + $choiceList = new EntityChoiceList( + $this->em, + $shorthandName, + null, + null, + null, + null + ); + + $this->assertEquals(array(1, 2), $choiceList->getValuesForChoices(array($item1, $item2))); + $this->assertEquals(array(1, 2), $choiceList->getIndicesForChoices(array($item1, $item2))); + } + + // Ticket #3446 + public function testGetEmptyArrayChoicesForEmptyValues() + { + $qb = $this->em->createQueryBuilder()->select('s')->from(self::SINGLE_IDENT_CLASS, 's'); + $entityLoader = new ORMQueryBuilderLoader($qb); + $choiceList = new EntityChoiceList( + $this->em, + self::SINGLE_IDENT_CLASS, + null, + $entityLoader + ); + + $this->assertEquals(array(), $choiceList->getChoicesForValues(array())); + } + + // https://github.com/symfony/symfony/issues/3635 + public function testSingleNonIntIdFallsBackToGeneration() + { + $entity1 = new SingleStringIdentEntity('Id 1', 'Foo'); + $entity2 = new SingleStringIdentEntity('Id 2', 'Bar'); + + // Persist for managed state + $this->em->persist($entity1); + $this->em->persist($entity2); + $this->em->flush(); + + $choiceList = new EntityChoiceList( + $this->em, + self::SINGLE_STRING_IDENT_CLASS, + 'name' + ); + + $this->assertSame(array(0 => $entity1, 1 => $entity2), $choiceList->getChoices()); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php new file mode 100644 index 0000000..38f4dc6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.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\Bridge\Doctrine\Tests\Form\Type; + +use Symfony\Component\Form\Exception\UnexpectedTypeException; +use Symfony\Component\Form\Tests\Extension\Core\Type\TypeTestCase; +use Symfony\Bridge\Doctrine\Tests\DoctrineOrmTestCase; +use Symfony\Bridge\Doctrine\Tests\Fixtures\ItemGroupEntity; +use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity; +use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdentEntity; +use Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity; +use Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeStringIdentEntity; +use Symfony\Bridge\Doctrine\Form\DoctrineOrmExtension; +use Doctrine\ORM\Tools\SchemaTool; +use Doctrine\Common\Collections\ArrayCollection; +use Symfony\Component\Form\Extension\Core\View\ChoiceView; + +class EntityTypeTest extends TypeTestCase +{ + const ITEM_GROUP_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\ItemGroupEntity'; + const SINGLE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity'; + const SINGLE_STRING_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdentEntity'; + const COMPOSITE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity'; + const COMPOSITE_STRING_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeStringIdentEntity'; + + private $em; + + protected function setUp() + { + if (!class_exists('Symfony\Component\Form\Form')) { + $this->markTestSkipped('The "Form" component is not available'); + } + + if (!class_exists('Doctrine\DBAL\Platforms\MySqlPlatform')) { + $this->markTestSkipped('Doctrine DBAL is not available.'); + } + + if (!class_exists('Doctrine\Common\Version')) { + $this->markTestSkipped('Doctrine Common is not available.'); + } + + if (!class_exists('Doctrine\ORM\EntityManager')) { + $this->markTestSkipped('Doctrine ORM is not available.'); + } + + $this->em = DoctrineOrmTestCase::createTestEntityManager(); + + parent::setUp(); + + $schemaTool = new SchemaTool($this->em); + $classes = array( + $this->em->getClassMetadata(self::ITEM_GROUP_CLASS), + $this->em->getClassMetadata(self::SINGLE_IDENT_CLASS), + $this->em->getClassMetadata(self::SINGLE_STRING_IDENT_CLASS), + $this->em->getClassMetadata(self::COMPOSITE_IDENT_CLASS), + $this->em->getClassMetadata(self::COMPOSITE_STRING_IDENT_CLASS), + ); + + try { + $schemaTool->dropSchema($classes); + } catch (\Exception $e) { + } + + try { + $schemaTool->createSchema($classes); + } catch (\Exception $e) { + } + } + + protected function tearDown() + { + parent::tearDown(); + + $this->em = null; + } + + protected function getExtensions() + { + return array_merge(parent::getExtensions(), array( + new DoctrineOrmExtension($this->createRegistryMock('default', $this->em)), + )); + } + + protected function persist(array $entities) + { + foreach ($entities as $entity) { + $this->em->persist($entity); + } + + $this->em->flush(); + // no clear, because entities managed by the choice field must + // be managed! + } + + public function testSetDataToUninitializedEntityWithNonRequired() + { + $entity1 = new SingleIdentEntity(1, 'Foo'); + $entity2 = new SingleIdentEntity(2, 'Bar'); + + $this->persist(array($entity1, $entity2)); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + 'required' => false, + 'property' => 'name' + )); + + $this->assertEquals(array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')), $field->createView()->getVar('choices')); + } + + public function testSetDataToUninitializedEntityWithNonRequiredToString() + { + $entity1 = new SingleIdentEntity(1, 'Foo'); + $entity2 = new SingleIdentEntity(2, 'Bar'); + + $this->persist(array($entity1, $entity2)); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + 'required' => false, + )); + + $this->assertEquals(array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')), $field->createView()->getVar('choices')); + } + + public function testSetDataToUninitializedEntityWithNonRequiredQueryBuilder() + { + $entity1 = new SingleIdentEntity(1, 'Foo'); + $entity2 = new SingleIdentEntity(2, 'Bar'); + + $this->persist(array($entity1, $entity2)); + $qb = $this->em->createQueryBuilder()->select('e')->from(self::SINGLE_IDENT_CLASS, 'e'); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + 'required' => false, + 'property' => 'name', + 'query_builder' => $qb + )); + + $this->assertEquals(array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')), $field->createView()->getVar('choices')); + } + + /** + * @expectedException Symfony\Component\Form\Exception\UnexpectedTypeException + */ + public function testConfigureQueryBuilderWithNonQueryBuilderAndNonClosure() + { + $field = $this->factory->createNamed('name', 'entity', null, array( + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + 'query_builder' => new \stdClass(), + )); + } + + /** + * @expectedException Symfony\Component\Form\Exception\UnexpectedTypeException + */ + public function testConfigureQueryBuilderWithClosureReturningNonQueryBuilder() + { + $field = $this->factory->createNamed('name', 'entity', null, array( + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + 'query_builder' => function () { + return new \stdClass(); + }, + )); + + $field->bind('2'); + } + + public function testSetDataSingleNull() + { + $field = $this->factory->createNamed('name', 'entity', null, array( + 'multiple' => false, + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + )); + $field->setData(null); + + $this->assertNull($field->getData()); + $this->assertSame('', $field->getClientData()); + } + + public function testSetDataMultipleExpandedNull() + { + $field = $this->factory->createNamed('name', 'entity', null, array( + 'multiple' => true, + 'expanded' => true, + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + )); + $field->setData(null); + + $this->assertNull($field->getData()); + $this->assertSame(array(), $field->getClientData()); + } + + public function testSetDataMultipleNonExpandedNull() + { + $field = $this->factory->createNamed('name', 'entity', null, array( + 'multiple' => true, + 'expanded' => false, + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + )); + $field->setData(null); + + $this->assertNull($field->getData()); + $this->assertSame(array(), $field->getClientData()); + } + + public function testSubmitSingleExpandedNull() + { + $field = $this->factory->createNamed('name', 'entity', null, array( + 'multiple' => false, + 'expanded' => true, + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + )); + $field->bind(null); + + $this->assertNull($field->getData()); + $this->assertSame(array(), $field->getClientData()); + } + + public function testSubmitSingleNonExpandedNull() + { + $field = $this->factory->createNamed('name', 'entity', null, array( + 'multiple' => false, + 'expanded' => false, + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + )); + $field->bind(null); + + $this->assertNull($field->getData()); + $this->assertSame('', $field->getClientData()); + } + + public function testSubmitMultipleNull() + { + $field = $this->factory->createNamed('name', 'entity', null, array( + 'multiple' => true, + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + )); + $field->bind(null); + + $this->assertEquals(new ArrayCollection(), $field->getData()); + $this->assertSame(array(), $field->getClientData()); + } + + public function testSubmitSingleNonExpandedSingleIdentifier() + { + $entity1 = new SingleIdentEntity(1, 'Foo'); + $entity2 = new SingleIdentEntity(2, 'Bar'); + + $this->persist(array($entity1, $entity2)); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'multiple' => false, + 'expanded' => false, + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + 'property' => 'name', + )); + + $field->bind('2'); + + $this->assertTrue($field->isSynchronized()); + $this->assertSame($entity2, $field->getData()); + $this->assertSame('2', $field->getClientData()); + } + + public function testSubmitSingleNonExpandedCompositeIdentifier() + { + $entity1 = new CompositeIdentEntity(10, 20, 'Foo'); + $entity2 = new CompositeIdentEntity(30, 40, 'Bar'); + + $this->persist(array($entity1, $entity2)); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'multiple' => false, + 'expanded' => false, + 'em' => 'default', + 'class' => self::COMPOSITE_IDENT_CLASS, + 'property' => 'name', + )); + + // the collection key is used here + $field->bind('1'); + + $this->assertTrue($field->isSynchronized()); + $this->assertSame($entity2, $field->getData()); + $this->assertSame('1', $field->getClientData()); + } + + public function testSubmitMultipleNonExpandedSingleIdentifier() + { + $entity1 = new SingleIdentEntity(1, 'Foo'); + $entity2 = new SingleIdentEntity(2, 'Bar'); + $entity3 = new SingleIdentEntity(3, 'Baz'); + + $this->persist(array($entity1, $entity2, $entity3)); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'multiple' => true, + 'expanded' => false, + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + 'property' => 'name', + )); + + $field->bind(array('1', '3')); + + $expected = new ArrayCollection(array($entity1, $entity3)); + + $this->assertTrue($field->isSynchronized()); + $this->assertEquals($expected, $field->getData()); + $this->assertSame(array('1', '3'), $field->getClientData()); + } + + public function testSubmitMultipleNonExpandedSingleIdentifier_existingData() + { + $entity1 = new SingleIdentEntity(1, 'Foo'); + $entity2 = new SingleIdentEntity(2, 'Bar'); + $entity3 = new SingleIdentEntity(3, 'Baz'); + + $this->persist(array($entity1, $entity2, $entity3)); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'multiple' => true, + 'expanded' => false, + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + 'property' => 'name', + )); + + $existing = new ArrayCollection(array(0 => $entity2)); + + $field->setData($existing); + $field->bind(array('1', '3')); + + // entry with index 0 ($entity2) was replaced + $expected = new ArrayCollection(array(0 => $entity1, 1 => $entity3)); + + $this->assertTrue($field->isSynchronized()); + $this->assertEquals($expected, $field->getData()); + // same object still, useful if it is a PersistentCollection + $this->assertSame($existing, $field->getData()); + $this->assertSame(array('1', '3'), $field->getClientData()); + } + + public function testSubmitMultipleNonExpandedCompositeIdentifier() + { + $entity1 = new CompositeIdentEntity(10, 20, 'Foo'); + $entity2 = new CompositeIdentEntity(30, 40, 'Bar'); + $entity3 = new CompositeIdentEntity(50, 60, 'Baz'); + + $this->persist(array($entity1, $entity2, $entity3)); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'multiple' => true, + 'expanded' => false, + 'em' => 'default', + 'class' => self::COMPOSITE_IDENT_CLASS, + 'property' => 'name', + )); + + // because of the composite key collection keys are used + $field->bind(array('0', '2')); + + $expected = new ArrayCollection(array($entity1, $entity3)); + + $this->assertTrue($field->isSynchronized()); + $this->assertEquals($expected, $field->getData()); + $this->assertSame(array('0', '2'), $field->getClientData()); + } + + public function testSubmitMultipleNonExpandedCompositeIdentifier_existingData() + { + $entity1 = new CompositeIdentEntity(10, 20, 'Foo'); + $entity2 = new CompositeIdentEntity(30, 40, 'Bar'); + $entity3 = new CompositeIdentEntity(50, 60, 'Baz'); + + $this->persist(array($entity1, $entity2, $entity3)); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'multiple' => true, + 'expanded' => false, + 'em' => 'default', + 'class' => self::COMPOSITE_IDENT_CLASS, + 'property' => 'name', + )); + + $existing = new ArrayCollection(array(0 => $entity2)); + + $field->setData($existing); + $field->bind(array('0', '2')); + + // entry with index 0 ($entity2) was replaced + $expected = new ArrayCollection(array(0 => $entity1, 1 => $entity3)); + + $this->assertTrue($field->isSynchronized()); + $this->assertEquals($expected, $field->getData()); + // same object still, useful if it is a PersistentCollection + $this->assertSame($existing, $field->getData()); + $this->assertSame(array('0', '2'), $field->getClientData()); + } + + public function testSubmitSingleExpanded() + { + $entity1 = new SingleIdentEntity(1, 'Foo'); + $entity2 = new SingleIdentEntity(2, 'Bar'); + + $this->persist(array($entity1, $entity2)); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'multiple' => false, + 'expanded' => true, + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + 'property' => 'name', + )); + + $field->bind('2'); + + $this->assertTrue($field->isSynchronized()); + $this->assertSame($entity2, $field->getData()); + $this->assertFalse($field['1']->getData()); + $this->assertTrue($field['2']->getData()); + $this->assertNull($field['1']->getClientData()); + $this->assertSame('2', $field['2']->getClientData()); + } + + public function testSubmitMultipleExpanded() + { + $entity1 = new SingleIdentEntity(1, 'Foo'); + $entity2 = new SingleIdentEntity(2, 'Bar'); + $entity3 = new SingleIdentEntity(3, 'Bar'); + + $this->persist(array($entity1, $entity2, $entity3)); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'multiple' => true, + 'expanded' => true, + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + 'property' => 'name', + )); + + $field->bind(array('1', '3')); + + $expected = new ArrayCollection(array($entity1, $entity3)); + + $this->assertTrue($field->isSynchronized()); + $this->assertEquals($expected, $field->getData()); + $this->assertTrue($field['1']->getData()); + $this->assertFalse($field['2']->getData()); + $this->assertTrue($field['3']->getData()); + $this->assertSame('1', $field['1']->getClientData()); + $this->assertNull($field['2']->getClientData()); + $this->assertSame('3', $field['3']->getClientData()); + } + + public function testOverrideChoices() + { + $entity1 = new SingleIdentEntity(1, 'Foo'); + $entity2 = new SingleIdentEntity(2, 'Bar'); + $entity3 = new SingleIdentEntity(3, 'Baz'); + + $this->persist(array($entity1, $entity2, $entity3)); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + // not all persisted entities should be displayed + 'choices' => array($entity1, $entity2), + 'property' => 'name', + )); + + $field->bind('2'); + + $this->assertEquals(array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')), $field->createView()->getVar('choices')); + $this->assertTrue($field->isSynchronized()); + $this->assertSame($entity2, $field->getData()); + $this->assertSame('2', $field->getClientData()); + } + + public function testGroupByChoices() + { + $item1 = new ItemGroupEntity(1, 'Foo', 'Group1'); + $item2 = new ItemGroupEntity(2, 'Bar', 'Group1'); + $item3 = new ItemGroupEntity(3, 'Baz', 'Group2'); + $item4 = new ItemGroupEntity(4, 'Boo!', null); + + $this->persist(array($item1, $item2, $item3, $item4)); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'em' => 'default', + 'class' => self::ITEM_GROUP_CLASS, + 'choices' => array($item1, $item2, $item3, $item4), + 'property' => 'name', + 'group_by' => 'groupName', + )); + + $field->bind('2'); + + $this->assertSame('2', $field->getClientData()); + $this->assertEquals(array( + 'Group1' => array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')), + 'Group2' => array(3 => new ChoiceView('3', 'Baz')), + '4' => new ChoiceView('4', 'Boo!') + ), $field->createView()->getVar('choices')); + } + + public function testDisallowChoicesThatAreNotIncluded_choicesSingleIdentifier() + { + $entity1 = new SingleIdentEntity(1, 'Foo'); + $entity2 = new SingleIdentEntity(2, 'Bar'); + $entity3 = new SingleIdentEntity(3, 'Baz'); + + $this->persist(array($entity1, $entity2, $entity3)); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + 'choices' => array($entity1, $entity2), + 'property' => 'name', + )); + + $field->bind('3'); + + $this->assertFalse($field->isSynchronized()); + $this->assertNull($field->getData()); + } + + public function testDisallowChoicesThatAreNotIncluded_choicesCompositeIdentifier() + { + $entity1 = new CompositeIdentEntity(10, 20, 'Foo'); + $entity2 = new CompositeIdentEntity(30, 40, 'Bar'); + $entity3 = new CompositeIdentEntity(50, 60, 'Baz'); + + $this->persist(array($entity1, $entity2, $entity3)); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'em' => 'default', + 'class' => self::COMPOSITE_IDENT_CLASS, + 'choices' => array($entity1, $entity2), + 'property' => 'name', + )); + + $field->bind('2'); + + $this->assertFalse($field->isSynchronized()); + $this->assertNull($field->getData()); + } + + public function testDisallowChoicesThatAreNotIncludedQueryBuilderSingleIdentifier() + { + $entity1 = new SingleIdentEntity(1, 'Foo'); + $entity2 = new SingleIdentEntity(2, 'Bar'); + $entity3 = new SingleIdentEntity(3, 'Baz'); + + $this->persist(array($entity1, $entity2, $entity3)); + + $repository = $this->em->getRepository(self::SINGLE_IDENT_CLASS); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + 'query_builder' => $repository->createQueryBuilder('e') + ->where('e.id IN (1, 2)'), + 'property' => 'name', + )); + + $field->bind('3'); + + $this->assertFalse($field->isSynchronized()); + $this->assertNull($field->getData()); + } + + public function testDisallowChoicesThatAreNotIncludedQueryBuilderAsClosureSingleIdentifier() + { + $entity1 = new SingleIdentEntity(1, 'Foo'); + $entity2 = new SingleIdentEntity(2, 'Bar'); + $entity3 = new SingleIdentEntity(3, 'Baz'); + + $this->persist(array($entity1, $entity2, $entity3)); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + 'query_builder' => function ($repository) { + return $repository->createQueryBuilder('e') + ->where('e.id IN (1, 2)'); + }, + 'property' => 'name', + )); + + $field->bind('3'); + + $this->assertFalse($field->isSynchronized()); + $this->assertNull($field->getData()); + } + + public function testDisallowChoicesThatAreNotIncludedQueryBuilderAsClosureCompositeIdentifier() + { + $entity1 = new CompositeIdentEntity(10, 20, 'Foo'); + $entity2 = new CompositeIdentEntity(30, 40, 'Bar'); + $entity3 = new CompositeIdentEntity(50, 60, 'Baz'); + + $this->persist(array($entity1, $entity2, $entity3)); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'em' => 'default', + 'class' => self::COMPOSITE_IDENT_CLASS, + 'query_builder' => function ($repository) { + return $repository->createQueryBuilder('e') + ->where('e.id1 IN (10, 50)'); + }, + 'property' => 'name', + )); + + $field->bind('2'); + + $this->assertFalse($field->isSynchronized()); + $this->assertNull($field->getData()); + } + + public function testSubmitSingleStringIdentifier() + { + $entity1 = new SingleStringIdentEntity('foo', 'Foo'); + + $this->persist(array($entity1)); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'multiple' => false, + 'expanded' => false, + 'em' => 'default', + 'class' => self::SINGLE_STRING_IDENT_CLASS, + 'property' => 'name', + )); + + $field->bind('foo'); + + $this->assertTrue($field->isSynchronized()); + $this->assertSame($entity1, $field->getData()); + $this->assertSame('foo', $field->getClientData()); + } + + public function testSubmitCompositeStringIdentifier() + { + $entity1 = new CompositeStringIdentEntity('foo1', 'foo2', 'Foo'); + + $this->persist(array($entity1)); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'multiple' => false, + 'expanded' => false, + 'em' => 'default', + 'class' => self::COMPOSITE_STRING_IDENT_CLASS, + 'property' => 'name', + )); + + // the collection key is used here + $field->bind('0'); + + $this->assertTrue($field->isSynchronized()); + $this->assertSame($entity1, $field->getData()); + $this->assertSame('0', $field->getClientData()); + } + + protected function createRegistryMock($name, $em) + { + $registry = $this->getMock('Doctrine\Common\Persistence\ManagerRegistry'); + $registry->expects($this->any()) + ->method('getManager') + ->with($this->equalTo($name)) + ->will($this->returnValue($em)); + + return $registry; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/HttpFoundation/DbalSessionHandlerTest.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/HttpFoundation/DbalSessionHandlerTest.php new file mode 100644 index 0000000..2238187 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/HttpFoundation/DbalSessionHandlerTest.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\Bridge\Doctrine\HttpFoundation; + +use Symfony\Bridge\Doctrine\HttpFoundation\DbalSessionHandler; + +/** + * Test class for DbalSessionHandler. + * + * @author Drak + */ +class DbalSessionHandlerTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\HttpFoundation\Request')) { + $this->markTestSkipped('The "HttpFoundation" component is not available'); + } + } + + public function testConstruct() + { + $this->connection = $this->getMock('Doctrine\DBAL\Driver\Connection'); + $mock = $this->getMockBuilder('Symfony\Bridge\Doctrine\HttpFoundation\DbalSessionHandler'); + $mock->setConstructorArgs(array($this->connection)); + $this->driver = $mock->getMock(); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php new file mode 100644 index 0000000..3df1be5 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.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\Bridge\Doctrine\Tests\Security\User; + +use Symfony\Bridge\Doctrine\Tests\DoctrineOrmTestCase; +use Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity; +use Symfony\Bridge\Doctrine\Security\User\EntityUserProvider; +use Doctrine\ORM\Tools\SchemaTool; + +class EntityUserProviderTest extends DoctrineOrmTestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\Security\Core\SecurityContext')) { + $this->markTestSkipped('The "Security" component is not available'); + } + + parent::setUp(); + } + + public function testRefreshUserGetsUserByPrimaryKey() + { + $em = $this->createTestEntityManager(); + $this->createSchema($em); + + $user1 = new CompositeIdentEntity(1, 1, 'user1'); + $user2 = new CompositeIdentEntity(1, 2, 'user2'); + + $em->persist($user1); + $em->persist($user2); + $em->flush(); + + $provider = new EntityUserProvider($this->getManager($em), 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity', 'name'); + + // try to change the user identity + $user1->name = 'user2'; + + $this->assertSame($user1, $provider->refreshUser($user1)); + } + + public function testRefreshUserRequiresId() + { + $em = $this->createTestEntityManager(); + + $user1 = new CompositeIdentEntity(null, null, 'user1'); + $provider = new EntityUserProvider($this->getManager($em), 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity', 'name'); + + $this->setExpectedException( + 'InvalidArgumentException', + 'You cannot refresh a user from the EntityUserProvider that does not contain an identifier. The user object has to be serialized with its own identifier mapped by Doctrine' + ); + $provider->refreshUser($user1); + } + + public function testRefreshInvalidUser() + { + $em = $this->createTestEntityManager(); + $this->createSchema($em); + + $user1 = new CompositeIdentEntity(1, 1, 'user1'); + + $em->persist($user1); + $em->flush(); + + $provider = new EntityUserProvider($this->getManager($em), 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity', 'name'); + + $user2 = new CompositeIdentEntity(1, 2, 'user2'); + $this->setExpectedException( + 'Symfony\Component\Security\Core\Exception\UsernameNotFoundException', + 'User with id {"id1":1,"id2":2} not found' + ); + $provider->refreshUser($user2); + } + + public function testSupportProxy() + { + $em = $this->createTestEntityManager(); + $this->createSchema($em); + + $user1 = new CompositeIdentEntity(1, 1, 'user1'); + + $em->persist($user1); + $em->flush(); + $em->clear(); + + $provider = new EntityUserProvider($this->getManager($em), 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity', 'name'); + + $user2 = $em->getReference('Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity', array('id1' => 1, 'id2' => 1)); + $this->assertTrue($provider->supportsClass(get_class($user2))); + } + + private function getManager($em, $name = null) + { + $manager = $this->getMock('Doctrine\Common\Persistence\ManagerRegistry'); + $manager->expects($this->once()) + ->method('getManager') + ->with($this->equalTo($name)) + ->will($this->returnValue($em)); + + return $manager; + } + + private function createSchema($em) + { + $schemaTool = new SchemaTool($em); + $schemaTool->createSchema(array( + $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity'), + )); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueValidatorTest.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueValidatorTest.php new file mode 100644 index 0000000..9dac62d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueValidatorTest.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\Bridge\Doctrine\Tests\Validator\Constraints; + +use Symfony\Bridge\Doctrine\Tests\DoctrineOrmTestCase; +use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity; +use Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity; +use Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity; +use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; +use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator; +use Symfony\Component\Validator\Mapping\ClassMetadata; +use Symfony\Component\Validator\Validator; +use Doctrine\ORM\Tools\SchemaTool; + +class UniqueValidatorTest extends DoctrineOrmTestCase +{ + protected function setUp() + { + parent::setUp(); + + if (!class_exists('Symfony\Component\Security\Core\SecurityContext')) { + $this->markTestSkipped('The "Security" component is not available'); + } + + if (!class_exists('Symfony\Component\Validator\Constraint')) { + $this->markTestSkipped('The "Validator" component is not available'); + } + } + + protected function createRegistryMock($entityManagerName, $em) + { + $registry = $this->getMock('Doctrine\Common\Persistence\ManagerRegistry'); + $registry->expects($this->any()) + ->method('getManager') + ->with($this->equalTo($entityManagerName)) + ->will($this->returnValue($em)); + + return $registry; + } + + protected function createMetadataFactoryMock($metadata) + { + $metadataFactory = $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface'); + $metadataFactory->expects($this->any()) + ->method('getClassMetadata') + ->with($this->equalTo($metadata->name)) + ->will($this->returnValue($metadata)); + + return $metadataFactory; + } + + protected function createValidatorFactory($uniqueValidator) + { + $validatorFactory = $this->getMock('Symfony\Component\Validator\ConstraintValidatorFactoryInterface'); + $validatorFactory->expects($this->any()) + ->method('getInstance') + ->with($this->isInstanceOf('Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity')) + ->will($this->returnValue($uniqueValidator)); + + return $validatorFactory; + } + + public function createValidator($entityManagerName, $em, $validateClass = null, $uniqueFields = null) + { + if (!$validateClass) { + $validateClass = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity'; + } + if (!$uniqueFields) { + $uniqueFields = array('name'); + } + + $registry = $this->createRegistryMock($entityManagerName, $em); + + $uniqueValidator = new UniqueEntityValidator($registry); + + $metadata = new ClassMetadata($validateClass); + $metadata->addConstraint(new UniqueEntity(array('fields' => $uniqueFields, 'em' => $entityManagerName))); + + $metadataFactory = $this->createMetadataFactoryMock($metadata); + $validatorFactory = $this->createValidatorFactory($uniqueValidator); + + return new Validator($metadataFactory, $validatorFactory); + } + + private function createSchema($em) + { + $schemaTool = new SchemaTool($em); + $schemaTool->createSchema(array( + $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity'), + $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity'), + $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity'), + )); + } + + /** + * This is a functional test as there is a large integration necessary to get the validator working. + */ + public function testValidateUniqueness() + { + $entityManagerName = "foo"; + $em = $this->createTestEntityManager(); + $this->createSchema($em); + $validator = $this->createValidator($entityManagerName, $em); + + $entity1 = new SingleIdentEntity(1, 'Foo'); + $violationsList = $validator->validate($entity1); + $this->assertEquals(0, $violationsList->count(), "No violations found on entity before it is saved to the database."); + + $em->persist($entity1); + $em->flush(); + + $violationsList = $validator->validate($entity1); + $this->assertEquals(0, $violationsList->count(), "No violations found on entity after it was saved to the database."); + + $entity2 = new SingleIdentEntity(2, 'Foo'); + + $violationsList = $validator->validate($entity2); + $this->assertEquals(1, $violationsList->count(), "No violations found on entity after it was saved to the database."); + + $violation = $violationsList[0]; + $this->assertEquals('This value is already used.', $violation->getMessage()); + $this->assertEquals('name', $violation->getPropertyPath()); + $this->assertEquals('Foo', $violation->getInvalidValue()); + } + + public function testValidateUniquenessWithNull() + { + $entityManagerName = "foo"; + $em = $this->createTestEntityManager(); + $this->createSchema($em); + $validator = $this->createValidator($entityManagerName, $em); + + $entity1 = new SingleIdentEntity(1, null); + $entity2 = new SingleIdentEntity(2, null); + + $em->persist($entity1); + $em->persist($entity2); + $em->flush(); + + $violationsList = $validator->validate($entity1); + $this->assertEquals(0, $violationsList->count(), "No violations found on entity having a null value."); + } + + public function testValidateUniquenessAfterConsideringMultipleQueryResults() + { + $entityManagerName = "foo"; + $em = $this->createTestEntityManager(); + $this->createSchema($em); + $validator = $this->createValidator($entityManagerName, $em); + + $entity1 = new SingleIdentEntity(1, 'foo'); + $entity2 = new SingleIdentEntity(2, 'foo'); + + $em->persist($entity1); + $em->persist($entity2); + $em->flush(); + + $violationsList = $validator->validate($entity1); + $this->assertEquals(1, $violationsList->count(), 'Violation found on entity with conflicting entity existing in the database.'); + + $violationsList = $validator->validate($entity2); + $this->assertEquals(1, $violationsList->count(), 'Violation found on entity with conflicting entity existing in the database.'); + } + + /** + * @group GH-1635 + */ + public function testAssociatedEntity() + { + $entityManagerName = "foo"; + $em = $this->createTestEntityManager(); + $this->createSchema($em); + $validator = $this->createValidator($entityManagerName, $em, 'Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity', array('single')); + + $entity1 = new SingleIdentEntity(1, 'foo'); + $associated = new AssociationEntity(); + $associated->single = $entity1; + + $em->persist($entity1); + $em->persist($associated); + $em->flush(); + + $violationsList = $validator->validate($associated); + $this->assertEquals(0, $violationsList->count()); + + $associated2 = new AssociationEntity(); + $associated2->single = $entity1; + + $em->persist($associated2); + $em->flush(); + + $violationsList = $validator->validate($associated2); + $this->assertEquals(1, $violationsList->count()); + } + + /** + * @group GH-1635 + */ + public function testAssociatedCompositeEntity() + { + $entityManagerName = "foo"; + $em = $this->createTestEntityManager(); + $this->createSchema($em); + $validator = $this->createValidator($entityManagerName, $em, 'Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity', array('composite')); + + $composite = new CompositeIdentEntity(1, 1, "test"); + $associated = new AssociationEntity(); + $associated->composite = $composite; + + $em->persist($composite); + $em->persist($associated); + $em->flush(); + + $this->setExpectedException( + 'Symfony\Component\Validator\Exception\ConstraintDefinitionException', + 'Associated entities are not allowed to have more than one identifier field' + ); + $violationsList = $validator->validate($associated); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/bootstrap.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/bootstrap.php new file mode 100644 index 0000000..994592e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Tests/bootstrap.php @@ -0,0 +1,70 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +spl_autoload_register($loader = function ($class) { + foreach (array( + 'SYMFONY_HTTP_FOUNDATION' => 'HttpFoundation', + 'SYMFONY_DEPENDENCY_INJECTION' => 'DependencyInjection', + 'SYMFONY_FORM' => 'Form', + 'SYMFONY_SECURITY' => 'Security', + 'SYMFONY_VALIDATOR' => 'Validator', + 'SYMFONY_HTTP_KERNEL' => 'HttpKernel', + 'SYMFONY_EVENT_DISPATCHER' => 'EventDispatcher', + ) as $env => $name) { + if (isset($_SERVER[$env]) && 0 === strpos(ltrim($class, '/'), 'Symfony\Component\\'.$name)) { + if (file_exists($file = $_SERVER[$env].'/'.substr(str_replace('\\', '/', $class), strlen('Symfony\Component\\'.$name)).'.php')) { + require_once $file; + } + } + } + + if (isset($_SERVER['SYMFONY_HTTP_FOUNDATION']) && 'SessionHandlerInterface' === ltrim($class, '/')) { + require_once $_SERVER['SYMFONY_HTTP_FOUNDATION'].'/Resources/stubs/SessionHandlerInterface.php'; + } + + if (isset($_SERVER['DOCTRINE_FIXTURES']) && 0 === strpos(ltrim($class, '/'), 'Doctrine\Common\DataFixtures')) { + if (file_exists($file = $_SERVER['DOCTRINE_FIXTURES'].'/lib/'.str_replace('\\', '/', $class).'.php')) { + require_once $file; + } + } + + if (isset($_SERVER['DOCTRINE_COMMON']) && 0 === strpos(ltrim($class, '/'), 'Doctrine\Common')) { + if (file_exists($file = $_SERVER['DOCTRINE_COMMON'].'/lib/'.str_replace('\\', '/', $class).'.php')) { + require_once $file; + } + } + + if (isset($_SERVER['DOCTRINE_DBAL']) && 0 === strpos(ltrim($class, '/'), 'Doctrine\DBAL')) { + if (file_exists($file = $_SERVER['DOCTRINE_DBAL'].'/lib/'.str_replace('\\', '/', $class).'.php')) { + require_once $file; + } + } + + if (isset($_SERVER['DOCTRINE_ORM']) && 0 === strpos(ltrim($class, '/'), 'Doctrine\ORM')) { + if (file_exists($file = $_SERVER['DOCTRINE_ORM'].'/lib/'.str_replace('\\', '/', $class).'.php')) { + require_once $file; + } + } + + if (0 === strpos(ltrim($class, '/'), 'Symfony\Bridge\Doctrine')) { + if (file_exists($file = __DIR__.'/../'.substr(str_replace('\\', '/', $class), strlen('Symfony\Bridge\Doctrine')).'.php')) { + require_once $file; + } + } +}); + +if (isset($_SERVER['DOCTRINE_COMMON'])) { + Doctrine\Common\Annotations\AnnotationRegistry::registerLoader(function($class) use ($loader) { + $loader($class); + + return class_exists($class, false); + }); +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php new file mode 100644 index 0000000..be9b9ee --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.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\Bridge\Doctrine\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * Constraint for the Unique Entity validator + * + * @Annotation + * @author Benjamin Eberlei + */ +class UniqueEntity extends Constraint +{ + public $message = 'This value is already used.'; + public $service = 'doctrine.orm.validator.unique'; + public $em = null; + public $fields = array(); + + public function getRequiredOptions() + { + return array('fields'); + } + + /** + * The validator must be defined as a service with this name. + * + * @return string + */ + public function validatedBy() + { + return $this->service; + } + + /** + * {@inheritDoc} + */ + public function getTargets() + { + return self::CLASS_CONSTRAINT; + } + + public function getDefaultOption() + { + return 'fields'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php new file mode 100644 index 0000000..38929b0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.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\Bridge\Doctrine\Validator\Constraints; + +use Doctrine\Common\Persistence\ManagerRegistry; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; +use Symfony\Component\Validator\ConstraintValidator; + +/** + * Unique Entity Validator checks if one or a set of fields contain unique values. + * + * @author Benjamin Eberlei + */ +class UniqueEntityValidator extends ConstraintValidator +{ + /** + * @var ManagerRegistry + */ + private $registry; + + /** + * @param ManagerRegistry $registry + */ + public function __construct(ManagerRegistry $registry) + { + $this->registry = $registry; + } + + /** + * @param object $entity + * @param Constraint $constraint + */ + public function validate($entity, Constraint $constraint) + { + if (!is_array($constraint->fields) && !is_string($constraint->fields)) { + throw new UnexpectedTypeException($constraint->fields, 'array'); + } + + $fields = (array) $constraint->fields; + + if (0 === count($fields)) { + throw new ConstraintDefinitionException('At least one field has to be specified.'); + } + + if ($constraint->em) { + $em = $this->registry->getManager($constraint->em); + } else { + $em = $this->registry->getManagerForClass(get_class($entity)); + } + + $className = $this->context->getCurrentClass(); + $class = $em->getClassMetadata($className); + /* @var $class \Doctrine\Common\Persistence\Mapping\ClassMetadata */ + + $criteria = array(); + foreach ($fields as $fieldName) { + if (!$class->hasField($fieldName) && !$class->hasAssociation($fieldName)) { + throw new ConstraintDefinitionException("Only field names mapped by Doctrine can be validated for uniqueness."); + } + + $criteria[$fieldName] = $class->reflFields[$fieldName]->getValue($entity); + + if (null === $criteria[$fieldName]) { + return; + } + + if ($class->hasAssociation($fieldName)) { + /* Ensure the Proxy is initialized before using reflection to + * read its identifiers. This is necessary because the wrapped + * getter methods in the Proxy are being bypassed. + */ + $em->initializeObject($criteria[$fieldName]); + + $relatedClass = $em->getClassMetadata($class->getAssociationTargetClass($fieldName)); + $relatedId = $relatedClass->getIdentifierValues($criteria[$fieldName]); + + if (count($relatedId) > 1) { + throw new ConstraintDefinitionException( + "Associated entities are not allowed to have more than one identifier field to be " . + "part of a unique constraint in: " . $class->getName() . "#" . $fieldName + ); + } + $criteria[$fieldName] = array_pop($relatedId); + } + } + + $repository = $em->getRepository($className); + $result = $repository->findBy($criteria); + + /* If the result is a MongoCursor, it must be advanced to the first + * element. Rewinding should have no ill effect if $result is another + * iterator implementation. + */ + if ($result instanceof \Iterator) { + $result->rewind(); + } + + /* If no entity matched the query criteria or a single entity matched, + * which is the same as the entity being validated, the criteria is + * unique. + */ + if (0 === count($result) || (1 === count($result) && $entity === ($result instanceof \Iterator ? $result->current() : current($result)))) { + return; + } + + $this->context->addViolationAtSubPath($fields[0], $constraint->message, array(), $criteria[$fields[0]]); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Validator/DoctrineInitializer.php b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Validator/DoctrineInitializer.php new file mode 100644 index 0000000..42cafdd --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Validator/DoctrineInitializer.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\Bridge\Doctrine\Validator; + +use Doctrine\Common\Persistence\ManagerRegistry; +use Symfony\Component\Validator\ObjectInitializerInterface; + +/** + * Automatically loads proxy object before validation. + * + * @author Fabien Potencier + */ +class DoctrineInitializer implements ObjectInitializerInterface +{ + protected $registry; + + public function __construct(ManagerRegistry $registry) + { + $this->registry = $registry; + } + + public function initialize($object) + { + $manager = $this->registry->getManagerForClass(get_class($object)); + if (null !== $manager) { + $manager->initializeObject($object); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/composer.json b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/composer.json new file mode 100644 index 0000000..df69458 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/composer.json @@ -0,0 +1,38 @@ +{ + "name": "symfony/doctrine-bridge", + "type": "symfony-bridge", + "description": "Symfony Doctrine Bridge", + "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", + "doctrine/common": ">=2.2,<2.4-dev" + }, + "suggest": { + "symfony/form": "self.version", + "symfony/validator": "self.version", + "doctrine/data-fixtures": "1.0.*", + "doctrine/dbal": ">=2.2,<2.4-dev", + "doctrine/orm": ">=2.2,<2.4-dev" + }, + "autoload": { + "psr-0": { "Symfony\\Bridge\\Doctrine": "" } + }, + "target-dir": "Symfony/Bridge/Doctrine", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/phpunit.xml.dist b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/phpunit.xml.dist new file mode 100644 index 0000000..779a6e0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/phpunit.xml.dist @@ -0,0 +1,29 @@ + + + + + + ./Tests/ + + + + + + ./ + + ./Resources + ./Tests + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/CHANGELOG.md b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/CHANGELOG.md new file mode 100644 index 0000000..88ecedd --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/CHANGELOG.md @@ -0,0 +1,7 @@ +CHANGELOG +========= + +2.1.0 +----- + + * added ChromePhpHandler diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Handler/ChromePhpHandler.php b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Handler/ChromePhpHandler.php new file mode 100644 index 0000000..81766d7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Handler/ChromePhpHandler.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\Bridge\Monolog\Handler; + +use Monolog\Handler\ChromePHPHandler as BaseChromePhpHandler; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Component\HttpKernel\HttpKernelInterface; + +/** + * ChromePhpHandler. + * + * @author Christophe Coevoet + */ +class ChromePhpHandler extends BaseChromePhpHandler +{ + /** + * @var array + */ + private $headers = array(); + + /** + * @var Response + */ + private $response; + + /** + * Adds the headers to the response once it's created + */ + public function onKernelResponse(FilterResponseEvent $event) + { + if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) { + return; + } + + if (!preg_match('{\bChrome/\d+[\.\d+]*\b}', $event->getRequest()->headers->get('User-Agent'))) { + + $this->sendHeaders = false; + $this->headers = array(); + + return; + } + + $this->response = $event->getResponse(); + foreach ($this->headers as $header => $content) { + $this->response->headers->set($header, $content); + } + $this->headers = array(); + } + + /** + * {@inheritDoc} + */ + protected function sendHeader($header, $content) + { + if (!$this->sendHeaders) { + return; + } + + if ($this->response) { + $this->response->headers->set($header, $content); + } else { + $this->headers[$header] = $content; + } + } + + /** + * Override default behavior since we check it in onKernelResponse + */ + protected function headersAccepted() + { + return true; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Handler/DebugHandler.php b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Handler/DebugHandler.php new file mode 100644 index 0000000..e1c1f51 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Handler/DebugHandler.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\Bridge\Monolog\Handler; + +use Monolog\Logger; +use Monolog\Handler\TestHandler; +use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; + +/** + * DebugLogger. + * + * @author Jordi Boggiano + */ +class DebugHandler extends TestHandler implements DebugLoggerInterface +{ + /** + * {@inheritdoc} + */ + public function getLogs() + { + $records = array(); + foreach ($this->records as $record) { + $records[] = array( + 'timestamp' => $record['datetime']->getTimestamp(), + 'message' => $record['message'], + 'priority' => $record['level'], + 'priorityName' => $record['level_name'], + 'context' => $record['context'], + ); + } + + return $records; + } + + /** + * {@inheritdoc} + */ + public function countErrors() + { + $cnt = 0; + foreach (array(Logger::ERROR, Logger::CRITICAL, Logger::ALERT) as $level) { + if (isset($this->recordsByLevel[$level])) { + $cnt += count($this->recordsByLevel[$level]); + } + } + + return $cnt; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Handler/FirePHPHandler.php b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Handler/FirePHPHandler.php new file mode 100644 index 0000000..f36cd9f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Handler/FirePHPHandler.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\Bridge\Monolog\Handler; + +use Monolog\Handler\FirePHPHandler as BaseFirePHPHandler; +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\HttpKernelInterface; + +/** + * FirePHPHandler. + * + * @author Jordi Boggiano + */ +class FirePHPHandler extends BaseFirePHPHandler +{ + /** + * @var array + */ + private $headers = array(); + + /** + * @var Response + */ + private $response; + + /** + * Adds the headers to the response once it's created + */ + public function onKernelResponse(FilterResponseEvent $event) + { + if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) { + return; + } + + if (!preg_match('{\bFirePHP/\d+\.\d+\b}', $event->getRequest()->headers->get('User-Agent')) + && !$event->getRequest()->headers->has('X-FirePHP-Version')) { + + $this->sendHeaders = false; + $this->headers = array(); + + return; + } + + $this->response = $event->getResponse(); + foreach ($this->headers as $header => $content) { + $this->response->headers->set($header, $content); + } + $this->headers = array(); + } + + /** + * {@inheritDoc} + */ + protected function sendHeader($header, $content) + { + if (!$this->sendHeaders) { + return; + } + + if ($this->response) { + $this->response->headers->set($header, $content); + } else { + $this->headers[$header] = $content; + } + } + + /** + * Override default behavior since we check the user agent in onKernelResponse + */ + protected function headersAccepted() + { + return true; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/LICENSE b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/LICENSE new file mode 100644 index 0000000..cdffe7a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 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/symfony/src/Symfony/Bridge/Monolog/Logger.php b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Logger.php new file mode 100644 index 0000000..f818381 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Logger.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\Bridge\Monolog; + +use Monolog\Logger as BaseLogger; +use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; + +/** + * Logger. + * + * @author Fabien Potencier + */ +class Logger extends BaseLogger implements LoggerInterface, DebugLoggerInterface +{ + /** + * @see Symfony\Component\HttpKernel\Log\DebugLoggerInterface + */ + public function getLogs() + { + if ($logger = $this->getDebugLogger()) { + return $logger->getLogs(); + } + } + + /** + * @see Symfony\Component\HttpKernel\Log\DebugLoggerInterface + */ + public function countErrors() + { + if ($logger = $this->getDebugLogger()) { + return $logger->countErrors(); + } + } + + /** + * Returns a DebugLoggerInterface instance if one is registered with this logger. + * + * @return DebugLoggerInterface A DebugLoggerInterface instance or null if none is registered + */ + private function getDebugLogger() + { + foreach ($this->handlers as $handler) { + if ($handler instanceof DebugLoggerInterface) { + return $handler; + } + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Processor/WebProcessor.php b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Processor/WebProcessor.php new file mode 100644 index 0000000..aac05d2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Processor/WebProcessor.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\Bridge\Monolog\Processor; + +use Monolog\Processor\WebProcessor as BaseWebProcessor; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\HttpKernelInterface; + +/** + * WebProcessor override to read from the HttpFoundation's Request + * + * @author Jordi Boggiano + */ +class WebProcessor extends BaseWebProcessor +{ + public function __construct() + { + // Pass an empty array as the default null value would access $_SERVER + parent::__construct(array()); + } + + public function onKernelRequest(GetResponseEvent $event) + { + if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) { + $this->serverData = $event->getRequest()->server->all(); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/README.md b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/README.md new file mode 100644 index 0000000..111f673 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/README.md @@ -0,0 +1,18 @@ +Monolog Bridge +============== + +Provides integration for Monolog with various Symfony2 components. + +Resources +--------- + +You can run the unit tests with the following command: + + phpunit -c src/Symfony/Bridge/Monolog/ + +If you also want to run the unit tests that depend on other Symfony +Components, declare the following environment variables before running +PHPUnit: + + export MONOLOG=../path/to/Monolog + export SYMFONY_HTTP_FOUNDATION=../path/to/HttpFoundation diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php new file mode 100644 index 0000000..caf764a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.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\Bridge\Monolog\Tests\Processor; + +use Monolog\Logger; +use Symfony\Bridge\Monolog\Processor\WebProcessor; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\HttpKernelInterface; + +class WebProcessorTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Monolog\\Logger')) { + $this->markTestSkipped('Monolog is not available.'); + } + } + + public function testUsesRequestServerData() + { + $server = array( + 'REQUEST_URI' => 'A', + 'REMOTE_ADDR' => 'B', + 'REQUEST_METHOD' => 'C', + 'SERVER_NAME' => 'D', + 'HTTP_REFERER' => 'E' + ); + + $request = new Request(); + $request->server->replace($server); + + $event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent') + ->disableOriginalConstructor() + ->getMock(); + $event->expects($this->any()) + ->method('getRequestType') + ->will($this->returnValue(HttpKernelInterface::MASTER_REQUEST)); + $event->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)); + + $processor = new WebProcessor(); + $processor->onKernelRequest($event); + $record = $processor($this->getRecord()); + + $this->assertEquals($server['REQUEST_URI'], $record['extra']['url']); + $this->assertEquals($server['REMOTE_ADDR'], $record['extra']['ip']); + $this->assertEquals($server['REQUEST_METHOD'], $record['extra']['http_method']); + $this->assertEquals($server['SERVER_NAME'], $record['extra']['server']); + $this->assertEquals($server['HTTP_REFERER'], $record['extra']['referrer']); + } + + /** + * @return array Record + */ + protected function getRecord($level = Logger::WARNING, $message = 'test') + { + return array( + 'message' => $message, + 'context' => array(), + 'level' => $level, + 'level_name' => Logger::getLevelName($level), + 'channel' => 'test', + 'datetime' => new \DateTime(), + 'extra' => array(), + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Tests/bootstrap.php b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Tests/bootstrap.php new file mode 100644 index 0000000..571a8ef --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/Tests/bootstrap.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +spl_autoload_register(function ($class) { + foreach (array( + 'SYMFONY_HTTP_FOUNDATION' => 'HttpFoundation', + ) as $env => $name) { + if (isset($_SERVER[$env]) && 0 === strpos(ltrim($class, '/'), 'Symfony\Component\\'.$name)) { + if (file_exists($file = $_SERVER[$env].'/'.substr(str_replace('\\', '/', $class), strlen('Symfony\Component\\'.$name)).'.php')) { + require_once $file; + } + } + } + + if (isset($_SERVER['MONOLOG']) && 0 === strpos(ltrim($class, '/'), 'Monolog')) { + if (file_exists($file = $_SERVER['MONOLOG'].'/src/'.str_replace('\\', '/', $class).'.php')) { + require_once $file; + } + } + + if (0 === strpos(ltrim($class, '/'), 'Symfony\Bridge\Monolog')) { + if (file_exists($file = __DIR__.'/../'.substr(str_replace('\\', '/', $class), strlen('Symfony\Bridge\Monolog')).'.php')) { + require_once $file; + } + } +}); diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/composer.json b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/composer.json new file mode 100644 index 0000000..3375b49 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/composer.json @@ -0,0 +1,32 @@ +{ + "name": "symfony/monolog-bridge", + "type": "symfony-bridge", + "description": "Symfony Monolog Bridge", + "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/http-kernel": "self.version", + "monolog/monolog": "1.*" + }, + "autoload": { + "psr-0": { "Symfony\\Bridge\\Monolog": "" } + }, + "target-dir": "Symfony/Bridge/Monolog", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/phpunit.xml.dist b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/phpunit.xml.dist new file mode 100644 index 0000000..f26e3fa --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Monolog/phpunit.xml.dist @@ -0,0 +1,29 @@ + + + + + + ./Tests/ + + + + + + ./ + + ./Resources + ./Tests + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/CHANGELOG.md b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/CHANGELOG.md new file mode 100644 index 0000000..e76b9f6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/CHANGELOG.md @@ -0,0 +1,7 @@ +CHANGELOG +========= + +2.1.0 +----- + + * added the bridge diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/DataCollector/PropelDataCollector.php b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/DataCollector/PropelDataCollector.php new file mode 100644 index 0000000..40f3687 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/DataCollector/PropelDataCollector.php @@ -0,0 +1,145 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Propel1\DataCollector; + +use Symfony\Bridge\Propel1\Logger\PropelLogger; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\DataCollector\DataCollector; + +/** + * The PropelDataCollector collector class collects information. + * + * @author William Durand + */ +class PropelDataCollector extends DataCollector +{ + /** + * Propel logger + * @var \Symfony\Bridge\Propel1\Logger\PropelLogger + */ + private $logger; + + /** + * Propel configuration + * @var \PropelConfiguration + */ + protected $propelConfiguration; + + /** + * Constructor + * + * @param PropelLogger $logger A Propel logger. + * @param \PropelConfiguration $propelConfiguration The Propel configuration object. + */ + public function __construct(PropelLogger $logger, \PropelConfiguration $propelConfiguration) + { + $this->logger = $logger; + $this->propelConfiguration = $propelConfiguration; + } + + /** + * {@inheritdoc} + */ + public function collect(Request $request, Response $response, \Exception $exception = null) + { + $this->data = array( + 'queries' => $this->buildQueries(), + 'querycount' => $this->countQueries(), + ); + } + + /** + * Returns the collector name. + * + * @return string The collector name. + */ + public function getName() + { + return 'propel'; + } + + /** + * Returns queries. + * + * @return array Queries + */ + public function getQueries() + { + return $this->data['queries']; + } + + /** + * Returns the query count. + * + * @return int The query count + */ + public function getQueryCount() + { + return $this->data['querycount']; + } + + /** + * Returns the total time of queries. + * + * @return float The total time of queries + */ + public function getTime() + { + $time = 0; + foreach ($this->data['queries'] as $query) { + $time += (float) $query['time']; + } + + return $time; + } + + /** + * Creates an array of Build objects. + * + * @return array An array of Build objects + */ + private function buildQueries() + { + $queries = array(); + + $outerGlue = $this->propelConfiguration->getParameter('debugpdo.logging.outerglue', ' | '); + $innerGlue = $this->propelConfiguration->getParameter('debugpdo.logging.innerglue', ': '); + + foreach ($this->logger->getQueries() as $q) { + $parts = explode($outerGlue, $q, 4); + + $times = explode($innerGlue, $parts[0]); + $con = explode($innerGlue, $parts[2]); + $memories = explode($innerGlue, $parts[1]); + + $sql = trim($parts[3]); + $con = trim($con[1]); + $time = trim($times[1]); + $memory = trim($memories[1]); + + $queries[] = array('connection' => $con, 'sql' => $sql, 'time' => $time, 'memory' => $memory); + } + + return $queries; + } + + /** + * Count queries. + * + * @return int The number of queries. + */ + private function countQueries() + { + return count($this->logger->getQueries()); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/DependencyInjection/Security/UserProvider/PropelFactory.php b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/DependencyInjection/Security/UserProvider/PropelFactory.php new file mode 100644 index 0000000..2706d34 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/DependencyInjection/Security/UserProvider/PropelFactory.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\Bridge\Propel1\DependencyInjection\Security\UserProvider; + +use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\UserProviderFactoryInterface; +use Symfony\Component\Config\Definition\Builder\NodeDefinition; +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * PropelFactory creates services for Propel user provider. + * + * @author William Durand + */ +class PropelFactory implements UserProviderFactoryInterface +{ + private $key; + private $providerId; + + public function __construct($key, $providerId) + { + $this->key = $key; + $this->providerId = $providerId; + } + + public function create(ContainerBuilder $container, $id, $config) + { + $container + ->setDefinition($id, new DefinitionDecorator($this->providerId)) + ->addArgument($config['class']) + ->addArgument($config['property']) + ; + } + + public function getKey() + { + return $this->key; + } + + public function addConfiguration(NodeDefinition $node) + { + $node + ->children() + ->scalarNode('class')->isRequired()->cannotBeEmpty()->end() + ->scalarNode('property')->defaultNull()->end() + ->end() + ; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php new file mode 100644 index 0000000..bc0867a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php @@ -0,0 +1,354 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Propel1\Form\ChoiceList; + +use \BaseObject; +use \Persistent; +use Symfony\Component\Form\Exception\FormException; +use Symfony\Component\Form\Exception\StringCastException; +use Symfony\Component\Form\Extension\Core\ChoiceList\ObjectChoiceList; + +/** + * Widely inspirated by the EntityChoiceList. + * + * @author William Durand + */ +class ModelChoiceList extends ObjectChoiceList +{ + /** + * The fields of which the identifier of the underlying class consists + * + * This property should only be accessed through identifier. + * + * @var array + */ + private $identifier = array(); + + /** + * Query + */ + private $query = null; + + /** + * Whether the model objects have already been loaded. + * + * @var Boolean + */ + private $loaded = false; + + /** + * @param string $class + * @param string $labelPath + * @param array $choices + * @param \ModelCriteria $queryObject + * @param string $groupPath + */ + public function __construct($class, $labelPath = null, $choices = null, $queryObject = null, $groupPath = null) + { + $this->class = $class; + + $queryClass = $this->class . 'Query'; + $query = new $queryClass(); + + $this->identifier = $query->getTableMap()->getPrimaryKeys(); + $this->query = $queryObject ?: $query; + $this->loaded = is_array($choices) || $choices instanceof \Traversable; + + if (!$this->loaded) { + // Make sure the constraints of the parent constructor are + // fulfilled + $choices = array(); + } + + parent::__construct($choices, $labelPath, array(), $groupPath); + } + + /** + * Returns the class name + * + * @return string + */ + public function getClass() + { + return $this->class; + } + + /** + * Returns the list of model objects + * + * @return array + * + * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + public function getChoices() + { + if (!$this->loaded) { + $this->load(); + } + + return parent::getChoices(); + } + + /** + * Returns the values for the model objects + * + * @return array + * + * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + public function getValues() + { + if (!$this->loaded) { + $this->load(); + } + + return parent::getValues(); + } + + /** + * Returns the choice views of the preferred choices as nested array with + * the choice groups as top-level keys. + * + * @return array + * + * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + public function getPreferredViews() + { + if (!$this->loaded) { + $this->load(); + } + + return parent::getPreferredViews(); + } + + /** + * Returns the choice views of the choices that are not preferred as nested + * array with the choice groups as top-level keys. + * + * @return array + * + * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + public function getRemainingViews() + { + if (!$this->loaded) { + $this->load(); + } + + return parent::getRemainingViews(); + } + + /** + * Returns the model objects corresponding to the given values. + * + * @param array $values + * + * @return array + * + * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + public function getChoicesForValues(array $values) + { + if (!$this->loaded) { + if (1 === count($this->identifier)) { + $filterBy = 'filterBy' . current($this->identifier)->getPhpName(); + + return (array) $this->query->create() + ->$filterBy($values) + ->find(); + } + + $this->load(); + } + + return parent::getChoicesForValues($values); + } + + /** + * Returns the values corresponding to the given model objects. + * + * @param array $models + * + * @return array + * + * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + public function getValuesForChoices(array $models) + { + if (!$this->loaded) { + // Optimize performance for single-field identifiers. We already + // know that the IDs are used as values + + // Attention: This optimization does not check choices for existence + if (1 === count($this->identifier)) { + $values = array(); + foreach ($models as $model) { + if ($model instanceof $this->class) { + // Make sure to convert to the right format + $values[] = $this->fixValue(current($this->getIdentifierValues($model))); + } + } + + return $values; + } + + $this->load(); + } + + return parent::getValuesForChoices($models); + } + + /** + * Returns the indices corresponding to the given models. + * + * @param array $models + * + * @return array + * + * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + public function getIndicesForChoices(array $models) + { + if (!$this->loaded) { + // Optimize performance for single-field identifiers. We already + // know that the IDs are used as indices + + // Attention: This optimization does not check choices for existence + if (1 === count($this->identifier)) { + $indices = array(); + + foreach ($models as $model) { + if ($model instanceof $this->class) { + // Make sure to convert to the right format + $indices[] = $this->fixIndex(current($this->getIdentifierValues($model))); + } + } + + return $indices; + } + + $this->load(); + } + + return parent::getIndicesForChoices($models); + } + + /** + * Returns the models corresponding to the given values. + * + * @param array $values + * + * @return array + * + * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + public function getIndicesForValues(array $values) + { + if (!$this->loaded) { + // Optimize performance for single-field identifiers. We already + // know that the IDs are used as indices and values + + // Attention: This optimization does not check values for existence + if (1 === count($this->identifier)) { + return $this->fixIndices($values); + } + + $this->load(); + } + + return parent::getIndicesForValues($values); + } + + /** + * Creates a new unique index for this model. + * + * If the model has a single-field identifier, this identifier is used. + * + * Otherwise a new integer is generated. + * + * @param mixed $choice The choice to create an index for + * + * @return integer|string A unique index containing only ASCII letters, + * digits and underscores. + */ + protected function createIndex($model) + { + if (1 === count($this->identifier)) { + return current($this->getIdentifierValues($model)); + } + + return parent::createIndex($model); + } + + /** + * Creates a new unique value for this model. + * + * If the model has a single-field identifier, this identifier is used. + * + * Otherwise a new integer is generated. + * + * @param mixed $choice The choice to create a value for + * + * @return integer|string A unique value without character limitations. + */ + protected function createValue($model) + { + if (1 === count($this->identifier)) { + return (string) current($this->getIdentifierValues($model)); + } + + return parent::createValue($model); + } + + /** + * Loads the list with model objects. + */ + private function load() + { + $models = (array) $this->query->find(); + + try { + // The second parameter $labels is ignored by ObjectChoiceList + // The third parameter $preferredChoices is currently not supported + parent::initialize($models, array(), array()); + } catch (StringCastException $e) { + throw new StringCastException(str_replace('argument $labelPath', 'option "property"', $e->getMessage()), null, $e); + } + + $this->loaded = true; + } + + /** + * Returns the values of the identifier fields of an model + * + * Propel must know about this model, that is, the model must already + * be persisted or added to the idmodel map before. Otherwise an + * exception is thrown. + * + * @param object $model The model for which to get the identifier + * @throws FormException If the model does not exist + */ + private function getIdentifierValues($model) + { + if ($model instanceof Persistent) { + return array($model->getPrimaryKey()); + } + + // readonly="true" models do not implement Persistent. + if ($model instanceof BaseObject and method_exists($model, 'getPrimaryKey')) { + return array($model->getPrimaryKey()); + } + + return $model->getPrimaryKeys(); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Form/DataTransformer/CollectionToArrayTransformer.php b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Form/DataTransformer/CollectionToArrayTransformer.php new file mode 100644 index 0000000..9d3b61f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Form/DataTransformer/CollectionToArrayTransformer.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\Bridge\Propel1\Form\DataTransformer; + +use \PropelObjectCollection; +use Symfony\Component\Form\DataTransformerInterface; +use Symfony\Component\Form\Exception\UnexpectedTypeException; + +/** + * CollectionToArrayTransformer class. + * + * @author William Durand + * @author Pierre-Yves Lebecq + */ +class CollectionToArrayTransformer implements DataTransformerInterface +{ + public function transform($collection) + { + if (null === $collection) { + return array(); + } + + if (!$collection instanceof PropelObjectCollection) { + throw new UnexpectedTypeException($collection, '\PropelObjectCollection'); + } + + return $collection->getData(); + } + + public function reverseTransform($array) + { + $collection = new PropelObjectCollection(); + + if ('' === $array || null === $array) { + return $collection; + } + + if (!is_array($array)) { + throw new UnexpectedTypeException($array, 'array'); + } + + $collection->setData($array); + + return $collection; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Form/PropelExtension.php b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Form/PropelExtension.php new file mode 100644 index 0000000..3df2afd --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Form/PropelExtension.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\Bridge\Propel1\Form; + +use Symfony\Component\Form\AbstractExtension; + +/** + * Represents the Propel form extension, which loads the Propel functionality. + * + * @author Joseph Rouff + */ +class PropelExtension extends AbstractExtension +{ + protected function loadTypes() + { + return array( + new Type\ModelType(), + ); + } + + protected function loadTypeGuesser() + { + return new PropelTypeGuesser(); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Form/PropelTypeGuesser.php b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Form/PropelTypeGuesser.php new file mode 100644 index 0000000..4ee475e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Form/PropelTypeGuesser.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\Bridge\Propel1\Form; + +use Symfony\Component\Form\FormTypeGuesserInterface; +use Symfony\Component\Form\Guess\Guess; +use Symfony\Component\Form\Guess\TypeGuess; +use Symfony\Component\Form\Guess\ValueGuess; + +/** + * Propel Type guesser. + * + * @author Fabien Potencier + */ +class PropelTypeGuesser implements FormTypeGuesserInterface +{ + private $cache = array(); + + /** + * {@inheritDoc} + */ + public function guessType($class, $property) + { + if (!$table = $this->getTable($class)) { + return new TypeGuess('text', array(), Guess::LOW_CONFIDENCE); + } + + foreach ($table->getRelations() as $relation) { + if (in_array($relation->getType(), array(\RelationMap::MANY_TO_ONE, \RelationMap::ONE_TO_MANY))) { + if ($property == $relation->getForeignTable()->getName()) { + return new TypeGuess('model', array( + 'class' => $relation->getForeignTable()->getClassName(), + 'multiple' => \RelationMap::MANY_TO_ONE === $relation->getType() ? false : true, + ), Guess::HIGH_CONFIDENCE); + } + } elseif ($relation->getType() === \RelationMap::MANY_TO_MANY) { + if (strtolower($property) == strtolower($relation->getPluralName())) { + return new TypeGuess('model', array( + 'class' => $relation->getLocalTable()->getClassName(), + 'multiple' => true, + ), Guess::HIGH_CONFIDENCE); + } + } + } + + if (!$column = $this->getColumn($class, $property)) { + return new TypeGuess('text', array(), Guess::LOW_CONFIDENCE); + } + + switch ($column->getType()) { + case \PropelColumnTypes::BOOLEAN: + case \PropelColumnTypes::BOOLEAN_EMU: + return new TypeGuess('checkbox', array(), Guess::HIGH_CONFIDENCE); + case \PropelColumnTypes::TIMESTAMP: + case \PropelColumnTypes::BU_TIMESTAMP: + return new TypeGuess('datetime', array(), Guess::HIGH_CONFIDENCE); + case \PropelColumnTypes::DATE: + case \PropelColumnTypes::BU_DATE: + return new TypeGuess('date', array(), Guess::HIGH_CONFIDENCE); + case \PropelColumnTypes::TIME: + return new TypeGuess('time', array(), Guess::HIGH_CONFIDENCE); + case \PropelColumnTypes::FLOAT: + case \PropelColumnTypes::REAL: + case \PropelColumnTypes::DOUBLE: + case \PropelColumnTypes::DECIMAL: + return new TypeGuess('number', array(), Guess::MEDIUM_CONFIDENCE); + case \PropelColumnTypes::TINYINT: + case \PropelColumnTypes::SMALLINT: + case \PropelColumnTypes::INTEGER: + case \PropelColumnTypes::BIGINT: + case \PropelColumnTypes::NUMERIC: + return new TypeGuess('integer', array(), Guess::MEDIUM_CONFIDENCE); + case \PropelColumnTypes::CHAR: + case \PropelColumnTypes::VARCHAR: + return new TypeGuess('text', array(), Guess::MEDIUM_CONFIDENCE); + case \PropelColumnTypes::LONGVARCHAR: + case \PropelColumnTypes::BLOB: + case \PropelColumnTypes::CLOB: + case \PropelColumnTypes::CLOB_EMU: + return new TypeGuess('textarea', array(), Guess::MEDIUM_CONFIDENCE); + default: + return new TypeGuess('text', array(), Guess::LOW_CONFIDENCE); + } + } + + /** + * {@inheritDoc} + */ + public function guessRequired($class, $property) + { + if ($column = $this->getColumn($class, $property)) { + return new ValueGuess($column->isNotNull(), Guess::HIGH_CONFIDENCE); + } + } + + /** + * {@inheritDoc} + */ + public function guessMaxLength($class, $property) + { + if ($column = $this->getColumn($class, $property)) { + if ($column->isText()) { + return new ValueGuess($column->getSize(), Guess::HIGH_CONFIDENCE); + } + switch ($column->getType()) { + case \PropelColumnTypes::FLOAT: + case \PropelColumnTypes::REAL: + case \PropelColumnTypes::DOUBLE: + case \PropelColumnTypes::DECIMAL: + return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE); + } + } + } + + /** + * {@inheritDoc} + */ + public function guessMinLength($class, $property) + { + } + + /** + * {@inheritDoc} + */ + public function guessPattern($class, $property) + { + if ($column = $this->getColumn($class, $property)) { + switch ($column->getType()) { + case \PropelColumnTypes::FLOAT: + case \PropelColumnTypes::REAL: + case \PropelColumnTypes::DOUBLE: + case \PropelColumnTypes::DECIMAL: + return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE); + } + } + } + + protected function getTable($class) + { + if (isset($this->cache[$class])) { + return $this->cache[$class]; + } + + if (class_exists($queryClass = $class.'Query')) { + $query = new $queryClass(); + + return $this->cache[$class] = $query->getTableMap(); + } + } + + protected function getColumn($class, $property) + { + if (isset($this->cache[$class.'::'.$property])) { + return $this->cache[$class.'::'.$property]; + } + + $table = $this->getTable($class); + + if ($table && $table->hasColumn($property)) { + return $this->cache[$class.'::'.$property] = $table->getColumn($property); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Form/Type/ModelType.php b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Form/Type/ModelType.php new file mode 100644 index 0000000..f509dca --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Form/Type/ModelType.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\Bridge\Propel1\Form\Type; + +use Symfony\Bridge\Propel1\Form\ChoiceList\ModelChoiceList; +use Symfony\Bridge\Propel1\Form\DataTransformer\CollectionToArrayTransformer; +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\OptionsResolver\Options; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; + +/** + * ModelType class. + * + * @author William Durand + */ +class ModelType extends AbstractType +{ + public function buildForm(FormBuilderInterface $builder, array $options) + { + if ($options['multiple']) { + $builder->addViewTransformer(new CollectionToArrayTransformer(), true); + } + } + + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $choiceList = function (Options $options) { + return new ModelChoiceList( + $options['class'], + $options['property'], + $options['choices'], + $options['query'], + $options['group_by'] + ); + }; + + $resolver->setDefaults(array( + 'template' => 'choice', + 'multiple' => false, + 'expanded' => false, + 'class' => null, + 'property' => null, + 'query' => null, + 'choices' => null, + 'choice_list' => $choiceList, + 'group_by' => null, + 'by_reference' => false, + )); + } + + public function getParent() + { + return 'choice'; + } + + public function getName() + { + return 'propel_model'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/LICENSE b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/LICENSE new file mode 100644 index 0000000..cdffe7a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 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/symfony/src/Symfony/Bridge/Propel1/Logger/PropelLogger.php b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Logger/PropelLogger.php new file mode 100644 index 0000000..43211a0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Logger/PropelLogger.php @@ -0,0 +1,170 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Propel1\Logger; + +use Symfony\Component\HttpKernel\Debug\Stopwatch; +use Symfony\Component\HttpKernel\Log\LoggerInterface; + +/** + * PropelLogger. + * + * @author Fabien Potencier + * @author William Durand + */ +class PropelLogger +{ + /** + * @var LoggerInterface + */ + protected $logger; + + /** + * @var array + */ + protected $queries; + + /** + * @var \Symfony\Component\HttpKernel\Debug\Stopwatch + */ + protected $stopwatch; + + private $isPrepared; + + /** + * Constructor. + * + * @param LoggerInterface $logger A LoggerInterface instance + * @param Stopwatch $stopwatch A Stopwatch instance + */ + public function __construct(LoggerInterface $logger = null, Stopwatch $stopwatch = null) + { + $this->logger = $logger; + $this->queries = array(); + $this->stopwatch = $stopwatch; + $this->isPrepared = false; + } + + /** + * A convenience function for logging an alert event. + * + * @param mixed $message the message to log. + */ + public function alert($message) + { + if (null !== $this->logger) { + $this->logger->alert($message); + } + } + + /** + * A convenience function for logging a critical event. + * + * @param mixed $message the message to log. + */ + public function crit($message) + { + if (null !== $this->logger) { + $this->logger->crit($message); + } + } + + /** + * A convenience function for logging an error event. + * + * @param mixed $message the message to log. + */ + public function err($message) + { + if (null !== $this->logger) { + $this->logger->err($message); + } + } + + /** + * A convenience function for logging a warning event. + * + * @param mixed $message the message to log. + */ + public function warning($message) + { + if (null !== $this->logger) { + $this->logger->warn($message); + } + } + + /** + * A convenience function for logging an critical event. + * + * @param mixed $message the message to log. + */ + public function notice($message) + { + if (null !== $this->logger) { + $this->logger->notice($message); + } + } + + /** + * A convenience function for logging an critical event. + * + * @param mixed $message the message to log. + */ + public function info($message) + { + if (null !== $this->logger) { + $this->logger->info($message); + } + } + + /** + * A convenience function for logging a debug event. + * + * @param mixed $message the message to log. + */ + public function debug($message) + { + $add = true; + + if (null !== $this->stopwatch) { + $trace = debug_backtrace(); + $method = $trace[2]['args'][2]; + + $watch = 'Propel Query '.(count($this->queries)+1); + if ('PropelPDO::prepare' === $method) { + $this->isPrepared = true; + $this->stopwatch->start($watch, 'propel'); + + $add = false; + } elseif ($this->isPrepared) { + $this->isPrepared = false; + $this->stopwatch->stop($watch); + } + } + + if ($add) { + $this->queries[] = $message; + if (null !== $this->logger) { + $this->logger->debug($message); + } + } + } + + /** + * Returns queries. + * + * @return array Queries + */ + public function getQueries() + { + return $this->queries; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/README.md b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/README.md new file mode 100644 index 0000000..f3ca773 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/README.md @@ -0,0 +1,20 @@ +Propel Bridge +============= + +Provides integration for Propel with various Symfony2 components. + +Resources +--------- + +You can run the unit tests with the following command: + + phpunit -c src/Symfony/Bridge/Propel/ + +If you also want to run the unit tests that depend on other Symfony +Components, declare the following environment variables before running +PHPUnit: + + export PROPEL1=../path/to/Propel + export SYMFONY_HTTP_FOUNDATION=../path/to/HttpFoundation + export SYMFONY_HTTP_KERNEL=../path/to/HttpKernel + export SYMFONY_FORM=../path/to/Form diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Security/User/PropelUserProvider.php b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Security/User/PropelUserProvider.php new file mode 100644 index 0000000..4392bb4 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Security/User/PropelUserProvider.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\Bridge\Propel1\Security\User; + +use Symfony\Component\Security\Core\User\UserInterface; +use Symfony\Component\Security\Core\User\UserProviderInterface; +use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; +use Symfony\Component\Security\Core\Exception\UnsupportedUserException; + +/** + * Provides easy to use provisioning for Propel model users. + * + * @author William DURAND + */ +class PropelUserProvider implements UserProviderInterface +{ + /** + * A Model class name. + * @var string + */ + protected $class; + + /** + * A Query class name. + * @var string + */ + protected $queryClass; + + /** + * A property to use to retrieve the user. + * @var string + */ + protected $property; + + /** + * Default constructor + * + * @param $class The User model class. + * @param $property The property to use to retrieve a user. + */ + public function __construct($class, $property = null) + { + $this->class = $class; + $this->queryClass = $class . 'Query'; + $this->property = $property; + } + + /** + * {@inheritdoc} + */ + public function loadUserByUsername($username) + { + $queryClass = $this->queryClass; + $query = $queryClass::create(); + + if (null !== $this->property) { + $filter = 'filterBy' . ucfirst($this->property); + $query->$filter($username); + } else { + $query->filterByUsername($username); + } + + if (null === $user = $query->findOne()) { + throw new UsernameNotFoundException(sprintf('User "%s" not found.', $username)); + } + + return $user; + } + + /** + * {@inheritdoc} + */ + public function refreshUser(UserInterface $user) + { + if (!$user instanceof $this->class) { + throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user))); + } + + $queryClass = $this->queryClass; + + return $queryClass::create()->findPk($user->getPrimaryKey()); + } + + /** + * {@inheritdoc} + */ + public function supportsClass($class) + { + return $class === $this->class; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/DataCollector/PropelDataCollectorTest.php b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/DataCollector/PropelDataCollectorTest.php new file mode 100644 index 0000000..23d6fc9 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/DataCollector/PropelDataCollectorTest.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\Bridge\Propel1\Tests\DataCollector; + +use Symfony\Bridge\Propel1\DataCollector\PropelDataCollector; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Bridge\Propel1\Tests\Propel1TestCase; + +class PropelDataCollectorTest extends Propel1TestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\HttpFoundation\Request')) { + $this->markTestSkipped('The "HttpFoundation" component is not available'); + } + } + + public function testCollectWithoutData() + { + $c = $this->createCollector(array()); + $c->collect(new Request(), new Response()); + + $this->assertEquals(array(), $c->getQueries()); + $this->assertEquals(0, $c->getQueryCount()); + } + + public function testCollectWithData() + { + $queries = array( + "time: 0.000 sec | mem: 1.4 MB | connection: default | SET NAMES 'utf8'", + ); + + $c = $this->createCollector($queries); + $c->collect(new Request(), new Response()); + + $this->assertEquals(array( + array( + 'sql' => "SET NAMES 'utf8'", + 'time' => '0.000 sec', + 'connection'=> 'default', + 'memory' => '1.4 MB' + ) + ), $c->getQueries()); + $this->assertEquals(1, $c->getQueryCount()); + } + + public function testCollectWithMultipleData() + { + $queries = array( + "time: 0.000 sec | mem: 1.4 MB | connection: default | SET NAMES 'utf8'", + "time: 0.012 sec | mem: 2.4 MB | connection: default | SELECT tags.NAME, image.FILENAME FROM tags LEFT JOIN image ON tags.IMAGEID = image.ID WHERE image.ID = 12", + "time: 0.012 sec | mem: 2.4 MB | connection: default | INSERT INTO `table` (`some_array`) VALUES ('| 1 | 2 | 3 |')", + ); + + $c = $this->createCollector($queries); + $c->collect(new Request(), new Response()); + + $this->assertEquals(array( + array( + 'sql' => "SET NAMES 'utf8'", + 'time' => '0.000 sec', + 'connection'=> 'default', + 'memory' => '1.4 MB' + ), + array( + 'sql' => "SELECT tags.NAME, image.FILENAME FROM tags LEFT JOIN image ON tags.IMAGEID = image.ID WHERE image.ID = 12", + 'time' => '0.012 sec', + 'connection'=> 'default', + 'memory' => '2.4 MB' + ), + array( + 'sql' => "INSERT INTO `table` (`some_array`) VALUES ('| 1 | 2 | 3 |')", + 'time' => '0.012 sec', + 'connection'=> 'default', + 'memory' => '2.4 MB' + ), + ), $c->getQueries()); + $this->assertEquals(3, $c->getQueryCount()); + $this->assertEquals(0.024, $c->getTime()); + } + + private function createCollector($queries) + { + $config = $this->getMock('\PropelConfiguration'); + $config + ->expects($this->any()) + ->method('getParameter') + ->will($this->returnArgument(1)) + ; + + $logger = $this->getMock('\Symfony\Bridge\Propel1\Logger\PropelLogger'); + $logger + ->expects($this->any()) + ->method('getQueries') + ->will($this->returnValue($queries)) + ; + + return new PropelDataCollector($logger, $config); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Fixtures/Column.php b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Fixtures/Column.php new file mode 100644 index 0000000..6b03977 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Fixtures/Column.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\Bridge\Propel1\Tests\Fixtures; + +class Column +{ + private $name; + + private $type; + + public function __construct($name, $type) + { + $this->name = $name; + $this->type = $type; + } + + public function getType() + { + return $this->type; + } + + public function isText() + { + if (!$this->type) { + return false; + } + + switch ($this->type) { + case \PropelColumnTypes::CHAR: + case \PropelColumnTypes::VARCHAR: + case \PropelColumnTypes::LONGVARCHAR: + case \PropelColumnTypes::BLOB: + case \PropelColumnTypes::CLOB: + case \PropelColumnTypes::CLOB_EMU: + return true; + } + + return false; + } + + public function getSize() + { + return $this->isText() ? 255 : 0; + } + + public function isNotNull() + { + return ('id' === $this->name); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Fixtures/Item.php b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Fixtures/Item.php new file mode 100644 index 0000000..70705b6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Fixtures/Item.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\Bridge\Propel1\Tests\Fixtures; + +use \PropelPDO; + +class Item implements \Persistent +{ + private $id; + + private $value; + + private $groupName; + + private $price; + + public function __construct($id = null, $value = null, $groupName = null, $price = null) + { + $this->id = $id; + $this->value = $value; + $this->groupName = $groupName; + $this->price = $price; + } + + public function getId() + { + return $this->id; + } + + public function setId($id) + { + $this->id = $id; + } + + public function getValue() + { + return $this->value; + } + + public function getGroupName() + { + return $this->groupName; + } + + public function getPrice() + { + return $this->price; + } + + public function getPrimaryKey() + { + return $this->getId(); + } + + public function setPrimaryKey($primaryKey) + { + $this->setId($primaryKey); + } + + public function isModified() + { + return false; + } + + public function isColumnModified($col) + { + return false; + } + + public function isNew() + { + return false; + } + + public function setNew($b) + { + } + + public function resetModified() + { + } + + public function isDeleted() + { + return false; + } + + public function setDeleted($b) + { + } + + public function delete(PropelPDO $con = null) + { + } + + public function save(PropelPDO $con = null) + { + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Fixtures/ItemQuery.php b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Fixtures/ItemQuery.php new file mode 100644 index 0000000..75d2a4f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Fixtures/ItemQuery.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\Bridge\Propel1\Tests\Fixtures; + +class ItemQuery +{ + private $map = array( + 'id' => \PropelColumnTypes::INTEGER, + 'value' => \PropelColumnTypes::VARCHAR, + 'price' => \PropelColumnTypes::FLOAT, + 'is_active' => \PropelColumnTypes::BOOLEAN, + 'enabled' => \PropelColumnTypes::BOOLEAN_EMU, + 'updated_at' => \PropelColumnTypes::TIMESTAMP, + ); + + public function getTableMap() + { + // Allows to define methods in this class + // to avoid a lot of mock classes + return $this; + } + + public function getPrimaryKeys() + { + return array('id'); + } + + /** + * Method from the TableMap API + */ + public function hasColumn($column) + { + return in_array($column, array_keys($this->map)); + } + + /** + * Method from the TableMap API + */ + public function getColumn($column) + { + if ($this->hasColumn($column)) { + return new Column($column, $this->map[$column]); + } + + return null; + } + + /** + * Method from the TableMap API + */ + public function getRelations() + { + return array(); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Fixtures/ReadOnlyItem.php b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Fixtures/ReadOnlyItem.php new file mode 100644 index 0000000..fbedf25 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Fixtures/ReadOnlyItem.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\Bridge\Propel1\Tests\Fixtures; + +class ReadOnlyItem extends \BaseObject +{ + public function getName() + { + return 'Marvin'; + } + + public function getPrimaryKey() + { + return 42; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Fixtures/ReadOnlyItemQuery.php b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Fixtures/ReadOnlyItemQuery.php new file mode 100644 index 0000000..8c9677f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Fixtures/ReadOnlyItemQuery.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\Bridge\Propel1\Tests\Fixtures; + +class ReadOnlyItemQuery +{ + public function getTableMap() + { + // Allows to define methods in this class + // to avoid a lot of mock classes + return $this; + } + + public function getPrimaryKeys() + { + return array('id'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Form/ChoiceList/ModelChoiceListTest.php b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Form/ChoiceList/ModelChoiceListTest.php new file mode 100644 index 0000000..4ff29fb --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Form/ChoiceList/ModelChoiceListTest.php @@ -0,0 +1,161 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Propel1\Tests\Form\ChoiceList; + +use Symfony\Bridge\Propel1\Form\ChoiceList\ModelChoiceList; +use Symfony\Component\Form\Extension\Core\View\ChoiceView; +use Symfony\Bridge\Propel1\Tests\Fixtures\Item; +use Symfony\Bridge\Propel1\Tests\Fixtures\ReadOnlyItem; +use Symfony\Bridge\Propel1\Tests\Propel1TestCase; + +class ModelChoiceListTest extends Propel1TestCase +{ + const ITEM_CLASS = '\Symfony\Bridge\Propel1\Tests\Fixtures\Item'; + + protected function setUp() + { + if (!class_exists('Symfony\Component\Form\Form')) { + $this->markTestSkipped('The "Form" component is not available'); + } + } + + public function testEmptyChoicesReturnsEmpty() + { + $choiceList = new ModelChoiceList( + self::ITEM_CLASS, + 'value', + array() + ); + + $this->assertSame(array(), $choiceList->getChoices()); + } + + public function testReadOnlyIsValidChoice() + { + $item = new ReadOnlyItem(); + $choiceList = new ModelChoiceList( + '\Symfony\Bridge\Propel1\Tests\Fixtures\ReadOnlyItem', + 'name', + array( + $item, + ) + ); + + $this->assertSame(array(42 => $item), $choiceList->getChoices()); + } + + public function testFlattenedChoices() + { + $item1 = new Item(1, 'Foo'); + $item2 = new Item(2, 'Bar'); + + $choiceList = new ModelChoiceList( + self::ITEM_CLASS, + 'value', + array( + $item1, + $item2, + ) + ); + + $this->assertSame(array(1 => $item1, 2 => $item2), $choiceList->getChoices()); + } + + public function testNestedChoices() + { + $item1 = new Item(1, 'Foo'); + $item2 = new Item(2, 'Bar'); + + $choiceList = new ModelChoiceList( + self::ITEM_CLASS, + 'value', + array( + 'group1' => array($item1), + 'group2' => array($item2), + ) + ); + + $this->assertSame(array(1 => $item1, 2 => $item2), $choiceList->getChoices()); + $this->assertEquals(array( + 'group1' => array(1 => new ChoiceView('1', 'Foo')), + 'group2' => array(2 => new ChoiceView('2', 'Bar')) + ), $choiceList->getRemainingViews()); + } + + public function testGroupBySupportsString() + { + $item1 = new Item(1, 'Foo', 'Group1'); + $item2 = new Item(2, 'Bar', 'Group1'); + $item3 = new Item(3, 'Baz', 'Group2'); + $item4 = new Item(4, 'Boo!', null); + + $choiceList = new ModelChoiceList( + self::ITEM_CLASS, + 'value', + array( + $item1, + $item2, + $item3, + $item4, + ), + null, + 'groupName' + ); + + $this->assertEquals(array(1 => $item1, 2 => $item2, 3 => $item3, 4 => $item4), $choiceList->getChoices()); + $this->assertEquals(array( + 'Group1' => array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')), + 'Group2' => array(3 => new ChoiceView('3', 'Baz')), + 4 => new ChoiceView('4', 'Boo!') + ), $choiceList->getRemainingViews()); + } + + public function testGroupByInvalidPropertyPathReturnsFlatChoices() + { + $item1 = new Item(1, 'Foo', 'Group1'); + $item2 = new Item(2, 'Bar', 'Group1'); + + $choiceList = new ModelChoiceList( + self::ITEM_CLASS, + 'value', + array( + $item1, + $item2, + ), + null, + 'child.that.does.not.exist' + ); + + $this->assertEquals(array( + 1 => $item1, + 2 => $item2 + ), $choiceList->getChoices()); + } + + public function testGetValuesForChoices() + { + $item1 = new Item(1, 'Foo'); + $item2 = new Item(2, 'Bar'); + + $choiceList = new ModelChoiceList( + self::ITEM_CLASS, + 'value', + null, + null, + null, + null + ); + + $this->assertEquals(array(1, 2), $choiceList->getValuesForChoices(array($item1, $item2))); + $this->assertEquals(array(1, 2), $choiceList->getIndicesForChoices(array($item1, $item2))); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Form/DataTransformer/CollectionToArrayTransformerTest.php b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Form/DataTransformer/CollectionToArrayTransformerTest.php new file mode 100644 index 0000000..625b748 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Form/DataTransformer/CollectionToArrayTransformerTest.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\Bridge\Propel1\Tests\Form\DataTransformer; + +use \PropelObjectCollection; +use Symfony\Bridge\Propel1\Form\DataTransformer\CollectionToArrayTransformer; +use Symfony\Bridge\Propel1\Tests\Propel1TestCase; + +class CollectionToArrayTransformerTest extends Propel1TestCase +{ + private $transformer; + + protected function setUp() + { + if (!class_exists('Symfony\Component\Form\Form')) { + $this->markTestSkipped('The "Form" component is not available'); + } + + parent::setUp(); + + $this->transformer = new CollectionToArrayTransformer(); + } + + public function testTransform() + { + $result = $this->transformer->transform(new PropelObjectCollection()); + + $this->assertTrue(is_array($result)); + $this->assertEquals(0, count($result)); + } + + public function testTransformWithNull() + { + $result = $this->transformer->transform(null); + + $this->assertTrue(is_array($result)); + $this->assertEquals(0, count($result)); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException + */ + public function testTransformThrowsExceptionIfNotPropelObjectCollection() + { + $this->transformer->transform(new DummyObject()); + } + + public function testTransformWithData() + { + $coll = new PropelObjectCollection(); + $coll->setData(array('foo', 'bar')); + + $result = $this->transformer->transform($coll); + + $this->assertTrue(is_array($result)); + $this->assertEquals(2, count($result)); + $this->assertEquals('foo', $result[0]); + $this->assertEquals('bar', $result[1]); + } + + public function testReverseTransformWithNull() + { + $result = $this->transformer->reverseTransform(null); + + $this->assertInstanceOf('\PropelObjectCollection', $result); + $this->assertEquals(0, count($result->getData())); + } + + public function testReverseTransformWithEmptyString() + { + $result = $this->transformer->reverseTransform(''); + + $this->assertInstanceOf('\PropelObjectCollection', $result); + $this->assertEquals(0, count($result->getData())); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException + */ + public function testReverseTransformThrowsExceptionIfNotArray() + { + $this->transformer->reverseTransform(new DummyObject()); + } + + public function testReverseTransformWithData() + { + $inputData = array('foo', 'bar'); + + $result = $this->transformer->reverseTransform($inputData); + $data = $result->getData(); + + $this->assertInstanceOf('\PropelObjectCollection', $result); + + $this->assertTrue(is_array($data)); + $this->assertEquals(2, count($data)); + $this->assertEquals('foo', $data[0]); + $this->assertEquals('bar', $data[1]); + $this->assertsame($inputData, $data); + } +} + +class DummyObject {} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Form/PropelTypeGuesserTest.php b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Form/PropelTypeGuesserTest.php new file mode 100644 index 0000000..f60fc8f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Form/PropelTypeGuesserTest.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\Bridge\Propel1\Tests\Form; + +use Symfony\Bridge\Propel1\Form\PropelTypeGuesser; +use Symfony\Bridge\Propel1\Tests\Propel1TestCase; +use Symfony\Component\Form\Guess\Guess; + +class PropelTypeGuesserTest extends Propel1TestCase +{ + const CLASS_NAME = 'Symfony\Bridge\Propel1\Tests\Fixtures\Item'; + + const UNKNOWN_CLASS_NAME = 'Symfony\Bridge\Propel1\Tests\Fixtures\UnknownItem'; + + private $guesser; + + public function setUp() + { + $this->guesser = new PropelTypeGuesser(); + } + + public function testGuessMaxLengthWithText() + { + $value = $this->guesser->guessMaxLength(self::CLASS_NAME, 'value'); + + $this->assertNotNull($value); + $this->assertEquals(255, $value->getValue()); + } + + public function testGuessMaxLengthWithFloat() + { + $value = $this->guesser->guessMaxLength(self::CLASS_NAME, 'price'); + + $this->assertNotNull($value); + $this->assertNull($value->getValue()); + } + + public function testGuessMinLengthWithText() + { + $value = $this->guesser->guessPattern(self::CLASS_NAME, 'value'); + + $this->assertNull($value); + } + + public function testGuessMinLengthWithFloat() + { + $value = $this->guesser->guessPattern(self::CLASS_NAME, 'price'); + + $this->assertNotNull($value); + $this->assertNull($value->getValue()); + } + + public function testGuessRequired() + { + $value = $this->guesser->guessRequired(self::CLASS_NAME, 'id'); + + $this->assertNotNull($value); + $this->assertTrue($value->getValue()); + } + + public function testGuessRequiredWithNullableColumn() + { + $value = $this->guesser->guessRequired(self::CLASS_NAME, 'value'); + + $this->assertNotNull($value); + $this->assertFalse($value->getValue()); + } + + public function testGuessTypeWithoutTable() + { + $value = $this->guesser->guessType(self::UNKNOWN_CLASS_NAME, 'property'); + + $this->assertNotNull($value); + $this->assertEquals('text', $value->getType()); + $this->assertEquals(Guess::LOW_CONFIDENCE, $value->getConfidence()); + } + + public function testGuessTypeWithoutColumn() + { + $value = $this->guesser->guessType(self::CLASS_NAME, 'property'); + + $this->assertNotNull($value); + $this->assertEquals('text', $value->getType()); + $this->assertEquals(Guess::LOW_CONFIDENCE, $value->getConfidence()); + } + + /** + * @dataProvider dataProviderForGuessType + */ + public function testGuessType($property, $type, $confidence) + { + $value = $this->guesser->guessType(self::CLASS_NAME, $property); + + $this->assertNotNull($value); + $this->assertEquals($type, $value->getType()); + $this->assertEquals($confidence, $value->getConfidence()); + } + + static public function dataProviderForGuessType() + { + return array( + array('is_active', 'checkbox', Guess::HIGH_CONFIDENCE), + array('enabled', 'checkbox', Guess::HIGH_CONFIDENCE), + array('id', 'integer', Guess::MEDIUM_CONFIDENCE), + array('value', 'text', Guess::MEDIUM_CONFIDENCE), + array('price', 'number', Guess::MEDIUM_CONFIDENCE), + array('updated_at', 'datetime', Guess::HIGH_CONFIDENCE), + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Propel1TestCase.php b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Propel1TestCase.php new file mode 100644 index 0000000..93cc808 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/Propel1TestCase.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\Bridge\Propel1\Tests; + +abstract class Propel1TestCase extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('\Propel')) { + $this->markTestSkipped('Propel is not available.'); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/bootstrap.php b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/bootstrap.php new file mode 100644 index 0000000..abb49e0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/Tests/bootstrap.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +spl_autoload_register(function ($class) { + foreach (array( + 'SYMFONY_HTTP_FOUNDATION' => 'HttpFoundation', + 'SYMFONY_HTTP_KERNEL' => 'HttpKernel', + 'SYMFONY_FORM' => 'Form', + ) as $env => $name) { + if (isset($_SERVER[$env]) && 0 === strpos(ltrim($class, '/'), 'Symfony\Component\\'.$name)) { + if (file_exists($file = $_SERVER[$env].'/'.substr(str_replace('\\', '/', $class), strlen('Symfony\Component\\'.$name)).'.php')) { + require_once $file; + } + } + } + + if (0 === strpos(ltrim($class, '/'), 'Symfony\Bridge\Propel1')) { + if (file_exists($file = __DIR__.'/../'.substr(str_replace('\\', '/', $class), strlen('Symfony\Bridge\Propel1')).'.php')) { + require_once $file; + } + } +}); + +if (isset($_SERVER['PROPEL1']) && is_file($file = $_SERVER['PROPEL1'].'/runtime/lib/Propel.php')) { + require_once $file; +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/composer.json b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/composer.json new file mode 100644 index 0000000..f716f02 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/composer.json @@ -0,0 +1,34 @@ +{ + "name": "symfony/propel1-bridge", + "type": "symfony-bridge", + "description": "Symfony Propel1 Bridge", + "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/http-foundation": "self.version", + "symfony/http-kernel": "self.version", + "symfony/form": "self.version", + "propel/propel1": "1.6.*" + }, + "autoload": { + "psr-0": { "Symfony\\Bridge\\Propel1": "" } + }, + "target-dir": "Symfony/Bridge/Propel1", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/phpunit.xml.dist b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/phpunit.xml.dist new file mode 100644 index 0000000..ae1d6cd --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Propel1/phpunit.xml.dist @@ -0,0 +1,29 @@ + + + + + + ./Tests/ + + + + + + ./ + + ./Resources + ./Tests + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Swiftmailer/CHANGELOG.md b/vendor/symfony/symfony/src/Symfony/Bridge/Swiftmailer/CHANGELOG.md new file mode 100644 index 0000000..67100f8 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Swiftmailer/CHANGELOG.md @@ -0,0 +1,7 @@ +CHANGELOG +========= + +2.1.0 +----- + + * added a data collector diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Swiftmailer/DataCollector/MessageDataCollector.php b/vendor/symfony/symfony/src/Symfony/Bridge/Swiftmailer/DataCollector/MessageDataCollector.php new file mode 100644 index 0000000..3ae96a2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Swiftmailer/DataCollector/MessageDataCollector.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Swiftmailer\DataCollector; + +use Symfony\Component\HttpKernel\DataCollector\DataCollector; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * MessageDataCollector. + * + * @author Fabien Potencier + * @author Clément JOBEILI + */ +class MessageDataCollector extends DataCollector +{ + private $container; + private $isSpool; + + /** + * Constructor. + * + * We don't inject the message logger and mailer here + * to avoid the creation of these objects when no emails are sent. + * + * @param ContainerInterface $container A ContainerInterface instance + * @param Boolean $isSpool + */ + public function __construct(ContainerInterface $container, $isSpool) + { + $this->container = $container; + $this->isSpool = $isSpool; + } + + /** + * {@inheritdoc} + */ + public function collect(Request $request, Response $response, \Exception $exception = null) + { + // only collect when Swiftmailer has already been initialized + if (class_exists('Swift_Mailer', false)) { + $logger = $this->container->get('swiftmailer.plugin.messagelogger'); + $this->data['messages'] = $logger->getMessages(); + $this->data['messageCount'] = $logger->countMessages(); + } else { + $this->data['messages'] = array(); + $this->data['messageCount'] = 0; + } + + $this->data['isSpool'] = $this->isSpool; + } + + public function getMessageCount() + { + return $this->data['messageCount']; + } + + public function getMessages() + { + return $this->data['messages']; + } + + public function isSpool() + { + return $this->data['isSpool']; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'swiftmailer'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Swiftmailer/LICENSE b/vendor/symfony/symfony/src/Symfony/Bridge/Swiftmailer/LICENSE new file mode 100644 index 0000000..cdffe7a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Swiftmailer/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 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/symfony/src/Symfony/Bridge/Swiftmailer/composer.json b/vendor/symfony/symfony/src/Symfony/Bridge/Swiftmailer/composer.json new file mode 100644 index 0000000..baae3c7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Swiftmailer/composer.json @@ -0,0 +1,34 @@ +{ + "name": "symfony/swiftmailer-bridge", + "type": "symfony-bridge", + "description": "Symfony Swiftmailer Bridge", + "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", + "swiftmailer/swiftmailer": ">=4.1.2,<4.2-dev" + }, + "suggest": { + "symfony/http-kernel": "self.version" + }, + "autoload": { + "psr-0": { "Symfony\\Bridge\\Swiftmailer": "" } + }, + "target-dir": "Symfony/Bridge/Swiftmailer", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/CHANGELOG.md b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/CHANGELOG.md new file mode 100644 index 0000000..31d0045 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/CHANGELOG.md @@ -0,0 +1,11 @@ +CHANGELOG +========= + +2.1.0 +----- + + * added TwigEngine + * added TwigExtractor + * added a csrf_token function + * added a way to specify a default domain for a Twig template (via the + 'trans_default_domain' tag) diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/FormExtension.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/FormExtension.php new file mode 100644 index 0000000..cb6a866 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/FormExtension.php @@ -0,0 +1,366 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Twig\Extension; + +use Symfony\Bridge\Twig\TokenParser\FormThemeTokenParser; +use Symfony\Component\Form\FormView; +use Symfony\Component\Form\Exception\FormException; +use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface; +use Symfony\Component\Form\Extension\Core\View\ChoiceView; +use Symfony\Component\Form\Util\FormUtil; + +/** + * FormExtension extends Twig with form capabilities. + * + * @author Fabien Potencier + * @author Bernhard Schussek + */ +class FormExtension extends \Twig_Extension +{ + protected $csrfProvider; + protected $resources; + protected $blocks; + protected $environment; + protected $themes; + protected $varStack; + protected $template; + + public function __construct(CsrfProviderInterface $csrfProvider = null, array $resources = array()) + { + $this->csrfProvider = $csrfProvider; + $this->themes = new \SplObjectStorage(); + $this->varStack = array(); + $this->blocks = new \SplObjectStorage(); + $this->resources = $resources; + } + + /** + * {@inheritdoc} + */ + public function initRuntime(\Twig_Environment $environment) + { + $this->environment = $environment; + } + + /** + * Sets a theme for a given view. + * + * @param FormView $view A FormView instance + * @param array|string $resources An array of resource names|a resource name + */ + public function setTheme(FormView $view, $resources) + { + $this->themes->attach($view, (array) $resources); + $this->blocks = new \SplObjectStorage(); + } + + /** + * Returns the token parser instance to add to the existing list. + * + * @return array An array of Twig_TokenParser instances + */ + public function getTokenParsers() + { + return array( + // {% form_theme form "SomeBundle::widgets.twig" %} + new FormThemeTokenParser(), + ); + } + + public function getFunctions() + { + return array( + 'form_enctype' => new \Twig_Function_Method($this, 'renderEnctype', array('is_safe' => array('html'))), + 'form_widget' => new \Twig_Function_Method($this, 'renderWidget', array('is_safe' => array('html'))), + 'form_errors' => new \Twig_Function_Method($this, 'renderErrors', array('is_safe' => array('html'))), + 'form_label' => new \Twig_Function_Method($this, 'renderLabel', array('is_safe' => array('html'))), + 'form_row' => new \Twig_Function_Method($this, 'renderRow', array('is_safe' => array('html'))), + 'form_rest' => new \Twig_Function_Method($this, 'renderRest', array('is_safe' => array('html'))), + 'csrf_token' => new \Twig_Function_Method($this, 'getCsrfToken'), + '_form_is_choice_group' => new \Twig_Function_Method($this, 'isChoiceGroup', array('is_safe' => array('html'))), + '_form_is_choice_selected' => new \Twig_Function_Method($this, 'isChoiceSelected', array('is_safe' => array('html'))), + ); + } + + public function isChoiceGroup($label) + { + return FormUtil::isChoiceGroup($label); + } + + public function isChoiceSelected(FormView $view, ChoiceView $choice) + { + return FormUtil::isChoiceSelected($choice->getValue(), $view->getVar('value')); + } + + /** + * Renders the HTML enctype in the form tag, if necessary + * + * Example usage in Twig templates: + * + *
    + * + * @param FormView $view The view for which to render the encoding type + * + * @return string The html markup + */ + public function renderEnctype(FormView $view) + { + return $this->render($view, 'enctype'); + } + + /** + * Renders a row for the view. + * + * @param FormView $view The view to render as a row + * @param array $variables An array of variables + * + * @return string The html markup + */ + public function renderRow(FormView $view, array $variables = array()) + { + return $this->render($view, 'row', $variables); + } + + /** + * Renders views which have not already been rendered. + * + * @param FormView $view The parent view + * @param array $variables An array of variables + * + * @return string The html markup + */ + public function renderRest(FormView $view, array $variables = array()) + { + return $this->render($view, 'rest', $variables); + } + + /** + * Renders the HTML for a given view + * + * Example usage in Twig: + * + * {{ form_widget(view) }} + * + * You can pass options during the call: + * + * {{ form_widget(view, {'attr': {'class': 'foo'}}) }} + * + * {{ form_widget(view, {'separator': '+++++'}) }} + * + * @param FormView $view The view to render + * @param array $variables Additional variables passed to the template + * + * @return string The html markup + */ + public function renderWidget(FormView $view, array $variables = array()) + { + return $this->render($view, 'widget', $variables); + } + + /** + * Renders the errors of the given view + * + * @param FormView $view The view to render the errors for + * + * @return string The html markup + */ + public function renderErrors(FormView $view) + { + return $this->render($view, 'errors'); + } + + /** + * Renders the label of the given view + * + * @param FormView $view The view to render the label for + * @param string $label Label name + * @param array $variables Additional variables passed to the template + * + * @return string The html markup + */ + public function renderLabel(FormView $view, $label = null, array $variables = array()) + { + if ($label !== null) { + $variables += array('label' => $label); + } + + return $this->render($view, 'label', $variables); + } + + /** + * Renders a template. + * + * 1. This function first looks for a block named "__
    ", + * 2. if such a block is not found the function will look for a block named + * "_
    ", + * 3. the type name is recursively replaced by the parent type name until a + * corresponding block is found + * + * @param FormView $view The form view + * @param string $section The section to render (i.e. 'row', 'widget', 'label', ...) + * @param array $variables Additional variables + * + * @return string The html markup + * + * @throws FormException if no template block exists to render the given section of the view + */ + protected function render(FormView $view, $section, array $variables = array()) + { + $mainTemplate = in_array($section, array('widget', 'row')); + + if ($mainTemplate && $view->isRendered()) { + return ''; + } + + if (null === $this->template) { + $this->template = reset($this->resources); + if (!$this->template instanceof \Twig_Template) { + $this->template = $this->environment->loadTemplate($this->template); + } + } + + $custom = '_'.$view->getVar('id'); + $rendering = $custom.$section; + $blocks = $this->getBlocks($view); + + if (isset($this->varStack[$rendering])) { + $typeIndex = $this->varStack[$rendering]['typeIndex'] - 1; + $types = $this->varStack[$rendering]['types']; + $this->varStack[$rendering]['variables'] = array_replace_recursive($this->varStack[$rendering]['variables'], $variables); + } else { + $types = $view->getVar('types'); + $types[] = $custom; + $typeIndex = count($types) - 1; + $this->varStack[$rendering] = array( + 'variables' => array_replace_recursive($view->getVars(), $variables), + 'types' => $types, + ); + } + + do { + $types[$typeIndex] .= '_'.$section; + + if (isset($blocks[$types[$typeIndex]])) { + $this->varStack[$rendering]['typeIndex'] = $typeIndex; + + // we do not call renderBlock here to avoid too many nested level calls (XDebug limits the level to 100 by default) + ob_start(); + $this->template->displayBlock($types[$typeIndex], $this->varStack[$rendering]['variables'], $blocks); + $html = ob_get_clean(); + + if ($mainTemplate) { + $view->setRendered(); + } + + unset($this->varStack[$rendering]); + + return $html; + } + } while (--$typeIndex >= 0); + + throw new FormException(sprintf( + 'Unable to render the form as none of the following blocks exist: "%s".', + implode('", "', array_reverse($types)) + )); + } + + /** + * Returns a CSRF token. + * + * Use this helper for CSRF protection without the overhead of creating a + * form. + * + * + * + * + * + * Check the token in your action using the same intention. + * + * + * $csrfProvider = $this->get('form.csrf_provider'); + * if (!$csrfProvider->isCsrfTokenValid('rm_user_'.$user->getId(), $token)) { + * throw new \RuntimeException('CSRF attack detected.'); + * } + * + * + * @param string $intention The intention of the protected action + * + * @return string A CSRF token + */ + public function getCsrfToken($intention) + { + if (!$this->csrfProvider instanceof CsrfProviderInterface) { + throw new \BadMethodCallException('CSRF token can only be generated if a CsrfProviderInterface is injected in the constructor.'); + } + + return $this->csrfProvider->generateCsrfToken($intention); + } + + /** + * Returns the name of the extension. + * + * @return string The extension name + */ + public function getName() + { + return 'form'; + } + + /** + * Returns the blocks used to render the view. + * + * Templates are looked for in the resources in the following order: + * * resources from the themes (and its parents) + * * resources from the themes of parent views (up to the root view) + * * default resources + * + * @param FormView $view The view + * + * @return array An array of Twig_TemplateInterface instances + */ + protected function getBlocks(FormView $view) + { + if (!$this->blocks->contains($view)) { + $rootView = !$view->hasParent(); + + $templates = $rootView ? $this->resources : array(); + + if (isset($this->themes[$view])) { + $templates = array_merge($templates, $this->themes[$view]); + } + + $blocks = array(); + + foreach ($templates as $template) { + if (!$template instanceof \Twig_Template) { + $template = $this->environment->loadTemplate($template); + } + + $templateBlocks = array(); + do { + $templateBlocks = array_merge($template->getBlocks(), $templateBlocks); + } while (false !== $template = $template->getParent(array())); + $blocks = array_merge($blocks, $templateBlocks); + } + + if (!$rootView) { + $blocks = array_merge($this->getBlocks($view->getParent()), $blocks); + } + + $this->blocks->attach($view, $blocks); + } else { + $blocks = $this->blocks[$view]; + } + + return $blocks; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/RoutingExtension.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/RoutingExtension.php new file mode 100644 index 0000000..65d7dd2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/RoutingExtension.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\Bridge\Twig\Extension; + +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; + +/** + * Provides integration of the Routing component with Twig. + * + * @author Fabien Potencier + */ +class RoutingExtension extends \Twig_Extension +{ + private $generator; + + public function __construct(UrlGeneratorInterface $generator) + { + $this->generator = $generator; + } + + /** + * Returns a list of functions to add to the existing list. + * + * @return array An array of functions + */ + public function getFunctions() + { + return array( + 'url' => new \Twig_Function_Method($this, 'getUrl'), + 'path' => new \Twig_Function_Method($this, 'getPath'), + ); + } + + public function getPath($name, $parameters = array()) + { + return $this->generator->generate($name, $parameters, false); + } + + public function getUrl($name, $parameters = array()) + { + return $this->generator->generate($name, $parameters, true); + } + + /** + * Returns the name of the extension. + * + * @return string The extension name + */ + public function getName() + { + return 'routing'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/SecurityExtension.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/SecurityExtension.php new file mode 100644 index 0000000..c9f4466 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/SecurityExtension.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\Bridge\Twig\Extension; + +use Symfony\Component\Security\Acl\Voter\FieldVote; +use Symfony\Component\Security\Core\SecurityContextInterface; + +/** + * SecurityExtension exposes security context features. + * + * @author Fabien Potencier + */ +class SecurityExtension extends \Twig_Extension +{ + private $context; + + public function __construct(SecurityContextInterface $context = null) + { + $this->context = $context; + } + + public function isGranted($role, $object = null, $field = null) + { + if (null === $this->context) { + return false; + } + + if (null !== $field) { + $object = new FieldVote($object, $field); + } + + return $this->context->isGranted($role, $object); + } + + /** + * {@inheritdoc} + */ + public function getFunctions() + { + return array( + 'is_granted' => new \Twig_Function_Method($this, 'isGranted'), + ); + } + + /** + * Returns the name of the extension. + * + * @return string The extension name + */ + public function getName() + { + return 'security'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/TranslationExtension.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/TranslationExtension.php new file mode 100644 index 0000000..3718e9e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/TranslationExtension.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\Bridge\Twig\Extension; + +use Symfony\Bridge\Twig\TokenParser\TransTokenParser; +use Symfony\Bridge\Twig\TokenParser\TransChoiceTokenParser; +use Symfony\Bridge\Twig\TokenParser\TransDefaultDomainTokenParser; +use Symfony\Component\Translation\TranslatorInterface; +use Symfony\Bridge\Twig\NodeVisitor\TranslationNodeVisitor; +use Symfony\Bridge\Twig\NodeVisitor\TranslationDefaultDomainNodeVisitor; + +/** + * Provides integration of the Translation component with Twig. + * + * @author Fabien Potencier + */ +class TranslationExtension extends \Twig_Extension +{ + private $translator; + private $translationNodeVisitor; + + public function __construct(TranslatorInterface $translator) + { + $this->translator = $translator; + $this->translationNodeVisitor = new TranslationNodeVisitor(); + } + + public function getTranslator() + { + return $this->translator; + } + + /** + * {@inheritdoc} + */ + public function getFilters() + { + return array( + 'trans' => new \Twig_Filter_Method($this, 'trans'), + 'transchoice' => new \Twig_Filter_Method($this, 'transchoice'), + ); + } + + /** + * Returns the token parser instance to add to the existing list. + * + * @return array An array of Twig_TokenParser instances + */ + public function getTokenParsers() + { + return array( + // {% trans %}Symfony is great!{% endtrans %} + new TransTokenParser(), + + // {% transchoice count %} + // {0} There is no apples|{1} There is one apple|]1,Inf] There is {{ count }} apples + // {% endtranschoice %} + new TransChoiceTokenParser(), + + // {% trans_default_domain "foobar" %} + new TransDefaultDomainTokenParser(), + ); + } + + /** + * {@inheritdoc} + */ + public function getNodeVisitors() + { + return array($this->translationNodeVisitor, new TranslationDefaultDomainNodeVisitor()); + } + + public function getTranslationNodeVisitor() + { + return $this->translationNodeVisitor; + } + + public function trans($message, array $arguments = array(), $domain = null, $locale = null) + { + if (null === $domain) { + $domain = 'messages'; + } + + return $this->translator->trans($message, $arguments, $domain, $locale); + } + + public function transchoice($message, $count, array $arguments = array(), $domain = null, $locale = null) + { + if (null === $domain) { + $domain = 'messages'; + } + + return $this->translator->transChoice($message, $count, array_merge(array('%count%' => $count), $arguments), $domain, $locale); + } + + /** + * Returns the name of the extension. + * + * @return string The extension name + */ + public function getName() + { + return 'translator'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/YamlExtension.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/YamlExtension.php new file mode 100644 index 0000000..130575c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/YamlExtension.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\Bridge\Twig\Extension; + +use Symfony\Component\Yaml\Dumper as YamlDumper; + +/** + * Provides integration of the Yaml component with Twig. + * + * @author Fabien Potencier + */ +class YamlExtension extends \Twig_Extension +{ + /** + * {@inheritdoc} + */ + public function getFilters() + { + return array( + 'yaml_encode' => new \Twig_Filter_Method($this, 'encode'), + 'yaml_dump' => new \Twig_Filter_Method($this, 'dump'), + ); + } + + public function encode($input, $inline = 0) + { + static $dumper; + + if (null === $dumper) { + $dumper = new YamlDumper(); + } + + return $dumper->dump($input, $inline); + } + + public function dump($value) + { + if (is_resource($value)) { + return '%Resource%'; + } + + if (is_array($value) || is_object($value)) { + return '%'.gettype($value).'% '.$this->encode($value); + } + + return $this->encode($value); + } + + /** + * Returns the name of the extension. + * + * @return string The extension name + */ + public function getName() + { + return 'yaml'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/LICENSE b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/LICENSE new file mode 100644 index 0000000..cdffe7a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 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/symfony/src/Symfony/Bridge/Twig/Node/FormThemeNode.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Node/FormThemeNode.php new file mode 100644 index 0000000..c6fe132 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Node/FormThemeNode.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\Bridge\Twig\Node; + +/** + * @author Fabien Potencier + */ +class FormThemeNode extends \Twig_Node +{ + public function __construct(\Twig_NodeInterface $form, \Twig_NodeInterface $resources, $lineno, $tag = null) + { + parent::__construct(array('form' => $form, 'resources' => $resources), array(), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param \Twig_Compiler $compiler A Twig_Compiler instance + */ + public function compile(\Twig_Compiler $compiler) + { + $compiler + ->addDebugInfo($this) + ->write('echo $this->env->getExtension(\'form\')->setTheme(') + ->subcompile($this->getNode('form')) + ->raw(', ') + ->subcompile($this->getNode('resources')) + ->raw(");\n"); + ; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Node/TransDefaultDomainNode.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Node/TransDefaultDomainNode.php new file mode 100644 index 0000000..adee71f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Node/TransDefaultDomainNode.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\Bridge\Twig\Node; + +/** + * @author Fabien Potencier + */ +class TransDefaultDomainNode extends \Twig_Node +{ + public function __construct(\Twig_Node_Expression $expr, $lineno = 0, $tag = null) + { + parent::__construct(array('expr' => $expr), array(), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param \Twig_Compiler $compiler A Twig_Compiler instance + */ + public function compile(\Twig_Compiler $compiler) + { + // noop as this node is just a marker for TranslationDefaultDomainNodeVisitor + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Node/TransNode.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Node/TransNode.php new file mode 100644 index 0000000..a68c101 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Node/TransNode.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\Bridge\Twig\Node; + +/** + * @author Fabien Potencier + */ +class TransNode extends \Twig_Node +{ + public function __construct(\Twig_NodeInterface $body, \Twig_NodeInterface $domain = null, \Twig_Node_Expression $count = null, \Twig_Node_Expression $vars = null, \Twig_Node_Expression $locale = null, $lineno = 0, $tag = null) + { + parent::__construct(array('count' => $count, 'body' => $body, 'domain' => $domain, 'vars' => $vars, 'locale' => $locale), array(), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param \Twig_Compiler $compiler A Twig_Compiler instance + */ + public function compile(\Twig_Compiler $compiler) + { + $compiler->addDebugInfo($this); + + $vars = $this->getNode('vars'); + $defaults = new \Twig_Node_Expression_Array(array(), -1); + if ($vars instanceof \Twig_Node_Expression_Array) { + $defaults = $this->getNode('vars'); + $vars = null; + } + list($msg, $defaults) = $this->compileString($this->getNode('body'), $defaults); + + $method = null === $this->getNode('count') ? 'trans' : 'transChoice'; + + $compiler + ->write('echo $this->env->getExtension(\'translator\')->getTranslator()->'.$method.'(') + ->subcompile($msg) + ; + + $compiler->raw(', '); + + if (null !== $this->getNode('count')) { + $compiler + ->subcompile($this->getNode('count')) + ->raw(', ') + ; + } + + if (null !== $vars) { + $compiler + ->raw('array_merge(') + ->subcompile($defaults) + ->raw(', ') + ->subcompile($this->getNode('vars')) + ->raw(')') + ; + } else { + $compiler->subcompile($defaults); + } + + $compiler->raw(', '); + + if (null === $this->getNode('domain')) { + $compiler->repr('messages'); + } else { + $compiler->subcompile($this->getNode('domain')); + } + + if (null !== $this->getNode('locale')) { + $compiler + ->raw(', ') + ->subcompile($this->getNode('locale')) + ; + } + $compiler->raw(");\n"); + } + + protected function compileString(\Twig_NodeInterface $body, \Twig_Node_Expression_Array $vars) + { + if ($body instanceof \Twig_Node_Expression_Constant) { + $msg = $body->getAttribute('value'); + } elseif ($body instanceof \Twig_Node_Text) { + $msg = $body->getAttribute('data'); + } else { + return array($body, $vars); + } + + preg_match_all('/(?=')) { + foreach ($matches[1] as $var) { + $key = new \Twig_Node_Expression_Constant('%'.$var.'%', $body->getLine()); + if (!$vars->hasElement($key)) { + $vars->addElement(new \Twig_Node_Expression_Name($var, $body->getLine()), $key); + } + } + } else { + $current = array(); + foreach ($vars as $name => $var) { + $current[$name] = true; + } + foreach ($matches[1] as $var) { + if (!isset($current['%'.$var.'%'])) { + $vars->setNode('%'.$var.'%', new \Twig_Node_Expression_Name($var, $body->getLine())); + } + } + } + + return array(new \Twig_Node_Expression_Constant(str_replace('%%', '%', trim($msg)), $body->getLine()), $vars); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php new file mode 100644 index 0000000..c7bebdd --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.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\Bridge\Twig\NodeVisitor; + +use Symfony\Bridge\Twig\Node\TransNode; +use Symfony\Bridge\Twig\Node\TransDefaultDomainNode; + +/** + * TranslationDefaultDomainNodeVisitor. + * + * @author Fabien Potencier + */ +class TranslationDefaultDomainNodeVisitor implements \Twig_NodeVisitorInterface +{ + private $domain; + + /** + * {@inheritdoc} + */ + public function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env) + { + if ($node instanceof \Twig_Node_Module) { + $this->domain = null; + } + + if ($node instanceof TransDefaultDomainNode) { + $var = $env->getParser()->getVarName(); + $name = new \Twig_Node_Expression_AssignName($var, $node->getLine()); + $this->domain = new \Twig_Node_Expression_Name($var, $node->getLine()); + + return new \Twig_Node_Set(false, new \Twig_Node(array($name)), new \Twig_Node(array($node->getNode('expr'))), $node->getLine()); + } + + if (null === $this->domain) { + return $node; + } + + if ($node instanceof \Twig_Node_Expression_Filter && in_array($node->getNode('filter')->getAttribute('value'), array('trans', 'transchoice'))) { + $ind = 'trans' === $node->getNode('filter')->getAttribute('value') ? 1 : 2; + $arguments = $node->getNode('arguments'); + if (!$arguments->hasNode($ind)) { + if (!$arguments->hasNode($ind - 1)) { + $arguments->setNode($ind - 1, new \Twig_Node_Expression_Array(array(), $node->getLine())); + } + + $arguments->setNode($ind, $this->domain); + } + } elseif ($node instanceof TransNode) { + if (null === $node->getNode('domain')) { + $node->setNode('domain', $this->domain); + } + } + + return $node; + } + + /** + * {@inheritdoc} + */ + public function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env) + { + return $node; + } + + /** + * {@inheritdoc} + */ + public function getPriority() + { + return 0; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/NodeVisitor/TranslationNodeVisitor.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/NodeVisitor/TranslationNodeVisitor.php new file mode 100644 index 0000000..3a943f7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/NodeVisitor/TranslationNodeVisitor.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\Bridge\Twig\NodeVisitor; + +use Symfony\Bridge\Twig\Node\TransNode; + +/** + * TranslationNodeVisitor extracts translation messages. + * + * @author Fabien Potencier + */ +class TranslationNodeVisitor implements \Twig_NodeVisitorInterface +{ + private $enabled = false; + private $messages = array(); + + public function enable() + { + $this->enabled = true; + $this->messages = array(); + } + + public function disable() + { + $this->enabled = false; + $this->messages = array(); + } + + public function getMessages() + { + return $this->messages; + } + + /** + * {@inheritdoc} + */ + public function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env) + { + if (!$this->enabled) { + return $node; + } + + if ( + $node instanceof \Twig_Node_Expression_Filter && + 'trans' === $node->getNode('filter')->getAttribute('value') && + $node->getNode('node') instanceof \Twig_Node_Expression_Constant + ) { + // extract constant nodes with a trans filter + $this->messages[] = array( + $node->getNode('node')->getAttribute('value'), + $node->getNode('arguments')->hasNode(1) ? $node->getNode('arguments')->getNode(1)->getAttribute('value') : null, + ); + } elseif ( + $node instanceof \Twig_Node_Expression_Filter && + 'transchoice' === $node->getNode('filter')->getAttribute('value') && + $node->getNode('node') instanceof \Twig_Node_Expression_Constant + ) { + // extract constant nodes with a trans filter + $this->messages[] = array( + $node->getNode('node')->getAttribute('value'), + $node->getNode('arguments')->hasNode(2) ? $node->getNode('arguments')->getNode(2)->getAttribute('value') : null, + ); + } elseif ($node instanceof TransNode) { + // extract trans nodes + $this->messages[] = array( + $node->getNode('body')->getAttribute('data'), + null === $node->getNode('domain') ? 'messages' : $node->getNode('domain')->getAttribute('value'), + ); + } + + return $node; + } + + /** + * {@inheritdoc} + */ + public function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env) + { + return $node; + } + + /** + * {@inheritdoc} + */ + public function getPriority() + { + return -10; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/README.md b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/README.md new file mode 100644 index 0000000..80cf13b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/README.md @@ -0,0 +1,15 @@ +Twig Bridge +=========== + +Provides integration for [Twig](http://twig.sensiolabs.org/) with various +Symfony2 components. + +Resources +--------- + +If you want to run the unit tests, install dev dependencies before +running PHPUnit: + + php composer.phar install --dev + + phpunit diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig new file mode 100644 index 0000000..bff18c6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig @@ -0,0 +1,329 @@ +{# Widgets #} + +{% block form_widget %} +{% spaceless %} + {% if compound %} + {{ block('form_widget_compound') }} + {% else %} + {{ block('form_widget_simple') }} + {% endif %} +{% endspaceless %} +{% endblock form_widget %} + +{% block form_widget_simple %} +{% spaceless %} + {% set type = type|default('text') %} + +{% endspaceless %} +{% endblock form_widget_simple %} + +{% block form_widget_compound %} +{% spaceless %} +
    + {{ block('form_rows') }} + {{ form_rest(form) }} +
    +{% endspaceless %} +{% endblock form_widget_compound %} + +{% block collection_widget %} +{% spaceless %} + {% if prototype is defined %} + {% set attr = attr|merge({'data-prototype': form_row(prototype) }) %} + {% endif %} + {{ block('form_widget') }} +{% endspaceless %} +{% endblock collection_widget %} + +{% block textarea_widget %} +{% spaceless %} + +{% endspaceless %} +{% endblock textarea_widget %} + +{% block choice_widget %} +{% spaceless %} + {% if expanded %} + {{ block('choice_widget_expanded') }} + {% else %} + {{ block('choice_widget_collapsed') }} + {% endif %} +{% endspaceless %} +{% endblock choice_widget %} + +{% block choice_widget_expanded %} +{% spaceless %} +
    + {% for child in form %} + {{ form_widget(child) }} + {{ form_label(child) }} + {% endfor %} +
    +{% endspaceless %} +{% endblock choice_widget_expanded %} + +{% block choice_widget_collapsed %} +{% spaceless %} + +{% endspaceless %} +{% endblock choice_widget_collapsed %} + +{% block choice_widget_options %} +{% spaceless %} + {% for index, choice in options %} + {% if _form_is_choice_group(choice) %} + + {% for nested_choice in choice %} + + {% endfor %} + + {% else %} + + {% endif %} + {% endfor %} +{% endspaceless %} +{% endblock choice_widget_options %} + +{% block checkbox_widget %} +{% spaceless %} + +{% endspaceless %} +{% endblock checkbox_widget %} + +{% block radio_widget %} +{% spaceless %} + +{% endspaceless %} +{% endblock radio_widget %} + +{% block datetime_widget %} +{% spaceless %} + {% if widget == 'single_text' %} + {{ block('form_widget_simple') }} + {% else %} +
    + {{ form_errors(form.date) }} + {{ form_errors(form.time) }} + {{ form_widget(form.date) }} + {{ form_widget(form.time) }} +
    + {% endif %} +{% endspaceless %} +{% endblock datetime_widget %} + +{% block date_widget %} +{% spaceless %} + {% if widget == 'single_text' %} + {{ block('form_widget_simple') }} + {% else %} +
    + {{ date_pattern|replace({ + '{{ year }}': form_widget(form.year), + '{{ month }}': form_widget(form.month), + '{{ day }}': form_widget(form.day), + })|raw }} +
    + {% endif %} +{% endspaceless %} +{% endblock date_widget %} + +{% block time_widget %} +{% spaceless %} + {% if widget == 'single_text' %} + {{ block('form_widget_simple') }} + {% else %} +
    + {{ form_widget(form.hour, { 'attr': { 'size': '1' } }) }}:{{ form_widget(form.minute, { 'attr': { 'size': '1' } }) }}{% if with_seconds %}:{{ form_widget(form.second, { 'attr': { 'size': '1' } }) }}{% endif %} +
    + {% endif %} +{% endspaceless %} +{% endblock time_widget %} + +{% block number_widget %} +{% spaceless %} + {# type="number" doesn't work with floats #} + {% set type = type|default('text') %} + {{ block('form_widget_simple') }} +{% endspaceless %} +{% endblock number_widget %} + +{% block integer_widget %} +{% spaceless %} + {% set type = type|default('number') %} + {{ block('form_widget_simple') }} +{% endspaceless %} +{% endblock integer_widget %} + +{% block money_widget %} +{% spaceless %} + {{ money_pattern|replace({ '{{ widget }}': block('form_widget_simple') })|raw }} +{% endspaceless %} +{% endblock money_widget %} + +{% block url_widget %} +{% spaceless %} + {% set type = type|default('url') %} + {{ block('form_widget_simple') }} +{% endspaceless %} +{% endblock url_widget %} + +{% block search_widget %} +{% spaceless %} + {% set type = type|default('search') %} + {{ block('form_widget_simple') }} +{% endspaceless %} +{% endblock search_widget %} + +{% block percent_widget %} +{% spaceless %} + {% set type = type|default('text') %} + {{ block('form_widget_simple') }} % +{% endspaceless %} +{% endblock percent_widget %} + +{% block password_widget %} +{% spaceless %} + {% set type = type|default('password') %} + {{ block('form_widget_simple') }} +{% endspaceless %} +{% endblock password_widget %} + +{% block hidden_widget %} +{% spaceless %} + {% set type = type|default('hidden') %} + {{ block('form_widget_simple') }} +{% endspaceless %} +{% endblock hidden_widget %} + +{% block email_widget %} +{% spaceless %} + {% set type = type|default('email') %} + {{ block('form_widget_simple') }} +{% endspaceless %} +{% endblock email_widget %} + +{# Labels #} + +{% block form_label %} +{% spaceless %} + {% if not compound %} + {% set label_attr = label_attr|merge({'for': id}) %} + {% endif %} + {% if required %} + {% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %} + {% endif %} + {{ label|trans({}, translation_domain) }} +{% endspaceless %} +{% endblock form_label %} + +{# Rows #} + +{% block repeated_row %} +{% spaceless %} + {{ block('form_rows') }} +{% endspaceless %} +{% endblock repeated_row %} + +{% block form_row %} +{% spaceless %} +
    + {{ form_label(form, label|default(null)) }} + {# + If the child is a compound form, the errors are rendered inside + the container. See also block form_rows. + #} + {% if not compound %} + {{ form_errors(form) }} + {% endif %} + {{ form_widget(form) }} +
    +{% endspaceless %} +{% endblock form_row %} + +{% block hidden_row %} + {{ form_widget(form) }} +{% endblock hidden_row %} + +{# Misc #} + +{% block form_enctype %} +{% spaceless %} + {% if multipart %}enctype="multipart/form-data"{% endif %} +{% endspaceless %} +{% endblock form_enctype %} + +{% block form_errors %} +{% spaceless %} + {% if errors|length > 0 %} +
      + {% for error in errors %} +
    • {{ + error.messagePluralization is null + ? error.messageTemplate|trans(error.messageParameters, 'validators') + : error.messageTemplate|transchoice(error.messagePluralization, error.messageParameters, 'validators') + }}
    • + {% endfor %} +
    + {% endif %} +{% endspaceless %} +{% endblock form_errors %} + +{% block form_rest %} +{% spaceless %} + {% for child in form %} + {% if not child.rendered %} + {{ form_row(child) }} + {% endif %} + {% endfor %} +{% endspaceless %} +{% endblock form_rest %} + +{# Support #} + +{% block form_rows %} +{% spaceless %} + {{ form_errors(form) }} + {% for child in form %} + {{ form_row(child) }} + {% endfor %} +{% endspaceless %} +{% endblock form_rows %} + +{% block widget_attributes %} +{% spaceless %} + id="{{ id }}" name="{{ full_name }}"{% if read_only %} readonly="readonly"{% endif %}{% if disabled %} disabled="disabled"{% endif %}{% if required %} required="required"{% endif %}{% if max_length %} maxlength="{{ max_length }}"{% endif %}{% if pattern %} pattern="{{ pattern }}"{% endif %} + {% for attrname, attrvalue in attr %}{% if attrname in ['placeholder', 'title'] %}{{ attrname }}="{{ attrvalue|trans({}, translation_domain) }}" {% else %}{{ attrname }}="{{ attrvalue }}" {% endif %}{% endfor %} +{% endspaceless %} +{% endblock widget_attributes %} + +{% block widget_container_attributes %} +{% spaceless %} + {% if id is not empty %}id="{{ id }}" {% endif %} + {% for attrname, attrvalue in attr %}{{ attrname }}="{{ attrvalue }}" {% endfor %} +{% endspaceless %} +{% endblock widget_container_attributes %} + +{# Deprecated in Symfony 2.1, to be removed in 2.3 #} + +{% block generic_label %}{{ block('form_label') }}{% endblock %} +{% block widget_choice_options %}{{ block('choice_widget_options') }}{% endblock %} +{% block field_widget %}{{ block('form_widget_simple') }}{% endblock %} +{% block field_label %}{{ block('form_label') }}{% endblock %} +{% block field_row %}{{ block('form_row') }}{% endblock %} +{% block field_enctype %}{{ block('form_enctype') }}{% endblock %} +{% block field_errors %}{{ block('form_errors') }}{% endblock %} +{% block field_rest %}{{ block('form_rest') }}{% endblock %} +{% block field_rows %}{{ block('form_rows') }}{% endblock %} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form/form_table_layout.html.twig b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form/form_table_layout.html.twig new file mode 100644 index 0000000..fbfe96a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form/form_table_layout.html.twig @@ -0,0 +1,52 @@ +{% use "form_div_layout.html.twig" %} + +{% block form_row %} +{% spaceless %} + + + {{ form_label(form, label|default(null)) }} + + + {% if not compound %} + {{ form_errors(form) }} + {% endif %} + {{ form_widget(form) }} + + +{% endspaceless %} +{% endblock form_row %} + +{% block form_errors %} +{% spaceless %} + {% if not compound %} + {{ parent() }} + {% else %} + {% if errors|length > 0 %} + + + {{ parent() }} + + + {% endif %} + {% endif %} +{% endspaceless %} +{% endblock form_errors %} + +{% block hidden_row %} +{% spaceless %} + + + {{ form_widget(form) }} + + +{% endspaceless %} +{% endblock hidden_row %} + +{% block form_widget_compound %} +{% spaceless %} + + {{ block('form_rows') }} + {{ form_rest(form) }} +
    +{% endspaceless %} +{% endblock form_widget_compound %} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/Fixtures/StubFilesystemLoader.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/Fixtures/StubFilesystemLoader.php new file mode 100644 index 0000000..36c61cd --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/Fixtures/StubFilesystemLoader.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\Bridge\Twig\Tests\Extension\Fixtures; + +// Preventing autoloader throwing E_FATAL when Twig is now available +if (!class_exists('Twig_Environment')) { + class StubFilesystemLoader + { + } +} else { + class StubFilesystemLoader extends \Twig_Loader_Filesystem + { + protected function findTemplate($name) + { + // strip away bundle name + $parts = explode(':', $name); + + return parent::findTemplate(end($parts)); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/Fixtures/StubTranslator.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/Fixtures/StubTranslator.php new file mode 100644 index 0000000..b7d011b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/Fixtures/StubTranslator.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\Bridge\Twig\Tests\Extension\Fixtures; + +use Symfony\Component\Translation\TranslatorInterface; + +class StubTranslator implements TranslatorInterface +{ + public function trans($id, array $parameters = array(), $domain = null, $locale = null) + { + return '[trans]'.$id.'[/trans]'; + } + + public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null) + { + return '[trans]'.$id.'[/trans]'; + } + + public function setLocale($locale) + { + } + + public function getLocale() + { + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionDivLayoutTest.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionDivLayoutTest.php new file mode 100644 index 0000000..5b6e446 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionDivLayoutTest.php @@ -0,0 +1,147 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Twig\Tests\Extension; + +use Symfony\Bridge\Twig\Extension\FormExtension; +use Symfony\Bridge\Twig\Extension\TranslationExtension; +use Symfony\Bridge\Twig\Tests\Extension\Fixtures\StubTranslator; +use Symfony\Bridge\Twig\Tests\Extension\Fixtures\StubFilesystemLoader; +use Symfony\Component\Form\FormView; +use Symfony\Component\Form\Tests\AbstractDivLayoutTest; + +class FormExtensionDivLayoutTest extends AbstractDivLayoutTest +{ + protected $extension; + + protected function setUp() + { + if (!class_exists('Symfony\Component\Locale\Locale')) { + $this->markTestSkipped('The "Locale" component is not available'); + } + + if (!class_exists('Symfony\Component\EventDispatcher\EventDispatcher')) { + $this->markTestSkipped('The "EventDispatcher" component is not available'); + } + + if (!class_exists('Symfony\Component\Form\Form')) { + $this->markTestSkipped('The "Form" component is not available'); + } + + if (!class_exists('Twig_Environment')) { + $this->markTestSkipped('Twig is not available.'); + } + + parent::setUp(); + + $loader = new StubFilesystemLoader(array( + __DIR__.'/../../../../../../src/Symfony/Bridge/Twig/Resources/views/Form', + __DIR__, + )); + + $this->extension = new FormExtension($this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'), array( + 'form_div_layout.html.twig', + 'custom_widgets.html.twig', + )); + + $environment = new \Twig_Environment($loader); + $environment->addExtension($this->extension); + $environment->addExtension(new TranslationExtension(new StubTranslator())); + + $this->extension->initRuntime($environment); + } + + protected function tearDown() + { + parent::tearDown(); + + $this->extension = null; + } + + public function testThemeBlockInheritanceUsingUse() + { + $view = $this->factory + ->createNamed('name', 'email') + ->createView() + ; + + $this->setTheme($view, array('theme_use.html.twig')); + + $this->assertMatchesXpath( + $this->renderWidget($view), + '/input[@type="email"][@rel="theme"]' + ); + } + + public function testThemeBlockInheritanceUsingExtend() + { + $view = $this->factory + ->createNamed('name', 'email') + ->createView() + ; + + $this->setTheme($view, array('theme_extends.html.twig')); + + $this->assertMatchesXpath( + $this->renderWidget($view), + '/input[@type="email"][@rel="theme"]' + ); + } + + protected function renderEnctype(FormView $view) + { + return (string)$this->extension->renderEnctype($view); + } + + protected function renderLabel(FormView $view, $label = null, array $vars = array()) + { + return (string)$this->extension->renderLabel($view, $label, $vars); + } + + protected function renderErrors(FormView $view) + { + return (string)$this->extension->renderErrors($view); + } + + protected function renderWidget(FormView $view, array $vars = array()) + { + return (string)$this->extension->renderWidget($view, $vars); + } + + protected function renderRow(FormView $view, array $vars = array()) + { + return (string)$this->extension->renderRow($view, $vars); + } + + protected function renderRest(FormView $view, array $vars = array()) + { + return (string)$this->extension->renderRest($view, $vars); + } + + protected function setTheme(FormView $view, array $themes) + { + $this->extension->setTheme($view, $themes); + } + + static public function themeBlockInheritanceProvider() + { + return array( + array(array('theme.html.twig')) + ); + } + + static public function themeInheritanceProvider() + { + return array( + array(array('parent_label.html.twig'), array('child_label.html.twig')) + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionTableLayoutTest.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionTableLayoutTest.php new file mode 100644 index 0000000..bfcce48 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionTableLayoutTest.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\Bridge\Twig\Tests\Extension; + +use Symfony\Component\Form\FormView; +use Symfony\Bridge\Twig\Extension\FormExtension; +use Symfony\Bridge\Twig\Extension\TranslationExtension; +use Symfony\Component\Form\Tests\AbstractTableLayoutTest; +use Symfony\Bridge\Twig\Tests\Extension\Fixtures\StubTranslator; +use Symfony\Bridge\Twig\Tests\Extension\Fixtures\StubFilesystemLoader; + +class FormExtensionTableLayoutTest extends AbstractTableLayoutTest +{ + protected $extension; + + protected function setUp() + { + if (!class_exists('Symfony\Component\Locale\Locale')) { + $this->markTestSkipped('The "Locale" component is not available'); + } + + if (!class_exists('Symfony\Component\EventDispatcher\EventDispatcher')) { + $this->markTestSkipped('The "EventDispatcher" component is not available'); + } + + if (!class_exists('Symfony\Component\Form\Form')) { + $this->markTestSkipped('The "Form" component is not available'); + } + + if (!class_exists('Twig_Environment')) { + $this->markTestSkipped('Twig is not available.'); + } + + parent::setUp(); + + $loader = new StubFilesystemLoader(array( + __DIR__.'/../../../../../../src/Symfony/Bridge/Twig/Resources/views/Form', + __DIR__, + )); + + $this->extension = new FormExtension($this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'), array( + 'form_table_layout.html.twig', + 'custom_widgets.html.twig', + )); + + $environment = new \Twig_Environment($loader); + $environment->addExtension($this->extension); + $environment->addExtension(new TranslationExtension(new StubTranslator())); + + $this->extension->initRuntime($environment); + } + + protected function tearDown() + { + parent::tearDown(); + + $this->extension = null; + } + + protected function renderEnctype(FormView $view) + { + return (string)$this->extension->renderEnctype($view); + } + + protected function renderLabel(FormView $view, $label = null, array $vars = array()) + { + return (string)$this->extension->renderLabel($view, $label, $vars); + } + + protected function renderErrors(FormView $view) + { + return (string)$this->extension->renderErrors($view); + } + + protected function renderWidget(FormView $view, array $vars = array()) + { + return (string)$this->extension->renderWidget($view, $vars); + } + + protected function renderRow(FormView $view, array $vars = array()) + { + return (string)$this->extension->renderRow($view, $vars); + } + + protected function renderRest(FormView $view, array $vars = array()) + { + return (string)$this->extension->renderRest($view, $vars); + } + + protected function setTheme(FormView $view, array $themes) + { + $this->extension->setTheme($view, $themes); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php new file mode 100644 index 0000000..b5d8666 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php @@ -0,0 +1,149 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Twig\Tests\Extension; + +use Symfony\Bridge\Twig\Extension\TranslationExtension; +use Symfony\Component\Translation\Translator; +use Symfony\Component\Translation\MessageSelector; +use Symfony\Component\Translation\Loader\ArrayLoader; +use Symfony\Bridge\Twig\Tests\TestCase; + +class TranslationExtensionTest extends TestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\Translation\Translator')) { + $this->markTestSkipped('The "Translation" component is not available'); + } + + if (!class_exists('Twig_Environment')) { + $this->markTestSkipped('Twig is not available.'); + } + } + + public function testEscaping() + { + $output = $this->getTemplate('{% trans %}Percent: %value%%% (%msg%){% endtrans %}')->render(array('value' => 12, 'msg' => 'approx.')); + + $this->assertEquals('Percent: 12% (approx.)', $output); + } + + /** + * @dataProvider getTransTests + */ + public function testTrans($template, $expected, array $variables = array()) + { + if ($expected != $this->getTemplate($template)->render($variables)) { + print $template."\n"; + $loader = new \Twig_Loader_Array(array('index' => $template)); + $twig = new \Twig_Environment($loader, array('debug' => true, 'cache' => false)); + $twig->addExtension(new TranslationExtension(new Translator('en', new MessageSelector()))); + + echo $twig->compile($twig->parse($twig->tokenize($twig->getLoader()->getSource('index'), 'index')))."\n\n"; + $this->assertEquals($expected, $this->getTemplate($template)->render($variables)); + } + + $this->assertEquals($expected, $this->getTemplate($template)->render($variables)); + } + + public function getTransTests() + { + return array( + // trans tag + array('{% trans %}Hello{% endtrans %}', 'Hello'), + array('{% trans %}%name%{% endtrans %}', 'Symfony2', array('name' => 'Symfony2')), + + array('{% trans from elsewhere %}Hello{% endtrans %}', 'Hello'), + + array('{% trans %}Hello %name%{% endtrans %}', 'Hello Symfony2', array('name' => 'Symfony2')), + array('{% trans with { \'%name%\': \'Symfony2\' } %}Hello %name%{% endtrans %}', 'Hello Symfony2'), + array('{% set vars = { \'%name%\': \'Symfony2\' } %}{% trans with vars %}Hello %name%{% endtrans %}', 'Hello Symfony2'), + + array('{% trans into "fr"%}Hello{% endtrans %}', 'Hello'), + + // transchoice + array('{% transchoice count from "messages" %}{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples{% endtranschoice %}', + 'There is no apples', array('count' => 0)), + array('{% transchoice count %}{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples{% endtranschoice %}', + 'There is 5 apples', array('count' => 5)), + array('{% transchoice count %}{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples (%name%){% endtranschoice %}', + 'There is 5 apples (Symfony2)', array('count' => 5, 'name' => 'Symfony2')), + array('{% transchoice count with { \'%name%\': \'Symfony2\' } %}{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples (%name%){% endtranschoice %}', + 'There is 5 apples (Symfony2)', array('count' => 5)), + array('{% transchoice count into "fr"%}{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples{% endtranschoice %}', + 'There is no apples', array('count' => 0)), + + // trans filter + array('{{ "Hello"|trans }}', 'Hello'), + array('{{ name|trans }}', 'Symfony2', array('name' => 'Symfony2')), + array('{{ hello|trans({ \'%name%\': \'Symfony2\' }) }}', 'Hello Symfony2', array('hello' => 'Hello %name%')), + array('{% set vars = { \'%name%\': \'Symfony2\' } %}{{ hello|trans(vars) }}', 'Hello Symfony2', array('hello' => 'Hello %name%')), + array('{{ "Hello"|trans({}, "messages", "fr") }}', 'Hello'), + + // transchoice filter + array('{{ "{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples"|transchoice(count) }}', 'There is 5 apples', array('count' => 5)), + array('{{ text|transchoice(5, {\'%name%\': \'Symfony2\'}) }}', 'There is 5 apples (Symfony2)', array('text' => '{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples (%name%)')), + array('{{ "{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples"|transchoice(count, {}, "messages", "fr") }}', 'There is 5 apples', array('count' => 5)), + ); + } + + public function testDefaultTranslationDomain() + { + $templates = array( + 'index' => ' + {%- extends "base" %} + + {%- trans_default_domain "foo" %} + + {%- block content %} + {%- trans %}foo{% endtrans %} + {%- trans from "custom" %}foo{% endtrans %} + {{- "foo"|trans }} + {{- "foo"|trans({}, "custom") }} + {{- "foo"|transchoice(1) }} + {{- "foo"|transchoice(1, {}, "custom") }} + {% endblock %} + ', + + 'base' => ' + {%- block content "" %} + ', + ); + + $translator = new Translator('en', new MessageSelector()); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', array('foo' => 'foo (messages)'), 'en'); + $translator->addResource('array', array('foo' => 'foo (custom)'), 'en', 'custom'); + $translator->addResource('array', array('foo' => 'foo (foo)'), 'en', 'foo'); + + $template = $this->getTemplate($templates, $translator); + + $this->assertEquals('foo (foo)foo (custom)foo (foo)foo (custom)foo (foo)foo (custom)', trim($template->render(array()))); + } + + protected function getTemplate($template, $translator = null) + { + if (null === $translator) { + $translator = new Translator('en', new MessageSelector()); + } + + if (is_array($template)) { + $loader = new \Twig_Loader_Array($template); + } else { + $loader = new \Twig_Loader_Array(array('index' => $template)); + } + $twig = new \Twig_Environment($loader, array('debug' => true, 'cache' => false)); + $twig->addExtension(new TranslationExtension($translator)); + + return $twig->loadTemplate('index'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/child_label.html.twig b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/child_label.html.twig new file mode 100644 index 0000000..061ef42 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/child_label.html.twig @@ -0,0 +1,3 @@ +{% block form_label %} + +{% endblock form_label %} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/custom_widgets.html.twig b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/custom_widgets.html.twig new file mode 100644 index 0000000..6b9c0bb --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/custom_widgets.html.twig @@ -0,0 +1,5 @@ +{% block _text_id_widget %} +
    + {{ form_widget(form) }} +
    +{% endblock _text_id_widget %} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/parent_label.html.twig b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/parent_label.html.twig new file mode 100644 index 0000000..e96278b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/parent_label.html.twig @@ -0,0 +1,3 @@ +{% block form_label %} + +{% endblock form_label %} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/theme.html.twig b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/theme.html.twig new file mode 100644 index 0000000..da1c1b6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/theme.html.twig @@ -0,0 +1,6 @@ +{% block form_widget_simple %} +{% spaceless %} + {% set type = type|default('text') %} + +{% endspaceless %} +{% endblock form_widget_simple %} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/theme_extends.html.twig b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/theme_extends.html.twig new file mode 100644 index 0000000..8c71986 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/theme_extends.html.twig @@ -0,0 +1,8 @@ +{% extends 'form_div_layout.html.twig' %} + +{% block form_widget_simple %} +{% spaceless %} + {% set type = type|default('text') %} + +{% endspaceless %} +{% endblock form_widget_simple %} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/theme_use.html.twig b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/theme_use.html.twig new file mode 100644 index 0000000..d485b8d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Extension/theme_use.html.twig @@ -0,0 +1,8 @@ +{% use 'form_div_layout.html.twig' %} + +{% block form_widget_simple %} +{% spaceless %} + {% set type = type|default('text') %} + +{% endspaceless %} +{% endblock form_widget_simple %} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Node/FormThemeTest.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Node/FormThemeTest.php new file mode 100644 index 0000000..ec81f5f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Node/FormThemeTest.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Twig\Tests\Node; + +use Symfony\Bridge\Twig\Tests\TestCase; +use Symfony\Bridge\Twig\Node\FormThemeNode; + +class FormThemeTest extends TestCase +{ + protected function setUp() + { + parent::setUp(); + + if (version_compare(\Twig_Environment::VERSION, '1.5.0', '<')) { + $this->markTestSkipped('Requires Twig version to be at least 1.5.0.'); + } + } + + public function testConstructor() + { + $form = new \Twig_Node_Expression_Name('form', 0); + $resources = new \Twig_Node(array( + new \Twig_Node_Expression_Constant('tpl1', 0), + new \Twig_Node_Expression_Constant('tpl2', 0) + )); + + $node = new FormThemeNode($form, $resources, 0); + + $this->assertEquals($form, $node->getNode('form')); + $this->assertEquals($resources, $node->getNode('resources')); + } + + public function testCompile() + { + $form = new \Twig_Node_Expression_Name('form', 0); + $resources = new \Twig_Node_Expression_Array(array( + new \Twig_Node_Expression_Constant(0, 0), + new \Twig_Node_Expression_Constant('tpl1', 0), + new \Twig_Node_Expression_Constant(1, 0), + new \Twig_Node_Expression_Constant('tpl2', 0) + ), 0); + + $node = new FormThemeNode($form, $resources, 0); + + $compiler = new \Twig_Compiler(new \Twig_Environment()); + + $this->assertEquals( + sprintf( + 'echo $this->env->getExtension(\'form\')->setTheme(%s, array(0 => "tpl1", 1 => "tpl2"));', + $this->getVariableGetter('form') + ), + trim($compiler->compile($node)->getSource()) + ); + + $resources = new \Twig_Node_Expression_Constant('tpl1', 0); + + $node = new FormThemeNode($form, $resources, 0); + + $this->assertEquals( + sprintf( + 'echo $this->env->getExtension(\'form\')->setTheme(%s, "tpl1");', + $this->getVariableGetter('form') + ), + trim($compiler->compile($node)->getSource()) + ); + } + + protected function getVariableGetter($name) + { + if (version_compare(phpversion(), '5.4.0RC1', '>=')) { + return sprintf('(isset($context["%s"]) ? $context["%s"] : null)', $name, $name); + } + + return sprintf('$this->getContext($context, "%s")', $name); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/TestCase.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/TestCase.php new file mode 100644 index 0000000..ecfb7da --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/TestCase.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\Bridge\Twig\Tests; + +abstract class TestCase extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Twig_Environment')) { + $this->markTestSkipped('Twig is not available.'); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/TokenParser/FormThemeTokenParserTest.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/TokenParser/FormThemeTokenParserTest.php new file mode 100644 index 0000000..077cd76 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/TokenParser/FormThemeTokenParserTest.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\Bridge\Twig\Tests\Node; + +use Symfony\Bridge\Twig\Tests\TestCase; +use Symfony\Bridge\Twig\TokenParser\FormThemeTokenParser; +use Symfony\Bridge\Twig\Node\FormThemeNode; + +class FormThemeTokenParserTest extends TestCase +{ + protected function setUp() + { + parent::setUp(); + + if (version_compare(\Twig_Environment::VERSION, '1.5.0', '<')) { + $this->markTestSkipped('Requires Twig version to be at least 1.5.0.'); + } + } + + /** + * @dataProvider getTestsForFormTheme + */ + public function testCompile($source, $expected) + { + $env = new \Twig_Environment(new \Twig_Loader_String(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0)); + $env->addTokenParser(new FormThemeTokenParser()); + $stream = $env->tokenize($source); + $parser = new \Twig_Parser($env); + + $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)); + } + + public function getTestsForFormTheme() + { + return array( + array( + '{% form_theme form "tpl1" %}', + new FormThemeNode( + new \Twig_Node_Expression_Name('form', 1), + new \Twig_Node_Expression_Array(array( + new \Twig_Node_Expression_Constant(0, 1), + new \Twig_Node_Expression_Constant('tpl1', 1), + ), 1), + 1, + 'form_theme' + ) + ), + array( + '{% form_theme form "tpl1" "tpl2" %}', + new FormThemeNode( + new \Twig_Node_Expression_Name('form', 1), + new \Twig_Node_Expression_Array(array( + new \Twig_Node_Expression_Constant(0, 1), + new \Twig_Node_Expression_Constant('tpl1', 1), + new \Twig_Node_Expression_Constant(1, 1), + new \Twig_Node_Expression_Constant('tpl2', 1) + ), 1), + 1, + 'form_theme' + ) + ), + array( + '{% form_theme form with "tpl1" %}', + new FormThemeNode( + new \Twig_Node_Expression_Name('form', 1), + new \Twig_Node_Expression_Constant('tpl1', 1), + 1, + 'form_theme' + ) + ), + array( + '{% form_theme form with ["tpl1"] %}', + new FormThemeNode( + new \Twig_Node_Expression_Name('form', 1), + new \Twig_Node_Expression_Array(array( + new \Twig_Node_Expression_Constant(0, 1), + new \Twig_Node_Expression_Constant('tpl1', 1), + ), 1), + 1, + 'form_theme' + ) + ), + array( + '{% form_theme form with ["tpl1", "tpl2"] %}', + new FormThemeNode( + new \Twig_Node_Expression_Name('form', 1), + new \Twig_Node_Expression_Array(array( + new \Twig_Node_Expression_Constant(0, 1), + new \Twig_Node_Expression_Constant('tpl1', 1), + new \Twig_Node_Expression_Constant(1, 1), + new \Twig_Node_Expression_Constant('tpl2', 1) + ), 1), + 1, + 'form_theme' + ) + ), + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Translation/TwigExtractorTest.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Translation/TwigExtractorTest.php new file mode 100644 index 0000000..2d6ffdf --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Translation/TwigExtractorTest.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\Bridge\Twig\Tests\Translation; + +use Symfony\Bridge\Twig\Extension\TranslationExtension; +use Symfony\Bridge\Twig\Translation\TwigExtractor; +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Bridge\Twig\Tests\TestCase; + +class TwigExtractorTest extends TestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\Translation\Translator')) { + $this->markTestSkipped('The "Translation" component is not available'); + } + } + + /** + * @dataProvider getExtractData + */ + public function testExtract($template, $messages) + { + $loader = new \Twig_Loader_Array(array()); + $twig = new \Twig_Environment($loader, array( + 'strict_variables' => true, + 'debug' => true, + 'cache' => false, + 'autoescape' => false, + )); + $twig->addExtension(new TranslationExtension($this->getMock('Symfony\Component\Translation\TranslatorInterface'))); + + $extractor = new TwigExtractor($twig); + $extractor->setPrefix('prefix'); + $catalogue = new MessageCatalogue('en'); + + $m = new \ReflectionMethod($extractor, 'extractTemplate'); + $m->setAccessible(true); + $m->invoke($extractor, $template, $catalogue); + + foreach ($messages as $key => $domain) { + $this->assertTrue($catalogue->has($key, $domain)); + $this->assertEquals('prefix'.$key, $catalogue->get($key, $domain)); + } + } + + public function getExtractData() + { + return array( + array('{{ "new key" | trans() }}', array('new key' => 'messages')), + array('{{ "new key" | trans() | upper }}', array('new key' => 'messages')), + array('{{ "new key" | trans({}, "domain") }}', array('new key' => 'domain')), + array('{{ "new key" | transchoice(1) }}', array('new key' => 'messages')), + array('{{ "new key" | transchoice(1) | upper }}', array('new key' => 'messages')), + array('{{ "new key" | transchoice(1, {}, "domain") }}', array('new key' => 'domain')), + array('{% trans %}new key{% endtrans %}', array('new key' => 'messages')), + array('{% trans from "domain" %}new key{% endtrans %}', array('new key' => 'domain')), + array('{% set foo = "new key" | trans %}', array('new key' => 'messages')), + array('{{ 1 ? "new key" | trans : "another key" | trans }}', array('new key' => 'messages', 'another key' => 'messages')), + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/bootstrap.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/bootstrap.php new file mode 100644 index 0000000..dffd6eb --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/bootstrap.php @@ -0,0 +1,14 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (file_exists($loader = __DIR__.'/../vendor/autoload.php')) { + require_once $loader; +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/TokenParser/FormThemeTokenParser.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/TokenParser/FormThemeTokenParser.php new file mode 100644 index 0000000..244d676 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/TokenParser/FormThemeTokenParser.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\Bridge\Twig\TokenParser; + +use Symfony\Bridge\Twig\Node\FormThemeNode; + +/** + * Token Parser for the 'form_theme' tag. + * + * @author Fabien Potencier + */ +class FormThemeTokenParser extends \Twig_TokenParser +{ + /** + * Parses a token and returns a node. + * + * @param \Twig_Token $token A Twig_Token instance + * + * @return \Twig_NodeInterface A Twig_NodeInterface instance + */ + public function parse(\Twig_Token $token) + { + $lineno = $token->getLine(); + $stream = $this->parser->getStream(); + + $form = $this->parser->getExpressionParser()->parseExpression(); + + if ($this->parser->getStream()->test(\Twig_Token::NAME_TYPE, 'with')) { + $this->parser->getStream()->next(); + $resources = $this->parser->getExpressionParser()->parseExpression(); + } else { + $resources = new \Twig_Node_Expression_Array(array(), $stream->getCurrent()->getLine()); + do { + $resources->addElement($this->parser->getExpressionParser()->parseExpression()); + } while (!$stream->test(\Twig_Token::BLOCK_END_TYPE)); + } + + $stream->expect(\Twig_Token::BLOCK_END_TYPE); + + return new FormThemeNode($form, $resources, $lineno, $this->getTag()); + } + + /** + * Gets the tag name associated with this token parser. + * + * @return string The tag name + */ + public function getTag() + { + return 'form_theme'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/TokenParser/TransChoiceTokenParser.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/TokenParser/TransChoiceTokenParser.php new file mode 100644 index 0000000..872bd2e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/TokenParser/TransChoiceTokenParser.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\Bridge\Twig\TokenParser; + +use Symfony\Bridge\Twig\Node\TransNode; + +/** + * Token Parser for the 'transchoice' tag. + * + * @author Fabien Potencier + */ +class TransChoiceTokenParser extends TransTokenParser +{ + /** + * Parses a token and returns a node. + * + * @param \Twig_Token $token A Twig_Token instance + * + * @return \Twig_NodeInterface A Twig_NodeInterface instance + */ + public function parse(\Twig_Token $token) + { + $lineno = $token->getLine(); + $stream = $this->parser->getStream(); + + $vars = new \Twig_Node_Expression_Array(array(), $lineno); + + $count = $this->parser->getExpressionParser()->parseExpression(); + + $domain = null; + $locale = null; + + if ($stream->test('with')) { + // {% transchoice count with vars %} + $stream->next(); + $vars = $this->parser->getExpressionParser()->parseExpression(); + } + + if ($stream->test('from')) { + // {% transchoice count from "messages" %} + $stream->next(); + $domain = $this->parser->getExpressionParser()->parseExpression(); + } + + if ($stream->test('into')) { + // {% transchoice count into "fr" %} + $stream->next(); + $locale = $this->parser->getExpressionParser()->parseExpression(); + } + + $stream->expect(\Twig_Token::BLOCK_END_TYPE); + + $body = $this->parser->subparse(array($this, 'decideTransChoiceFork'), true); + + if (!$body instanceof \Twig_Node_Text && !$body instanceof \Twig_Node_Expression) { + throw new \Twig_Error_Syntax('A message must be a simple text.'); + } + + $stream->expect(\Twig_Token::BLOCK_END_TYPE); + + return new TransNode($body, $domain, $count, $vars, $locale, $lineno, $this->getTag()); + } + + public function decideTransChoiceFork($token) + { + return $token->test(array('endtranschoice')); + } + + /** + * Gets the tag name associated with this token parser. + * + * @return string The tag name + */ + public function getTag() + { + return 'transchoice'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/TokenParser/TransDefaultDomainTokenParser.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/TokenParser/TransDefaultDomainTokenParser.php new file mode 100644 index 0000000..0a0ed55 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/TokenParser/TransDefaultDomainTokenParser.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\Bridge\Twig\TokenParser; + +use Symfony\Bridge\Twig\Node\TransDefaultDomainNode; + +/** + * Token Parser for the 'trans_default_domain' tag. + * + * @author Fabien Potencier + */ +class TransDefaultDomainTokenParser extends \Twig_TokenParser +{ + /** + * Parses a token and returns a node. + * + * @param \Twig_Token $token A Twig_Token instance + * + * @return \Twig_NodeInterface A Twig_NodeInterface instance + */ + public function parse(\Twig_Token $token) + { + $expr = $this->parser->getExpressionParser()->parseExpression(); + + $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE); + + return new TransDefaultDomainNode($expr, $token->getLine(), $this->getTag()); + } + + /** + * Gets the tag name associated with this token parser. + * + * @return string The tag name + */ + public function getTag() + { + return 'trans_default_domain'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/TokenParser/TransTokenParser.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/TokenParser/TransTokenParser.php new file mode 100644 index 0000000..082c4a4 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/TokenParser/TransTokenParser.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\Bridge\Twig\TokenParser; + +use Symfony\Bridge\Twig\Node\TransNode; + +/** + * Token Parser for the 'trans' tag. + * + * @author Fabien Potencier + */ +class TransTokenParser extends \Twig_TokenParser +{ + /** + * Parses a token and returns a node. + * + * @param \Twig_Token $token A Twig_Token instance + * + * @return \Twig_NodeInterface A Twig_NodeInterface instance + */ + public function parse(\Twig_Token $token) + { + $lineno = $token->getLine(); + $stream = $this->parser->getStream(); + + $vars = new \Twig_Node_Expression_Array(array(), $lineno); + $domain = null; + $locale = null; + if (!$stream->test(\Twig_Token::BLOCK_END_TYPE)) { + if ($stream->test('with')) { + // {% trans with vars %} + $stream->next(); + $vars = $this->parser->getExpressionParser()->parseExpression(); + } + + if ($stream->test('from')) { + // {% trans from "messages" %} + $stream->next(); + $domain = $this->parser->getExpressionParser()->parseExpression(); + } + + if ($stream->test('into')) { + // {% trans into "fr" %} + $stream->next(); + $locale = $this->parser->getExpressionParser()->parseExpression(); + } elseif (!$stream->test(\Twig_Token::BLOCK_END_TYPE)) { + throw new \Twig_Error_Syntax('Unexpected token. Twig was looking for the "with" or "from" keyword.'); + } + } + + // {% trans %}message{% endtrans %} + $stream->expect(\Twig_Token::BLOCK_END_TYPE); + $body = $this->parser->subparse(array($this, 'decideTransFork'), true); + + if (!$body instanceof \Twig_Node_Text && !$body instanceof \Twig_Node_Expression) { + throw new \Twig_Error_Syntax('A message inside a trans tag must be a simple text'); + } + + $stream->expect(\Twig_Token::BLOCK_END_TYPE); + + return new TransNode($body, $domain, null, $vars, $locale, $lineno, $this->getTag()); + } + + public function decideTransFork($token) + { + return $token->test(array('endtrans')); + } + + /** + * Gets the tag name associated with this token parser. + * + * @return string The tag name + */ + public function getTag() + { + return 'trans'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php new file mode 100644 index 0000000..b1dc386 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Twig\Translation; + +use Symfony\Component\Finder\Finder; +use Symfony\Component\Translation\Extractor\ExtractorInterface; +use Symfony\Component\Translation\MessageCatalogue; + +/** + * TwigExtractor extracts translation messages from a twig template. + * + * @author Michel Salib + * @author Fabien Potencier + */ +class TwigExtractor implements ExtractorInterface +{ + /** + * Default domain for found messages. + * + * @var string + */ + private $defaultDomain = 'messages'; + + /** + * Prefix for found message. + * + * @var string + */ + private $prefix = ''; + + /** + * The twig environment. + * @var \Twig_Environment + */ + private $twig; + + public function __construct(\Twig_Environment $twig) + { + $this->twig = $twig; + } + + /** + * {@inheritDoc} + */ + public function extract($directory, MessageCatalogue $catalogue) + { + // load any existing translation files + $finder = new Finder(); + $files = $finder->files()->name('*.twig')->in($directory); + foreach ($files as $file) { + $this->extractTemplate(file_get_contents($file->getPathname()), $catalogue); + } + } + + /** + * {@inheritDoc} + */ + public function setPrefix($prefix) + { + $this->prefix = $prefix; + } + + protected function extractTemplate($template, MessageCatalogue $catalogue) + { + $visitor = $this->twig->getExtension('translator')->getTranslationNodeVisitor(); + $visitor->enable(); + + $this->twig->parse($this->twig->tokenize($template)); + + foreach ($visitor->getMessages() as $message) { + $catalogue->set($message[0], $this->prefix.$message[0], $message[1] ? $message[1] : $this->defaultDomain); + } + + $visitor->disable(); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/TwigEngine.php b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/TwigEngine.php new file mode 100644 index 0000000..955d4e0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/TwigEngine.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\Bridge\Twig; + +use Symfony\Component\Templating\EngineInterface; +use Symfony\Component\Templating\StreamingEngineInterface; +use Symfony\Component\Templating\TemplateNameParserInterface; + +/** + * This engine knows how to render Twig templates. + * + * @author Fabien Potencier + */ +class TwigEngine implements EngineInterface, StreamingEngineInterface +{ + protected $environment; + protected $parser; + + /** + * Constructor. + * + * @param \Twig_Environment $environment A \Twig_Environment instance + * @param TemplateNameParserInterface $parser A TemplateNameParserInterface instance + */ + public function __construct(\Twig_Environment $environment, TemplateNameParserInterface $parser) + { + $this->environment = $environment; + $this->parser = $parser; + } + + /** + * Renders a template. + * + * @param mixed $name A template name + * @param array $parameters An array of parameters to pass to the template + * + * @return string The evaluated template as a string + * + * @throws \InvalidArgumentException if the template does not exist + * @throws \RuntimeException if the template cannot be rendered + */ + public function render($name, array $parameters = array()) + { + return $this->load($name)->render($parameters); + } + + /** + * Streams a template. + * + * @param mixed $name A template name or a TemplateReferenceInterface instance + * @param array $parameters An array of parameters to pass to the template + * + * @throws \RuntimeException if the template cannot be rendered + */ + public function stream($name, array $parameters = array()) + { + $this->load($name)->display($parameters); + } + + /** + * Returns true if the template exists. + * + * @param mixed $name A template name + * + * @return Boolean true if the template exists, false otherwise + */ + public function exists($name) + { + try { + $this->load($name); + } catch (\InvalidArgumentException $e) { + return false; + } + + return true; + } + + /** + * Returns true if this class is able to render the given template. + * + * @param string $name A template name + * + * @return Boolean True if this class supports the given resource, false otherwise + */ + public function supports($name) + { + if ($name instanceof \Twig_Template) { + return true; + } + + $template = $this->parser->parse($name); + + return 'twig' === $template->get('engine'); + } + + /** + * Loads the given template. + * + * @param mixed $name A template name or an instance of Twig_Template + * + * @return \Twig_TemplateInterface A \Twig_TemplateInterface instance + * + * @throws \InvalidArgumentException if the template does not exist + */ + protected function load($name) + { + if ($name instanceof \Twig_Template) { + return $name; + } + + try { + return $this->environment->loadTemplate($name); + } catch (\Twig_Error_Loader $e) { + throw new \InvalidArgumentException($e->getMessage(), $e->getCode(), $e); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/composer.json b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/composer.json new file mode 100644 index 0000000..5635912 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/composer.json @@ -0,0 +1,47 @@ +{ + "name": "symfony/twig-bridge", + "type": "symfony-bridge", + "description": "Symfony Twig Bridge", + "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", + "twig/twig": ">=1.8,<2.0-dev" + }, + "require-dev": { + "symfony/form": "2.1.*", + "symfony/routing": "2.1.*", + "symfony/templating": "2.1.*", + "symfony/translation": "2.1.*", + "symfony/yaml": "2.1.*", + "symfony/security": "2.1.*" + }, + "suggest": { + "symfony/form": "self.version", + "symfony/routing": "self.version", + "symfony/templating": "self.version", + "symfony/translation": "self.version", + "symfony/yaml": "self.version", + "symfony/security": "self.version" + }, + "autoload": { + "psr-0": { "Symfony\\Bridge\\Twig": "" } + }, + "target-dir": "Symfony/Bridge/Twig", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bridge/Twig/phpunit.xml.dist b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/phpunit.xml.dist new file mode 100644 index 0000000..f0f8181 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bridge/Twig/phpunit.xml.dist @@ -0,0 +1,30 @@ + + + + + + ./Tests/ + + + + + + ./ + + ./Resources + ./Tests + ./vendor + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md new file mode 100644 index 0000000..4a28859 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -0,0 +1,34 @@ +CHANGELOG +========= + +2.1.0 +----- + + * moved the translation files to the Form and Validator components + * changed the default extension for XLIFF files from .xliff to .xlf + * moved Symfony\Bundle\FrameworkBundle\ContainerAwareEventDispatcher to Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher + * moved Symfony\Bundle\FrameworkBundle\Debug\TraceableEventDispatcher to Symfony\Component\EventDispatcher\ContainerAwareTraceableEventDispatcher + * added a router:match command + * added a config:dump-reference command + * added a server:run command + * added kernel.event_subscriber tag + * added a way to create relative symlinks when running assets:install command (--relative option) + * added Controller::getUser() + * [BC BREAK] assets_base_urls and base_urls merging strategy has changed + * changed the default profiler storage to use the filesystem instead of SQLite + * added support for placeholders in route defaults and requirements (replaced + by the value set in the service container) + * added Filesystem component as a dependency + * added support for hinclude (use ``standalone: 'js'`` in render tag) + * session options: lifetime, path, domain, secure, httponly were deprecated. + Prefixed versions should now be used instead: cookie_lifetime, cookie_path, + cookie_domain, cookie_secure, cookie_httponly + * [BC BREAK] following session options: 'lifetime', 'path', 'domain', 'secure', + 'httponly' are now prefixed with cookie_ when dumped to the container + * Added `handler_id` configuration under `session` key to represent `session.handler` + service, defaults to `session.handler.file`. + * Added `gc_maxlifetime`, `gc_probability`, and `gc_divisor` to session + configuration. This means session garbage collection has a + `gc_probability`/`gc_divisor` chance of being run. The `gc_maxlifetime` defines + how long a session can idle for. It is different from cookie lifetime which + declares how long a cookie can be stored on the remote client. diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/RouterCacheWarmer.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/RouterCacheWarmer.php new file mode 100644 index 0000000..df7261b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/RouterCacheWarmer.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\Bundle\FrameworkBundle\CacheWarmer; + +use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface; +use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface; +use Symfony\Component\Routing\RouterInterface; + +/** + * Generates the router matcher and generator classes. + * + * @author Fabien Potencier + */ +class RouterCacheWarmer implements CacheWarmerInterface +{ + protected $router; + + /** + * Constructor. + * + * @param Router $router A Router instance + */ + public function __construct(RouterInterface $router) + { + $this->router = $router; + } + + /** + * Warms up the cache. + * + * @param string $cacheDir The cache directory + */ + public function warmUp($cacheDir) + { + if ($this->router instanceof WarmableInterface) { + $this->router->warmUp($cacheDir); + } + } + + /** + * Checks whether this warmer is optional or not. + * + * @return Boolean always true + */ + public function isOptional() + { + return true; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplateFinder.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplateFinder.php new file mode 100644 index 0000000..16675f4 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplateFinder.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\Bundle\FrameworkBundle\CacheWarmer; + +use Symfony\Component\HttpKernel\KernelInterface; +use Symfony\Component\Finder\Finder; +use Symfony\Bundle\FrameworkBundle\Templating\TemplateNameParser; +use Symfony\Component\HttpKernel\Bundle\BundleInterface; + +/** + * Finds all the templates. + * + * @author Victor Berchet + */ +class TemplateFinder implements TemplateFinderInterface +{ + private $kernel; + private $parser; + private $rootDir; + private $templates; + + /** + * Constructor. + * + * @param KernelInterface $kernel A KernelInterface instance + * @param TemplateNameParser $parser A TemplateNameParser instance + * @param string $rootDir The directory where global templates can be stored + */ + public function __construct(KernelInterface $kernel, TemplateNameParser $parser, $rootDir) + { + $this->kernel = $kernel; + $this->parser = $parser; + $this->rootDir = $rootDir; + } + + /** + * Find all the templates in the bundle and in the kernel Resources folder. + * + * @return array An array of templates of type TemplateReferenceInterface + */ + public function findAllTemplates() + { + if (null !== $this->templates) { + return $this->templates; + } + + $templates = array(); + + foreach ($this->kernel->getBundles() as $name => $bundle) { + $templates = array_merge($templates, $this->findTemplatesInBundle($bundle)); + } + + $templates = array_merge($templates, $this->findTemplatesInFolder($this->rootDir.'/views')); + + return $this->templates = $templates; + } + + /** + * Find templates in the given directory. + * + * @param string $dir The folder where to look for templates + * + * @return array An array of templates of type TemplateReferenceInterface + */ + private function findTemplatesInFolder($dir) + { + $templates = array(); + + if (is_dir($dir)) { + $finder = new Finder(); + foreach ($finder->files()->followLinks()->in($dir) as $file) { + $template = $this->parser->parseFromFilename($file->getRelativePathname()); + if (false !== $template) { + $templates[] = $template; + } + } + } + + return $templates; + } + + /** + * Find templates in the given bundle. + * + * @param BundleInterface $bundle The bundle where to look for templates + * + * @return array An array of templates of type TemplateReferenceInterface + */ + private function findTemplatesInBundle(BundleInterface $bundle) + { + $templates = $this->findTemplatesInFolder($bundle->getPath().'/Resources/views'); + $name = $bundle->getName(); + + foreach ($templates as $i => $template) { + $templates[$i] = $template->set('bundle', $name); + } + + return $templates; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplateFinderInterface.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplateFinderInterface.php new file mode 100644 index 0000000..a2ef3aa --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplateFinderInterface.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\Bundle\FrameworkBundle\CacheWarmer; + + +/** + * Interface for finding all the templates. + * + * @author Victor Berchet + */ +interface TemplateFinderInterface +{ + /** + * Find all the templates. + * + * @return array An array of templates of type TemplateReferenceInterface + */ + function findAllTemplates(); +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplatePathsCacheWarmer.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplatePathsCacheWarmer.php new file mode 100644 index 0000000..0936290 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplatePathsCacheWarmer.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\Bundle\FrameworkBundle\CacheWarmer; + +use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmer; +use Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateLocator; + +/** + * Computes the association between template names and their paths on the disk. + * + * @author Fabien Potencier + */ +class TemplatePathsCacheWarmer extends CacheWarmer +{ + protected $finder; + protected $locator; + + /** + * Constructor. + * + * @param TemplateFinderInterface $finder A template finder + * @param TemplateLocator $locator The template locator + */ + public function __construct(TemplateFinderInterface $finder, TemplateLocator $locator) + { + $this->finder = $finder; + $this->locator = $locator; + } + + /** + * Warms up the cache. + * + * @param string $cacheDir The cache directory + */ + public function warmUp($cacheDir) + { + $templates = array(); + + foreach ($this->finder->findAllTemplates() as $template) { + $templates[$template->getLogicalName()] = $this->locator->locate($template); + } + + $this->writeCacheFile($cacheDir.'/templates.php', sprintf(' + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\Client as BaseClient; +use Symfony\Component\HttpKernel\Profiler\Profile as HttpProfile; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +/** + * Client simulates a browser and makes requests to a Kernel object. + * + * @author Fabien Potencier + */ +class Client extends BaseClient +{ + private $hasPerformedRequest = false; + + /** + * Returns the container. + * + * @return ContainerInterface + */ + public function getContainer() + { + return $this->kernel->getContainer(); + } + + /** + * Returns the kernel. + * + * @return HttpKernelInterface + */ + public function getKernel() + { + return $this->kernel; + } + + /** + * Gets the profile associated with the current Response. + * + * @return HttpProfile A Profile instance + */ + public function getProfile() + { + if (!$this->kernel->getContainer()->has('profiler')) { + return false; + } + + return $this->kernel->getContainer()->get('profiler')->loadProfileFromResponse($this->response); + } + + /** + * Makes a request. + * + * @param Request $request A Request instance + * + * @return Response A Response instance + */ + protected function doRequest($request) + { + // avoid shutting down the Kernel if no request has been performed yet + // WebTestCase::createClient() boots the Kernel but do not handle a request + if ($this->hasPerformedRequest) { + $this->kernel->shutdown(); + } else { + $this->hasPerformedRequest = true; + } + + return $this->kernel->handle($request); + } + + /** + * Returns the script to execute when the request must be insulated. + * + * @param Request $request A Request instance + * + * @return string The script content + */ + protected function getScript($request) + { + $kernel = str_replace("'", "\\'", serialize($this->kernel)); + $request = str_replace("'", "\\'", serialize($request)); + + $r = new \ReflectionObject($this->kernel); + $path = str_replace("'", "\\'", $r->getFileName()); + + return <<boot(); +echo serialize(\$kernel->handle(unserialize('$request'))); +EOF; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php new file mode 100644 index 0000000..bc145a2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.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\Bundle\FrameworkBundle\Command; + +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\Output\Output; +use Symfony\Component\Finder\Finder; + +/** + * Command that places bundle web assets into a given directory. + * + * @author Fabien Potencier + */ +class AssetsInstallCommand extends ContainerAwareCommand +{ + /** + * @see Command + */ + protected function configure() + { + $this + ->setName('assets:install') + ->setDefinition(array( + new InputArgument('target', InputArgument::REQUIRED, 'The target directory (usually "web")'), + )) + ->addOption('symlink', null, InputOption::VALUE_NONE, 'Symlinks the assets instead of copying it') + ->addOption('relative', null, InputOption::VALUE_NONE, 'Make relative symlinks') + ->setDescription('Installs bundles web assets under a public web directory') + ->setHelp(<<%command.name% command installs bundle assets into a given +directory (e.g. the web directory). + +php %command.full_name% web + +A "bundles" directory will be created inside the target directory, and the +"Resources/public" directory of each bundle will be copied into it. + +To create a symlink to each bundle instead of copying its assets, use the +--symlink option: + +php %command.full_name% web --symlink + +To make symlink relative, add the --relative option: + +php %command.full_name% web --symlink --relative + +EOT + ) + ; + } + + /** + * @see Command + * + * @throws \InvalidArgumentException When the target directory does not exist + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $targetArg = rtrim($input->getArgument('target'), '/'); + + if (!is_dir($targetArg)) { + throw new \InvalidArgumentException(sprintf('The target directory "%s" does not exist.', $input->getArgument('target'))); + } + + if (!function_exists('symlink') && $input->getOption('symlink')) { + throw new \InvalidArgumentException('The symlink() function is not available on your system. You need to install the assets without the --symlink option.'); + } + + $filesystem = $this->getContainer()->get('filesystem'); + + // Create the bundles directory otherwise symlink will fail. + $filesystem->mkdir($targetArg.'/bundles/', 0777); + + $output->writeln(sprintf("Installing assets using the %s option", $input->getOption('symlink') ? 'symlink' : 'hard copy')); + + foreach ($this->getContainer()->get('kernel')->getBundles() as $bundle) { + if (is_dir($originDir = $bundle->getPath().'/Resources/public')) { + $bundlesDir = $targetArg.'/bundles/'; + $targetDir = $bundlesDir.preg_replace('/bundle$/', '', strtolower($bundle->getName())); + + $output->writeln(sprintf('Installing assets for %s into %s', $bundle->getNamespace(), $targetDir)); + + $filesystem->remove($targetDir); + + if ($input->getOption('symlink')) { + if ($input->getOption('relative')) { + $relativeOriginDir = $filesystem->makePathRelative($originDir, realpath($bundlesDir)); + } else { + $relativeOriginDir = $originDir; + } + $filesystem->symlink($relativeOriginDir, $targetDir); + } else { + $filesystem->mkdir($targetDir, 0777); + // We use a custom iterator to ignore VCS files + $filesystem->mirror($originDir, $targetDir, Finder::create()->in($originDir)); + } + } + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php new file mode 100644 index 0000000..a9aa7a5 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.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\Bundle\FrameworkBundle\Command; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\HttpKernel\KernelInterface; +use Symfony\Component\Finder\Finder; + +/** + * Clear and Warmup the cache. + * + * @author Francis Besset + * @author Fabien Potencier + */ +class CacheClearCommand extends ContainerAwareCommand +{ + protected $name; + + /** + * @see Command + */ + protected function configure() + { + $this + ->setName('cache:clear') + ->setDefinition(array( + new InputOption('no-warmup', '', InputOption::VALUE_NONE, 'Do not warm up the cache'), + new InputOption('no-optional-warmers', '', InputOption::VALUE_NONE, 'Skip optional cache warmers (faster)'), + )) + ->setDescription('Clears the cache') + ->setHelp(<<%command.name% command clears the application cache for a given environment +and debug mode: + +php %command.full_name% --env=dev +php %command.full_name% --env=prod --no-debug +EOF + ) + ; + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $realCacheDir = $this->getContainer()->getParameter('kernel.cache_dir'); + $oldCacheDir = $realCacheDir.'_old'; + + if (!is_writable($realCacheDir)) { + throw new \RuntimeException(sprintf('Unable to write in the "%s" directory', $realCacheDir)); + } + + $kernel = $this->getContainer()->get('kernel'); + $output->writeln(sprintf('Clearing the cache for the %s environment with debug %s', $kernel->getEnvironment(), var_export($kernel->isDebug(), true))); + + $this->getContainer()->get('cache_clearer')->clear($realCacheDir); + + if ($input->getOption('no-warmup')) { + rename($realCacheDir, $oldCacheDir); + } else { + $warmupDir = $realCacheDir.'_new'; + + $this->warmup($warmupDir, !$input->getOption('no-optional-warmers')); + + rename($realCacheDir, $oldCacheDir); + rename($warmupDir, $realCacheDir); + } + + $this->getContainer()->get('filesystem')->remove($oldCacheDir); + } + + protected function warmup($warmupDir, $enableOptionalWarmers = true) + { + $this->getContainer()->get('filesystem')->remove($warmupDir); + + $parent = $this->getContainer()->get('kernel'); + $class = get_class($parent); + $namespace = ''; + if (false !== $pos = strrpos($class, '\\')) { + $namespace = substr($class, 0, $pos); + $class = substr($class, $pos + 1); + } + + $kernel = $this->getTempKernel($parent, $namespace, $class, $warmupDir); + $kernel->boot(); + + $warmer = $kernel->getContainer()->get('cache_warmer'); + + if ($enableOptionalWarmers) { + $warmer->enableOptionalWarmers(); + } + + $warmer->warmUp($warmupDir); + + // fix container files and classes + $regex = '/'.preg_quote($this->getTempKernelSuffix(), '/').'/'; + $finder = new Finder(); + foreach ($finder->files()->name(get_class($kernel->getContainer()).'*')->in($warmupDir) as $file) { + $content = file_get_contents($file); + $content = preg_replace($regex, '', $content); + + // fix absolute paths to the cache directory + $content = preg_replace('/'.preg_quote($warmupDir, '/').'/', preg_replace('/_new$/', '', $warmupDir), $content); + + file_put_contents(preg_replace($regex, '', $file), $content); + unlink($file); + } + + // fix meta references to the Kernel + foreach ($finder->files()->name('*.meta')->in($warmupDir) as $file) { + $content = preg_replace( + '/C\:\d+\:"'.preg_quote($class.$this->getTempKernelSuffix(), '"/').'"/', + sprintf('C:%s:"%s"', strlen($class), $class), + file_get_contents($file) + ); + file_put_contents($file, $content); + } + } + + protected function getTempKernelSuffix() + { + if (null === $this->name) { + $this->name = '__'.uniqid().'__'; + } + + return $this->name; + } + + protected function getTempKernel(KernelInterface $parent, $namespace, $class, $warmupDir) + { + $suffix = $this->getTempKernelSuffix(); + $rootDir = $parent->getRootDir(); + $code = <<getContainer()->get('filesystem')->mkdir($warmupDir); + file_put_contents($file = $warmupDir.'/kernel.tmp', $code); + require_once $file; + @unlink($file); + $class = "$namespace\\$class$suffix"; + + return new $class($parent->getEnvironment(), $parent->isDebug()); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/CacheWarmupCommand.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/CacheWarmupCommand.php new file mode 100644 index 0000000..e997e55 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/CacheWarmupCommand.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\Bundle\FrameworkBundle\Command; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Warmup the cache. + * + * @author Fabien Potencier + */ +class CacheWarmupCommand extends ContainerAwareCommand +{ + /** + * @see Command + */ + protected function configure() + { + $this + ->setName('cache:warmup') + ->setDefinition(array( + new InputOption('no-optional-warmers', '', InputOption::VALUE_NONE, 'Skip optional cache warmers (faster)'), + )) + ->setDescription('Warms up an empty cache') + ->setHelp(<<%command.name% command warms up the cache. + +Before running this command, the cache must be empty. +EOF + ) + ; + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $kernel = $this->getContainer()->get('kernel'); + $output->writeln(sprintf('Warming up the cache for the %s environment with debug %s', $kernel->getEnvironment(), var_export($kernel->isDebug(), true))); + + $warmer = $this->getContainer()->get('cache_warmer'); + + if (!$input->getOption('no-optional-warmers')) { + $warmer->enableOptionalWarmers(); + } + + $warmer->warmUp($this->getContainer()->getParameter('kernel.cache_dir')); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php new file mode 100644 index 0000000..5d9d06b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php @@ -0,0 +1,259 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Command; + +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Config\Definition\NodeInterface; +use Symfony\Component\Config\Definition\ArrayNode; +use Symfony\Component\Config\Definition\PrototypedArrayNode; + +/** + * A console command for dumping available configuration reference + * + * @author Kevin Bond + */ +class ConfigDumpReferenceCommand extends ContainerDebugCommand +{ + protected $output; + + /** + * @see Command + */ + protected function configure() + { + $this + ->setName('config:dump-reference') + ->setDefinition(array( + new InputArgument('name', InputArgument::REQUIRED, 'The Bundle or extension alias') + )) + ->setDescription('Dumps default configuration for an extension') + ->setHelp(<<%command.name% command dumps the default configuration for an extension/bundle. + +The extension alias or bundle name can be used: + +Example: + + php %command.full_name% framework + +or + + php %command.full_name% FrameworkBundle +EOF + ) + ; + } + + /** + * @see Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->output = $output; + $kernel = $this->getContainer()->get('kernel'); + $containerBuilder = $this->getContainerBuilder(); + + $name = $input->getArgument('name'); + + $extension = null; + + if (preg_match('/Bundle$/', $name)) { + // input is bundle name + $extension = $kernel->getBundle($name)->getContainerExtension(); + + if (!$extension) { + throw new \LogicException('No extensions with configuration available for "'.$name.'"'); + } + + $message = 'Default configuration for "'.$name.'"'; + } else { + foreach ($kernel->getBundles() as $bundle) { + $extension = $bundle->getContainerExtension(); + + if ($extension && $extension->getAlias() === $name) { + break; + } + + $extension = null; + } + + if (!$extension) { + throw new \LogicException('No extension with alias "'.$name.'" is enabled'); + } + + $message = 'Default configuration for extension with alias: "'.$name.'"'; + } + + $configuration = $extension->getConfiguration(array(), $containerBuilder); + + if (!$configuration) { + throw new \LogicException('The extension with alias "'.$extension->getAlias(). + '" does not have it\'s getConfiguration() method setup'); + } + + $rootNode = $configuration->getConfigTreeBuilder()->buildTree(); + + $output->writeln($message); + + // root node + $this->outputNode($rootNode); + } + + /** + * Outputs a single config reference line + * + * @param string $text + * @param int $indent + */ + private function outputLine($text, $indent = 0) + { + $indent = strlen($text) + $indent; + + $format = '%'.$indent.'s'; + + $this->output->writeln(sprintf($format, $text)); + } + + private function outputArray(array $array, $depth) + { + $isIndexed = array_values($array) === $array; + + foreach ($array as $key => $value) { + if (is_array($value)) { + $val = ''; + } else { + $val = $value; + } + + if ($isIndexed) { + $this->outputLine('- '.$val, $depth * 4); + } else { + $this->outputLine(sprintf('%-20s %s', $key.':', $val), $depth * 4); + } + + if (is_array($value)) { + $this->outputArray($value, $depth + 1); + } + } + } + + /** + * @param NodeInterface $node + * @param int $depth + */ + private function outputNode(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()) { + $keyNode = new ArrayNode($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 = '[]'; + } + } + } else { + $default = '~'; + + if ($node->hasDefaultValue()) { + $default = $node->getDefaultValue(); + + if (true === $default) { + $default = 'true'; + } elseif (false === $default) { + $default = 'false'; + } elseif (null === $default) { + $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 = sprintf('%-20s %s %s', $node->getName().':', $default, $comments); + + if ($info = $node->getInfo()) { + $this->outputLine(''); + $this->outputLine('# '.$info, $depth * 4); + } + + $this->outputLine($text, $depth * 4); + + // output defaults + if ($defaultArray) { + $this->outputLine(''); + + $message = count($defaultArray) > 1 ? 'Defaults' : 'Default'; + + $this->outputLine('# '.$message.':', $depth * 4 + 4); + + $this->outputArray($defaultArray, $depth + 1); + } + + if (is_array($example)) { + $this->outputLine(''); + + $message = count($example) > 1 ? 'Examples' : 'Example'; + + $this->outputLine('# '.$message.':', $depth * 4 + 4); + + $this->outputArray($example, $depth + 1); + } + + if ($children) { + foreach ($children as $childNode) { + $this->outputNode($childNode, $depth + 1); + } + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ContainerAwareCommand.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ContainerAwareCommand.php new file mode 100644 index 0000000..0540870 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ContainerAwareCommand.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\Bundle\FrameworkBundle\Command; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\ContainerAwareInterface; + +/** + * Command. + * + * @author Fabien Potencier + */ +abstract class ContainerAwareCommand extends Command implements ContainerAwareInterface +{ + /** + * @var ContainerInterface + */ + private $container; + + /** + * @return ContainerInterface + */ + protected function getContainer() + { + if (null === $this->container) { + $this->container = $this->getApplication()->getKernel()->getContainer(); + } + + return $this->container; + } + + /** + * @see ContainerAwareInterface::setContainer() + */ + public function setContainer(ContainerInterface $container = null) + { + $this->container = $container; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php new file mode 100644 index 0000000..dcfe53a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.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\Bundle\FrameworkBundle\Command; + +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\Output\Output; +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Config\FileLocator; + +/** + * A console command for retrieving information about services + * + * @author Ryan Weaver + */ +class ContainerDebugCommand extends ContainerAwareCommand +{ + /** + * @var ContainerBuilder + */ + private $containerBuilder; + + /** + * @see Command + */ + protected function configure() + { + $this + ->setName('container:debug') + ->setDefinition(array( + new InputArgument('name', InputArgument::OPTIONAL, 'A service name (foo)'), + new InputOption('show-private', null, InputOption::VALUE_NONE, 'Use to show public *and* private services'), + )) + ->setDescription('Displays current services for an application') + ->setHelp(<<%command.name% command displays all configured public services: + + php %command.full_name% + +To get specific information about a service, specify its name: + + php %command.full_name% validator + +By default, private services are hidden. You can display all services by +using the --show-private flag: + + php %command.full_name% --show-private +EOF + ) + ; + } + + /** + * @see Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $name = $input->getArgument('name'); + + $this->containerBuilder = $this->getContainerBuilder(); + $serviceIds = $this->containerBuilder->getServiceIds(); + + // sort so that it reads like an index of services + asort($serviceIds); + + if ($name) { + $this->outputService($output, $name); + } else { + $this->outputServices($output, $serviceIds, $input->getOption('show-private')); + } + } + + protected function outputServices(OutputInterface $output, $serviceIds, $showPrivate = false) + { + // set the label to specify public or public+private + if ($showPrivate) { + $label = 'Public and private services'; + } else { + $label = 'Public services'; + } + + $output->writeln($this->getHelper('formatter')->formatSection('container', $label)); + + // loop through to get space needed and filter private services + $maxName = 4; + $maxScope = 6; + foreach ($serviceIds as $key => $serviceId) { + $definition = $this->resolveServiceDefinition($serviceId); + + if ($definition instanceof Definition) { + // filter out private services unless shown explicitly + if (!$showPrivate && !$definition->isPublic()) { + unset($serviceIds[$key]); + continue; + } + + if (strlen($definition->getScope()) > $maxScope) { + $maxScope = strlen($definition->getScope()); + } + } + + if (strlen($serviceId) > $maxName) { + $maxName = strlen($serviceId); + } + } + $format = '%-'.$maxName.'s %-'.$maxScope.'s %s'; + + // the title field needs extra space to make up for comment tags + $format1 = '%-'.($maxName + 19).'s %-'.($maxScope + 19).'s %s'; + $output->writeln(sprintf($format1, 'Service Id', 'Scope', 'Class Name')); + + foreach ($serviceIds as $serviceId) { + $definition = $this->resolveServiceDefinition($serviceId); + + if ($definition instanceof Definition) { + $output->writeln(sprintf($format, $serviceId, $definition->getScope(), $definition->getClass())); + } elseif ($definition instanceof Alias) { + $alias = $definition; + $output->writeln(sprintf($format, $serviceId, 'n/a', sprintf('alias for %s', (string) $alias))); + } else { + // we have no information (happens with "service_container") + $service = $definition; + $output->writeln(sprintf($format, $serviceId, '', get_class($service))); + } + } + } + + /** + * Renders detailed service information about one service + */ + protected function outputService(OutputInterface $output, $serviceId) + { + $definition = $this->resolveServiceDefinition($serviceId); + + $label = sprintf('Information for service %s', $serviceId); + $output->writeln($this->getHelper('formatter')->formatSection('container', $label)); + $output->writeln(''); + + if ($definition instanceof Definition) { + $output->writeln(sprintf('Service Id %s', $serviceId)); + $output->writeln(sprintf('Class %s', $definition->getClass())); + + $tags = $definition->getTags() ? implode(', ', array_keys($definition->getTags())) : '-'; + $output->writeln(sprintf('Tags %s', $tags)); + + $output->writeln(sprintf('Scope %s', $definition->getScope())); + + $public = $definition->isPublic() ? 'yes' : 'no'; + $output->writeln(sprintf('Public %s', $public)); + + $synthetic = $definition->isSynthetic() ? 'yes' : 'no'; + $output->writeln(sprintf('Synthetic %s', $synthetic)); + + $file = $definition->getFile() ? $definition->getFile() : '-'; + $output->writeln(sprintf('Required File %s', $file)); + } elseif ($definition instanceof Alias) { + $alias = $definition; + $output->writeln(sprintf('This service is an alias for the service %s', (string) $alias)); + } else { + // edge case (but true for "service_container", all we have is the service itself + $service = $definition; + $output->writeln(sprintf('Service Id %s', $serviceId)); + $output->writeln(sprintf('Class %s', get_class($service))); + } + } + + /** + * Loads the ContainerBuilder from the cache. + * + * @return ContainerBuilder + */ + protected function getContainerBuilder() + { + if (!$this->getApplication()->getKernel()->isDebug()) { + throw new \LogicException(sprintf('Debug information about the container is only available in debug mode.')); + } + + if (!is_file($cachedFile = $this->getContainer()->getParameter('debug.container.dump'))) { + throw new \LogicException(sprintf('Debug information about the container could not be found. Please clear the cache and try again.')); + } + + $container = new ContainerBuilder(); + + $loader = new XmlFileLoader($container, new FileLocator()); + $loader->load($cachedFile); + + return $container; + } + + /** + * Given an array of service IDs, this returns the array of corresponding + * Definition and Alias objects that those ids represent. + * + * @param string $serviceId The service id to resolve + * + * @return \Symfony\Component\DependencyInjection\Definition|\Symfony\Component\DependencyInjection\Alias + */ + private function resolveServiceDefinition($serviceId) + { + if ($this->containerBuilder->hasDefinition($serviceId)) { + return $this->containerBuilder->getDefinition($serviceId); + } + + // Some service IDs don't have a Definition, they're simply an Alias + if ($this->containerBuilder->hasAlias($serviceId)) { + return $this->containerBuilder->getAlias($serviceId); + } + + // the service has been injected in some special way, just return the service + return $this->containerBuilder->get($serviceId); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/RouterApacheDumperCommand.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/RouterApacheDumperCommand.php new file mode 100644 index 0000000..12fe9b0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/RouterApacheDumperCommand.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\Bundle\FrameworkBundle\Command; + +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\Routing\Matcher\Dumper\ApacheMatcherDumper; +use Symfony\Component\Routing\RouterInterface; + +/** + * RouterApacheDumperCommand. + * + * @author Fabien Potencier + */ +class RouterApacheDumperCommand extends ContainerAwareCommand +{ + /** + * {@inheritDoc} + */ + public function isEnabled() + { + if (!$this->getContainer()->has('router')) { + return false; + } + $router = $this->getContainer()->get('router'); + if (!$router instanceof RouterInterface) { + return false; + } + + return parent::isEnabled(); + } + + /** + * @see Command + */ + protected function configure() + { + $this + ->setName('router:dump-apache') + ->setDefinition(array( + new InputArgument('script_name', InputArgument::OPTIONAL, 'The script name of the application\'s front controller.'), + new InputOption('base-uri', null, InputOption::VALUE_REQUIRED, 'The base URI'), + )) + ->setDescription('Dumps all routes as Apache rewrite rules') + ->setHelp(<<%command.name% dumps all routes as Apache rewrite rules. +These can then be used with the ApacheUrlMatcher to use Apache for route +matching. + + php %command.full_name% +EOF + ) + ; + } + + /** + * @see Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $router = $this->getContainer()->get('router'); + + $dumpOptions = array(); + if ($input->getArgument('script_name')) { + $dumpOptions['script_name'] = $input->getArgument('script_name'); + } + if ($input->getOption('base-uri')) { + $dumpOptions['base_uri'] = $input->getOption('base-uri'); + } + + $dumper = new ApacheMatcherDumper($router->getRouteCollection()); + + $output->writeln($dumper->dump($dumpOptions), OutputInterface::OUTPUT_RAW); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php new file mode 100644 index 0000000..dd4f5c5 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php @@ -0,0 +1,176 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Command; + +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Routing\RouterInterface; +use Symfony\Component\Console\Output\Output; + +/** + * A console command for retrieving information about routes + * + * @author Fabien Potencier + */ +class RouterDebugCommand extends ContainerAwareCommand +{ + /** + * {@inheritDoc} + */ + public function isEnabled() + { + if (!$this->getContainer()->has('router')) { + return false; + } + $router = $this->getContainer()->get('router'); + if (!$router instanceof RouterInterface) { + return false; + } + + return parent::isEnabled(); + } + + /** + * @see Command + */ + protected function configure() + { + $this + ->setName('router:debug') + ->setDefinition(array( + new InputArgument('name', InputArgument::OPTIONAL, 'A route name'), + )) + ->setDescription('Displays current routes for an application') + ->setHelp(<<%command.name% displays the configured routes: + + php %command.full_name% +EOF + ) + ; + } + + /** + * @see Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $name = $input->getArgument('name'); + + if ($name) { + $this->outputRoute($output, $name); + } else { + $this->outputRoutes($output); + } + } + + protected function outputRoutes(OutputInterface $output) + { + $routes = array(); + foreach ($this->getContainer()->get('router')->getRouteCollection()->all() as $name => $route) { + $routes[$name] = $route->compile(); + } + + $output->writeln($this->getHelper('formatter')->formatSection('router', 'Current routes')); + + $maxName = 4; + $maxMethod = 6; + foreach ($routes as $name => $route) { + $requirements = $route->getRequirements(); + $method = isset($requirements['_method']) + ? strtoupper(is_array($requirements['_method']) + ? implode(', ', $requirements['_method']) : $requirements['_method'] + ) + : 'ANY'; + + if (strlen($name) > $maxName) { + $maxName = strlen($name); + } + + if (strlen($method) > $maxMethod) { + $maxMethod = strlen($method); + } + } + $format = '%-'.$maxName.'s %-'.$maxMethod.'s %s'; + + // displays the generated routes + $format1 = '%-'.($maxName + 19).'s %-'.($maxMethod + 19).'s %s'; + $output->writeln(sprintf($format1, 'Name', 'Method', 'Pattern')); + foreach ($routes as $name => $route) { + $requirements = $route->getRequirements(); + $method = isset($requirements['_method']) + ? strtoupper(is_array($requirements['_method']) + ? implode(', ', $requirements['_method']) : $requirements['_method'] + ) + : 'ANY'; + $output->writeln(sprintf($format, $name, $method, $route->getPattern())); + } + } + + /** + * @throws \InvalidArgumentException When route does not exist + */ + protected function outputRoute(OutputInterface $output, $name) + { + $route = $this->getContainer()->get('router')->getRouteCollection()->get($name); + if (!$route) { + throw new \InvalidArgumentException(sprintf('The route "%s" does not exist.', $name)); + } + + $output->writeln($this->getHelper('formatter')->formatSection('router', sprintf('Route "%s"', $name))); + + $route = $route->compile(); + $output->writeln(sprintf('Name %s', $name)); + $output->writeln(sprintf('Pattern %s', $route->getPattern())); + $output->writeln(sprintf('Class %s', get_class($route))); + + $defaults = ''; + $d = $route->getDefaults(); + ksort($d); + foreach ($d as $name => $value) { + $defaults .= ($defaults ? "\n".str_repeat(' ', 13) : '').$name.': '.$this->formatValue($value); + } + $output->writeln(sprintf('Defaults %s', $defaults)); + + $requirements = ''; + $r = $route->getRequirements(); + ksort($r); + foreach ($r as $name => $value) { + $requirements .= ($requirements ? "\n".str_repeat(' ', 13) : '').$name.': '.$this->formatValue($value); + } + $output->writeln(sprintf('Requirements %s', $requirements)); + + $options = ''; + $o = $route->getOptions(); + ksort($o); + foreach ($o as $name => $value) { + $options .= ($options ? "\n".str_repeat(' ', 13) : '').$name.': '.$this->formatValue($value); + } + $output->writeln(sprintf('Options %s', $options)); + $output->write('Regex '); + $output->writeln(preg_replace('/^ /', '', preg_replace('/^/m', ' ', $route->getRegex())), OutputInterface::OUTPUT_RAW); + } + + protected function formatValue($value) + { + if (is_object($value)) { + return sprintf('object(%s)', get_class($value)); + } + + if (is_string($value)) { + return $value; + } + + return preg_replace("/\n\s*/s", '', var_export($value, true)); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/RouterMatchCommand.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/RouterMatchCommand.php new file mode 100644 index 0000000..a6b4b08 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/RouterMatchCommand.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\Bundle\FrameworkBundle\Command; + +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Routing\RouterInterface; +use Symfony\Component\Routing\Matcher\TraceableUrlMatcher; + +/** + * A console command to test route matching. + * + * @author Fabien Potencier + */ +class RouterMatchCommand extends ContainerAwareCommand +{ + /** + * {@inheritDoc} + */ + public function isEnabled() + { + if (!$this->getContainer()->has('router')) { + return false; + } + $router = $this->getContainer()->get('router'); + if (!$router instanceof RouterInterface) { + return false; + } + + return parent::isEnabled(); + } + + /** + * @see Command + */ + protected function configure() + { + $this + ->setName('router:match') + ->setDefinition(array( + new InputArgument('path_info', InputArgument::REQUIRED, 'A path info'), + )) + ->setDescription('Helps debug routes by simulating a path info match') + ->setHelp(<<%command.name% simulates a path info match: + + php %command.full_name% /foo +EOF + ) + ; + } + + /** + * @see Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $router = $this->getContainer()->get('router'); + $matcher = new TraceableUrlMatcher($router->getRouteCollection(), $router->getContext()); + + $traces = $matcher->getTraces($input->getArgument('path_info')); + + $matches = false; + foreach ($traces as $i => $trace) { + if (TraceableUrlMatcher::ROUTE_ALMOST_MATCHES == $trace['level']) { + $output->writeln(sprintf('Route "%s" almost matches but %s', $trace['name'], lcfirst($trace['log']))); + } elseif (TraceableUrlMatcher::ROUTE_MATCHES == $trace['level']) { + $output->writeln(sprintf('Route "%s" matches', $trace['name'])); + $matches = true; + } elseif ($input->getOption('verbose')) { + $output->writeln(sprintf('Route "%s" does not match: %s', $trace['name'], $trace['log'])); + } + } + + if (!$matches) { + $output->writeln('None of the routes matches'); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ServerRunCommand.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ServerRunCommand.php new file mode 100644 index 0000000..446db90 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ServerRunCommand.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\Bundle\FrameworkBundle\Command; + +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\Process\ProcessBuilder; + +/** + * Runs Symfony2 application using PHP built-in web server + * + * @author Michał Pipa + */ +class ServerRunCommand extends ContainerAwareCommand +{ + /** + * {@inheritDoc} + */ + public function isEnabled() + { + if (version_compare(phpversion(), '5.4.0', '<')) { + return false; + } + + return parent::isEnabled(); + } + + /** + * @see Command + */ + protected function configure() + { + $this + ->setDefinition(array( + new InputArgument('address', InputArgument::OPTIONAL, 'Address:port', 'localhost:8000'), + new InputOption('docroot', 'd', InputOption::VALUE_REQUIRED, 'Document root', 'web/'), + new InputOption('router', 'r', InputOption::VALUE_REQUIRED, 'Path to custom router script'), + )) + ->setName('server:run') + ->setDescription('Runs PHP built-in web server') + ->setHelp(<<%command.name% runs PHP built-in web server: + + %command.full_name% + +To change default bind address and port use the address argument: + + %command.full_name% 127.0.0.1:8080 + +To change default docroot directory use the --docroot option: + + %command.full_name% --docroot=htdocs/ + +If you have custom docroot directory layout, you can specify your own +router script using --router option: + + %command.full_name% --router=app/config/router.php + +See also: http://www.php.net/manual/en/features.commandline.webserver.php +EOF + ) + ; + } + + /** + * @see Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $router = $input->getOption('router') ?: $this + ->getContainer() + ->get('kernel') + ->locateResource('@FrameworkBundle/Resources/config/router.php') + ; + + $output->writeln(sprintf("Server running on %s\n", $input->getArgument('address'))); + + $builder = new ProcessBuilder(array(PHP_BINARY, '-S', $input->getArgument('address'), $router)); + $builder->setWorkingDirectory($input->getOption('docroot')); + $builder->setTimeout(null); + $builder->getProcess()->run(function ($type, $buffer) use ($output) { + if (OutputInterface::VERBOSITY_VERBOSE === $output->getVerbosity()) { + $output->write($buffer); + } + }); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php new file mode 100644 index 0000000..bbcff61 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.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\Bundle\FrameworkBundle\Command; + +use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Yaml\Yaml; + +/** + * A command that parse templates to extract translation messages and add them into the translation files. + * + * @author Michel Salib + */ +class TranslationUpdateCommand extends ContainerAwareCommand +{ + /** + * Compiled catalogue of messages. + * @var MessageCatalogue + */ + protected $catalogue; + + /** + * {@inheritDoc} + */ + protected function configure() + { + $this + ->setName('translation:update') + ->setDefinition(array( + new InputArgument('locale', InputArgument::REQUIRED, 'The locale'), + new InputArgument('bundle', InputArgument::REQUIRED, 'The bundle where to load the messages'), + new InputOption( + 'prefix', null, InputOption::VALUE_OPTIONAL, + 'Override the default prefix', '__' + ), + new InputOption( + 'output-format', null, InputOption::VALUE_OPTIONAL, + 'Override the default output format', 'yml' + ), + new InputOption( + 'dump-messages', null, InputOption::VALUE_NONE, + 'Should the messages be dumped in the console' + ), + new InputOption( + 'force', null, InputOption::VALUE_NONE, + 'Should the update be done' + ) + )) + ->setDescription('Updates the translation file') + ->setHelp(<<%command.name% command extract translation strings from templates +of a given bundle. It can display them or merge the new ones into the translation files. +When new translation strings are found it can automatically add a prefix to the translation +message. + +php %command.full_name% --dump-messages en AcmeBundle +php %command.full_name% --force --prefix="new_" fr AcmeBundle +EOF + ) + ; + } + + /** + * {@inheritDoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + // check presence of force or dump-message + if ($input->getOption('force') !== true && $input->getOption('dump-messages') !== true) { + $output->writeln('You must choose one of --force or --dump-messages'); + + return; + } + + // check format + $writer = $this->getContainer()->get('translation.writer'); + $supportedFormats = $writer->getFormats(); + if (!in_array($input->getOption('output-format'), $supportedFormats)) { + $output->writeln('Wrong output format'); + $output->writeln('Supported formats are '.implode(', ', $supportedFormats).'.'); + + return; + } + + // get bundle directory + $foundBundle = $this->getApplication()->getKernel()->getBundle($input->getArgument('bundle')); + $bundleTransPath = $foundBundle->getPath().'/Resources/translations'; + $output->writeln(sprintf('Generating "%s" translation files for "%s"', $input->getArgument('locale'), $foundBundle->getName())); + + // create catalogue + $catalogue = new MessageCatalogue($input->getArgument('locale')); + + // load any messages from templates + $output->writeln('Parsing templates'); + $extractor = $this->getContainer()->get('translation.extractor'); + $extractor->setPrefix($input->getOption('prefix')); + $extractor->extract($foundBundle->getPath().'/Resources/views/', $catalogue); + + // load any existing messages from the translation files + $output->writeln('Loading translation files'); + $loader = $this->getContainer()->get('translation.loader'); + $loader->loadMessages($bundleTransPath, $catalogue); + + // show compiled list of messages + if ($input->getOption('dump-messages') === true) { + foreach ($catalogue->getDomains() as $domain) { + $output->writeln(sprintf("\nDisplaying messages for domain %s:\n", $domain)); + $output->writeln(Yaml::dump($catalogue->all($domain), 10)); + } + if ($input->getOption('output-format') == 'xliff') { + $output->writeln('Xliff output version is 1.2'); + } + } + + // save the files + if ($input->getOption('force') === true) { + $output->writeln('Writing files'); + $writer->writeTranslations($catalogue, $input->getOption('output-format'), array('path' => $bundleTransPath)); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php new file mode 100644 index 0000000..cd80330 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.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\Bundle\FrameworkBundle\Console; + +use Symfony\Component\Console\Application as BaseApplication; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\HttpKernel\KernelInterface; +use Symfony\Component\HttpKernel\Kernel; + +/** + * Application. + * + * @author Fabien Potencier + */ +class Application extends BaseApplication +{ + private $kernel; + + /** + * Constructor. + * + * @param KernelInterface $kernel A KernelInterface instance + */ + public function __construct(KernelInterface $kernel) + { + $this->kernel = $kernel; + + parent::__construct('Symfony', Kernel::VERSION.' - '.$kernel->getName().'/'.$kernel->getEnvironment().($kernel->isDebug() ? '/debug' : '')); + + $this->getDefinition()->addOption(new InputOption('--shell', '-s', InputOption::VALUE_NONE, 'Launch the shell.')); + $this->getDefinition()->addOption(new InputOption('--process-isolation', null, InputOption::VALUE_NONE, 'Launch commands from shell as a separate processes.')); + $this->getDefinition()->addOption(new InputOption('--env', '-e', InputOption::VALUE_REQUIRED, 'The Environment name.', $kernel->getEnvironment())); + $this->getDefinition()->addOption(new InputOption('--no-debug', null, InputOption::VALUE_NONE, 'Switches off debug mode.')); + } + + /** + * Gets the Kernel associated with this Console. + * + * @return KernelInterface A KernelInterface instance + */ + public function getKernel() + { + return $this->kernel; + } + + /** + * Runs the current application. + * + * @param InputInterface $input An Input instance + * @param OutputInterface $output An Output instance + * + * @return integer 0 if everything went fine, or an error code + */ + public function doRun(InputInterface $input, OutputInterface $output) + { + $this->registerCommands(); + + if (true === $input->hasParameterOption(array('--shell', '-s'))) { + $shell = new Shell($this); + $shell->setProcessIsolation($input->hasParameterOption(array('--process-isolation'))); + $shell->run(); + + return 0; + } + + return parent::doRun($input, $output); + } + + protected function registerCommands() + { + $this->kernel->boot(); + foreach ($this->kernel->getBundles() as $bundle) { + $bundle->registerCommands($this); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Shell.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Shell.php new file mode 100644 index 0000000..33100bd --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Shell.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\Bundle\FrameworkBundle\Console; + +use Symfony\Component\Console\Shell as BaseShell; + +/** + * Shell. + * + * @author Fabien Potencier + */ +class Shell extends BaseShell +{ + /** + * Returns the shell header. + * + * @return string The header string + */ + protected function getHeader() + { + return << + _____ __ ___ + / ____| / _| |__ \ + | (___ _ _ _ __ ___ | |_ ___ _ __ _ _ ) | + \___ \| | | | '_ ` _ \| _/ _ \| '_ \| | | | / / + ____) | |_| | | | | | | || (_) | | | | |_| |/ /_ + |_____/ \__, |_| |_| |_|_| \___/|_| |_|\__, |____| + __/ | __/ | + |___/ |___/ + + +EOF + .parent::getHeader(); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php new file mode 100644 index 0000000..ba3a8ba --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php @@ -0,0 +1,247 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Controller; + +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\HttpFoundation\StreamedResponse; +use Symfony\Component\DependencyInjection\ContainerAware; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Symfony\Component\Form\FormTypeInterface; +use Symfony\Component\Form\Form; +use Symfony\Component\Form\FormBuilder; +use Doctrine\Bundle\DoctrineBundle\Registry; +use Symfony\Component\HttpFoundation\Request; + +/** + * Controller is a simple implementation of a Controller. + * + * It provides methods to common features needed in controllers. + * + * @author Fabien Potencier + */ +class Controller extends ContainerAware +{ + /** + * Generates a URL from the given parameters. + * + * @param string $route The name of the route + * @param mixed $parameters An array of parameters + * @param Boolean $absolute Whether to generate an absolute URL + * + * @return string The generated URL + */ + public function generateUrl($route, $parameters = array(), $absolute = false) + { + return $this->container->get('router')->generate($route, $parameters, $absolute); + } + + /** + * Forwards the request to another controller. + * + * @param string $controller The controller name (a string like BlogBundle:Post:index) + * @param array $path An array of path parameters + * @param array $query An array of query parameters + * + * @return Response A Response instance + */ + public function forward($controller, array $path = array(), array $query = array()) + { + return $this->container->get('http_kernel')->forward($controller, $path, $query); + } + + /** + * Returns a RedirectResponse to the given URL. + * + * @param string $url The URL to redirect to + * @param integer $status The status code to use for the Response + * + * @return RedirectResponse + */ + public function redirect($url, $status = 302) + { + return new RedirectResponse($url, $status); + } + + /** + * Returns a rendered view. + * + * @param string $view The view name + * @param array $parameters An array of parameters to pass to the view + * + * @return string The renderer view + */ + public function renderView($view, array $parameters = array()) + { + return $this->container->get('templating')->render($view, $parameters); + } + + /** + * Renders a view. + * + * @param string $view The view name + * @param array $parameters An array of parameters to pass to the view + * @param Response $response A response instance + * + * @return Response A Response instance + */ + public function render($view, array $parameters = array(), Response $response = null) + { + return $this->container->get('templating')->renderResponse($view, $parameters, $response); + } + + /** + * Streams a view. + * + * @param string $view The view name + * @param array $parameters An array of parameters to pass to the view + * @param StreamedResponse $response A response instance + * + * @return StreamedResponse A StreamedResponse instance + */ + public function stream($view, array $parameters = array(), StreamedResponse $response = null) + { + $templating = $this->container->get('templating'); + + $callback = function () use ($templating, $view, $parameters) { + $templating->stream($view, $parameters); + }; + + if (null === $response) { + return new StreamedResponse($callback); + } + + $response->setCallback($callback); + + return $response; + } + + /** + * Returns a NotFoundHttpException. + * + * This will result in a 404 response code. Usage example: + * + * throw $this->createNotFoundException('Page not found!'); + * + * @param string $message A message + * @param Exception $previous The previous exception + * + * @return NotFoundHttpException + */ + public function createNotFoundException($message = 'Not Found', \Exception $previous = null) + { + return new NotFoundHttpException($message, $previous); + } + + /** + * Creates and returns a Form instance from the type of the form. + * + * @param string|FormTypeInterface $type The built type of the form + * @param mixed $data The initial data for the form + * @param array $options Options for the form + * + * @return Form + */ + public function createForm($type, $data = null, array $options = array()) + { + return $this->container->get('form.factory')->create($type, $data, $options); + } + + /** + * Creates and returns a form builder instance + * + * @param mixed $data The initial data for the form + * @param array $options Options for the form + * + * @return FormBuilder + */ + public function createFormBuilder($data = null, array $options = array()) + { + return $this->container->get('form.factory')->createBuilder('form', $data, $options); + } + + /** + * Shortcut to return the request service. + * + * @return Request + */ + public function getRequest() + { + return $this->container->get('request'); + } + + /** + * Shortcut to return the Doctrine Registry service. + * + * @return Registry + * + * @throws \LogicException If DoctrineBundle is not available + */ + public function getDoctrine() + { + if (!$this->container->has('doctrine')) { + throw new \LogicException('The DoctrineBundle is not registered in your application.'); + } + + return $this->container->get('doctrine'); + } + + /** + * Get a user from the Security Context + * + * @return mixed + * + * @throws \LogicException If SecurityBundle is not available + * + * @see Symfony\Component\Security\Core\Authentication\Token\TokenInterface::getUser() + */ + public function getUser() + { + if (!$this->container->has('security.context')) { + throw new \LogicException('The SecurityBundle is not registered in your application.'); + } + + if (null === $token = $this->container->get('security.context')->getToken()) { + return null; + } + + if (!is_object($user = $token->getUser())) { + return null; + } + + return $user; + } + + /** + * Returns true if the service id is defined. + * + * @param string $id The service id + * + * @return Boolean true if the service id is defined, false otherwise + */ + public function has($id) + { + return $this->container->has($id); + } + + /** + * Gets a service by id. + * + * @param string $id The service id + * + * @return object The service + */ + public function get($id) + { + return $this->container->get($id); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php new file mode 100644 index 0000000..1c3fe19 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.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\Bundle\FrameworkBundle\Controller; + +use Symfony\Component\HttpKernel\KernelInterface; + +/** + * ControllerNameParser converts controller from the short notation a:b:c + * (BlogBundle:Post:index) to a fully-qualified class::method string + * (Bundle\BlogBundle\Controller\PostController::indexAction). + * + * @author Fabien Potencier + */ +class ControllerNameParser +{ + protected $kernel; + + /** + * Constructor. + * + * @param KernelInterface $kernel A KernelInterface instance + */ + public function __construct(KernelInterface $kernel) + { + $this->kernel = $kernel; + } + + /** + * Converts a short notation a:b:c to a class::method. + * + * @param string $controller A short notation controller (a:b:c) + */ + public function parse($controller) + { + if (3 != count($parts = explode(':', $controller))) { + throw new \InvalidArgumentException(sprintf('The "%s" controller is not a valid a:b:c controller string.', $controller)); + } + + list($bundle, $controller, $action) = $parts; + $controller = str_replace('/', '\\', $controller); + $class = null; + $logs = array(); + foreach ($this->kernel->getBundle($bundle, false) as $b) { + $try = $b->getNamespace().'\\Controller\\'.$controller.'Controller'; + if (!class_exists($try)) { + $logs[] = sprintf('Unable to find controller "%s:%s" - class "%s" does not exist.', $bundle, $controller, $try); + } else { + $class = $try; + + break; + } + } + + if (null === $class) { + $this->handleControllerNotFoundException($bundle, $controller, $logs); + } + + return $class.'::'.$action.'Action'; + } + + private function handleControllerNotFoundException($bundle, $controller, array $logs) + { + // just one log, return it as the exception + if (1 == count($logs)) { + throw new \InvalidArgumentException($logs[0]); + } + + // many logs, use a message that mentions each searched bundle + $names = array(); + foreach ($this->kernel->getBundle($bundle, false) as $b) { + $names[] = $b->getName(); + } + $msg = sprintf('Unable to find controller "%s:%s" in bundles %s.', $bundle, $controller, implode(', ', $names)); + + throw new \InvalidArgumentException($msg); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerResolver.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerResolver.php new file mode 100644 index 0000000..08a76f0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerResolver.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Controller; + +use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Symfony\Component\HttpKernel\Controller\ControllerResolver as BaseControllerResolver; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser; +use Symfony\Component\DependencyInjection\ContainerAwareInterface; + +/** + * ControllerResolver. + * + * @author Fabien Potencier + */ +class ControllerResolver extends BaseControllerResolver +{ + protected $container; + protected $parser; + + /** + * Constructor. + * + * @param ContainerInterface $container A ContainerInterface instance + * @param ControllerNameParser $parser A ControllerNameParser instance + * @param LoggerInterface $logger A LoggerInterface instance + */ + public function __construct(ContainerInterface $container, ControllerNameParser $parser, LoggerInterface $logger = null) + { + $this->container = $container; + $this->parser = $parser; + + parent::__construct($logger); + } + + /** + * Returns a callable for the given controller. + * + * @param string $controller A Controller string + * + * @return mixed A PHP callable + * + * @throws \LogicException When the name could not be parsed + * @throws \InvalidArgumentException When the controller class does not exist + */ + protected function createController($controller) + { + if (false === strpos($controller, '::')) { + $count = substr_count($controller, ':'); + if (2 == $count) { + // controller in the a:b:c notation then + $controller = $this->parser->parse($controller); + } elseif (1 == $count) { + // controller in the service:method notation + list($service, $method) = explode(':', $controller, 2); + + return array($this->container->get($service), $method); + } else { + throw new \LogicException(sprintf('Unable to parse the controller name "%s".', $controller)); + } + } + + list($class, $method) = explode('::', $controller, 2); + + if (!class_exists($class)) { + throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class)); + } + + $controller = new $class(); + if ($controller instanceof ContainerAwareInterface) { + $controller->setContainer($this->container); + } + + return array($controller, $method); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/InternalController.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/InternalController.php new file mode 100644 index 0000000..641deb7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/InternalController.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\Bundle\FrameworkBundle\Controller; + +use Symfony\Component\DependencyInjection\ContainerAware; +use Symfony\Component\HttpFoundation\Response; + +/** + * InternalController. + * + * @author Fabien Potencier + */ +class InternalController extends ContainerAware +{ + /** + * Forwards to the given controller with the given path. + * + * @param string $path The path + * @param string $controller The controller name + * + * @return Response A Response instance + */ + public function indexAction($path, $controller) + { + $request = $this->container->get('request'); + $attributes = $request->attributes; + + $attributes->remove('path'); + $attributes->remove('controller'); + if ('none' !== $path) { + parse_str($path, $tmp); + $attributes->add($tmp); + } + + return $this->container->get('http_kernel')->forward($controller, $attributes->all(), $request->query->all()); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php new file mode 100644 index 0000000..7174550 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.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\Bundle\FrameworkBundle\Controller; + +use Symfony\Component\DependencyInjection\ContainerAware; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\RedirectResponse; + +/** + * Redirects a request to another URL. + * + * @author Fabien Potencier + */ +class RedirectController extends ContainerAware +{ + /** + * Redirects to another route. + * + * It expects a route path parameter. + * By default, the response status code is 301. + * + * If the route empty, the status code will be 410. + * If the permanent path parameter is set, the status code will be 302. + * + * @param string $route The route pattern to redirect to + * @param Boolean $permanent Whether the redirect is permanent or not + * + * @return Response A Response instance + */ + public function redirectAction($route, $permanent = false) + { + if (!$route) { + return new Response(null, 410); + } + + $attributes = $this->container->get('request')->attributes->get('_route_params'); + unset($attributes['route'], $attributes['permanent']); + + return new RedirectResponse($this->container->get('router')->generate($route, $attributes), $permanent ? 301 : 302); + } + + /** + * Redirects to a URL. + * + * By default, the response status code is 301. + * + * If the path is empty, the status code will be 410. + * If the permanent flag is set, the status code will be 302. + * + * @param string $path The path to redirect to + * @param Boolean $permanent Whether the redirect is permanent or not + * @param Boolean $scheme The URL scheme (null to keep the current one) + * @param integer $httpPort The HTTP port + * @param integer $httpsPort The HTTPS port + * + * @return Response A Response instance + */ + public function urlRedirectAction($path, $permanent = false, $scheme = null, $httpPort = 80, $httpsPort = 443) + { + if (!$path) { + return new Response(null, 410); + } + + $statusCode = $permanent ? 301 : 302; + + // redirect if the path is a full URL + if (parse_url($path, PHP_URL_SCHEME)) { + return new RedirectResponse($path, $statusCode); + } + + $request = $this->container->get('request'); + if (null === $scheme) { + $scheme = $request->getScheme(); + } + + $qs = $request->getQueryString(); + if ($qs) { + $qs = '?'.$qs; + } + + $port = ''; + if ('http' === $scheme && 80 != $httpPort) { + $port = ':'.$httpPort; + } elseif ('https' === $scheme && 443 != $httpsPort) { + $port = ':'.$httpsPort; + } + + $url = $scheme.'://'.$request->getHost().$port.$request->getBaseUrl().$path.$qs; + + return new RedirectResponse($url, $statusCode); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/TemplateController.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/TemplateController.php new file mode 100644 index 0000000..fd6f1aa --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/TemplateController.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\Bundle\FrameworkBundle\Controller; + +use Symfony\Component\DependencyInjection\ContainerAware; +use Symfony\Component\HttpFoundation\Response; + +/** + * TemplateController. + * + * @author Fabien Potencier + */ +class TemplateController extends ContainerAware +{ + /** + * Renders a template. + * + * @param string $template The template name + * + * @return Response A Response instance + */ + public function templateAction($template) + { + return $this->container->get('templating')->renderResponse($template); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/TraceableControllerResolver.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/TraceableControllerResolver.php new file mode 100644 index 0000000..4994bea --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/TraceableControllerResolver.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\Bundle\FrameworkBundle\Controller; + +use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Symfony\Component\HttpKernel\Debug\Stopwatch; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser; + +/** + * TraceableControllerResolver. + * + * @author Fabien Potencier + */ +class TraceableControllerResolver extends ControllerResolver +{ + private $stopwatch; + + /** + * Constructor. + * + * @param ContainerInterface $container A ContainerInterface instance + * @param ControllerNameParser $parser A ControllerNameParser instance + * @param Stopwatch $stopwatch A Stopwatch instance + * @param LoggerInterface $logger A LoggerInterface instance + */ + public function __construct(ContainerInterface $container, ControllerNameParser $parser, Stopwatch $stopwatch, LoggerInterface $logger = null) + { + parent::__construct($container, $parser, $logger); + + $this->stopwatch = $stopwatch; + } + + /** + * @{inheritdoc} + */ + public function getController(Request $request) + { + $e = $this->stopwatch->start('controller.get_callable'); + + $ret = parent::getController($request); + + $e->stop(); + + return $ret; + } + + /** + * @{inheritdoc} + */ + public function getArguments(Request $request, $controller) + { + $e = $this->stopwatch->start('controller.get_arguments'); + + $ret = parent::getArguments($request, $controller); + + $e->stop(); + + return $ret; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DataCollector/RequestDataCollector.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DataCollector/RequestDataCollector.php new file mode 100644 index 0000000..bae7438 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DataCollector/RequestDataCollector.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\Bundle\FrameworkBundle\DataCollector; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\DataCollector\RequestDataCollector as BaseRequestDataCollector; +use Symfony\Component\HttpKernel\Event\FilterControllerEvent; + +/** + * RequestDataCollector. + * + * @author Fabien Potencier + */ +class RequestDataCollector extends BaseRequestDataCollector +{ + protected $controllers; + + public function __construct() + { + $this->controllers = new \SplObjectStorage(); + } + + /** + * {@inheritdoc} + */ + public function collect(Request $request, Response $response, \Exception $exception = null) + { + parent::collect($request, $response, $exception); + + $this->data['controller'] = 'n/a'; + + if (isset($this->controllers[$request])) { + $controller = $this->controllers[$request]; + if (is_array($controller)) { + $r = new \ReflectionMethod($controller[0], $controller[1]); + $this->data['controller'] = array( + 'class' => get_class($controller[0]), + 'method' => $controller[1], + 'file' => $r->getFilename(), + 'line' => $r->getStartLine(), + ); + } elseif ($controller instanceof \Closure) { + $this->data['controller'] = 'Closure'; + } else { + $this->data['controller'] = (string) $controller ?: 'n/a'; + } + unset($this->controllers[$request]); + } + } + + public function onKernelController(FilterControllerEvent $event) + { + $this->controllers[$event->getRequest()] = $event->getController(); + } + + /** + * Gets the route. + * + * @return string The route + */ + public function getRoute() + { + return isset($this->data['request_attributes']['_route']) ? $this->data['request_attributes']['_route'] : ''; + } + + /** + * Returns the route parameters. + * + * @return array The parameters + */ + public function getRouteParams() + { + return isset($this->data['request_attributes']['_route_params']) ? $this->data['request_attributes']['_route_params'] : array(); + } + + /** + * Gets the controller. + * + * @return string The controller as a string + */ + public function getController() + { + return $this->data['controller']; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DataCollector/RouterDataCollector.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DataCollector/RouterDataCollector.php new file mode 100644 index 0000000..5aa12b4 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DataCollector/RouterDataCollector.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\Bundle\FrameworkBundle\DataCollector; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\DataCollector\DataCollector; +use Symfony\Bundle\FrameworkBundle\Controller\RedirectController; +use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\HttpKernel\Event\FilterControllerEvent; + +/** + * RouterDataCollector. + * + * @author Fabien Potencier + */ +class RouterDataCollector extends DataCollector +{ + protected $controllers; + + public function __construct() + { + $this->controllers = new \SplObjectStorage(); + + $this->data = array( + 'redirect' => false, + 'url' => null, + 'route' => null, + ); + } + + /** + * {@inheritdoc} + */ + public function collect(Request $request, Response $response, \Exception $exception = null) + { + if ($response instanceof RedirectResponse) { + $this->data['redirect'] = true; + $this->data['url'] = $response->getTargetUrl(); + + if ($this->controllers->contains($request)) { + $controller = $this->controllers[$request]; + if (is_array($controller)) { + $controller = $controller[0]; + } + + if ($controller instanceof RedirectController) { + $this->data['route'] = $request->attributes->get('_route', 'n/a'); + } + } + } + } + + /** + * Remembers the controller associated to each request. + * + * @param FilterControllerEvent The filter controller event + */ + public function onKernelController(FilterControllerEvent $event) + { + $this->controllers[$event->getRequest()] = $event->getController(); + } + + /** + * @return Boolean Whether this request will result in a redirect + */ + public function getRedirect() + { + return $this->data['redirect']; + } + + /** + * @return string|null The target URL + */ + public function getTargetUrl() + { + return $this->data['url']; + } + + /** + * @return string|null The target route + */ + public function getTargetRoute() + { + return $this->data['route']; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'router'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddCacheClearerPass.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddCacheClearerPass.php new file mode 100644 index 0000000..c98e4e6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddCacheClearerPass.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\Bundle\FrameworkBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Registers the cache clearers. + * + * @author Dustin Dobervich + */ +class AddCacheClearerPass implements CompilerPassInterface +{ + /** + * {@inheritDoc} + */ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('cache_clearer')) { + return; + } + + $clearers = array(); + foreach ($container->findTaggedServiceIds('kernel.cache_clearer') as $id => $attributes) { + $clearers[] = new Reference($id); + } + + $container->getDefinition('cache_clearer')->replaceArgument(0, $clearers); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddCacheWarmerPass.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddCacheWarmerPass.php new file mode 100644 index 0000000..cf77dd5 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddCacheWarmerPass.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\Bundle\FrameworkBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Registers the cache warmers. + * + * @author Fabien Potencier + */ +class AddCacheWarmerPass implements CompilerPassInterface +{ + /** + * {@inheritDoc} + */ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('cache_warmer')) { + return; + } + + $warmers = array(); + foreach ($container->findTaggedServiceIds('kernel.cache_warmer') as $id => $attributes) { + $priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0; + $warmers[$priority][] = new Reference($id); + } + + if (empty($warmers)) { + return; + } + + // sort by priority and flatten + krsort($warmers); + $warmers = call_user_func_array('array_merge', $warmers); + + $container->getDefinition('cache_warmer')->replaceArgument(0, $warmers); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddConstraintValidatorsPass.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddConstraintValidatorsPass.php new file mode 100644 index 0000000..757c98b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddConstraintValidatorsPass.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\Bundle\FrameworkBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +class AddConstraintValidatorsPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('validator.validator_factory')) { + return; + } + + $validators = array(); + foreach ($container->findTaggedServiceIds('validator.constraint_validator') as $id => $attributes) { + if (isset($attributes[0]['alias'])) { + $validators[$attributes[0]['alias']] = $id; + } + } + + $container->getDefinition('validator.validator_factory')->replaceArgument(1, $validators); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddValidatorInitializersPass.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddValidatorInitializersPass.php new file mode 100644 index 0000000..6f3be9b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddValidatorInitializersPass.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\Bundle\FrameworkBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +class AddValidatorInitializersPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('validator')) { + return; + } + + $initializers = array(); + foreach ($container->findTaggedServiceIds('validator.initializer') as $id => $attributes) { + $initializers[] = new Reference($id); + } + + $container->getDefinition('validator')->replaceArgument(2, $initializers); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CompilerDebugDumpPass.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CompilerDebugDumpPass.php new file mode 100644 index 0000000..620edc2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CompilerDebugDumpPass.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\Bundle\FrameworkBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\Config\ConfigCache; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +class CompilerDebugDumpPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + $cache = new ConfigCache($this->getCompilerLogFilename($container), false); + $cache->write(implode("\n", $container->getCompiler()->getLog())); + } + + static public function getCompilerLogFilename(ContainerInterface $container) + { + $class = $container->getParameter('kernel.container_class'); + + return $container->getParameter('kernel.cache_dir').'/'.$class.'Compiler.log'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ContainerBuilderDebugDumpPass.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ContainerBuilderDebugDumpPass.php new file mode 100644 index 0000000..1457d7c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ContainerBuilderDebugDumpPass.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\Bundle\FrameworkBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Dumper\XmlDumper; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\Config\ConfigCache; + +/** + * Dumps the ContainerBuilder to a cache file so that it can be used by + * debugging tools such as the container:debug console command. + * + * @author Ryan Weaver + * @author Fabien Potencier + */ +class ContainerBuilderDebugDumpPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + $dumper = new XmlDumper($container); + $cache = new ConfigCache($container->getParameter('debug.container.dump'), false); + $cache->write($dumper->dump()); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/FormPass.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/FormPass.php new file mode 100644 index 0000000..e077cc1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/FormPass.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\Bundle\FrameworkBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Adds all services with the tags "form.type" and "form.type_guesser" as + * arguments of the "form.extension" service + * + * @author Bernhard Schussek + */ +class FormPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('form.extension')) { + return; + } + + // Builds an array with service IDs as keys and tag aliases as values + $types = array(); + + foreach ($container->findTaggedServiceIds('form.type') as $serviceId => $tag) { + $alias = isset($tag[0]['alias']) + ? $tag[0]['alias'] + : $serviceId; + + // Flip, because we want tag aliases (= type identifiers) as keys + $types[$alias] = $serviceId; + } + + $container->getDefinition('form.extension')->replaceArgument(1, $types); + + $typeExtensions = array(); + + foreach ($container->findTaggedServiceIds('form.type_extension') as $serviceId => $tag) { + $alias = isset($tag[0]['alias']) + ? $tag[0]['alias'] + : $serviceId; + + $typeExtensions[$alias][] = $serviceId; + } + + $container->getDefinition('form.extension')->replaceArgument(2, $typeExtensions); + + // Find all services annotated with "form.type_guesser" + $guessers = array_keys($container->findTaggedServiceIds('form.type_guesser')); + + $container->getDefinition('form.extension')->replaceArgument(3, $guessers); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ProfilerPass.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ProfilerPass.php new file mode 100644 index 0000000..d7dce5a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ProfilerPass.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\Bundle\FrameworkBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Adds tagged data_collector services to profiler service + * + * @author Fabien Potencier + */ +class ProfilerPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (false === $container->hasDefinition('profiler')) { + return; + } + + $definition = $container->getDefinition('profiler'); + + $collectors = new \SplPriorityQueue(); + $order = PHP_INT_MAX; + foreach ($container->findTaggedServiceIds('data_collector') as $id => $attributes) { + $priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0; + $template = null; + + if (isset($attributes[0]['template'])) { + if (!isset($attributes[0]['id'])) { + throw new \InvalidArgumentException(sprintf('Data collector service "%s" must have an id attribute in order to specify a template', $id)); + } + $template = array($attributes[0]['id'], $attributes[0]['template']); + } + + $collectors->insert(array($id, $template), array($priority, --$order)); + } + + $templates = array(); + foreach ($collectors as $collector) { + $definition->addMethodCall('add', array(new Reference($collector[0]))); + $templates[$collector[0]] = $collector[1]; + } + + $container->setParameter('data_collector.templates', $templates); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/RegisterKernelListenersPass.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/RegisterKernelListenersPass.php new file mode 100644 index 0000000..b6d94af --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/RegisterKernelListenersPass.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\Bundle\FrameworkBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +class RegisterKernelListenersPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('event_dispatcher')) { + return; + } + + $definition = $container->getDefinition('event_dispatcher'); + + foreach ($container->findTaggedServiceIds('kernel.event_listener') as $id => $events) { + foreach ($events as $event) { + $priority = isset($event['priority']) ? $event['priority'] : 0; + + if (!isset($event['event'])) { + throw new \InvalidArgumentException(sprintf('Service "%s" must define the "event" attribute on "kernel.event_listener" tags.', $id)); + } + + if (!isset($event['method'])) { + $event['method'] = 'on'.preg_replace(array( + '/(?<=\b)[a-z]/ie', + '/[^a-z0-9]/i' + ), array('strtoupper("\\0")', ''), $event['event']); + } + + $definition->addMethodCall('addListenerService', array($event['event'], array($id, $event['method']), $priority)); + } + } + + foreach ($container->findTaggedServiceIds('kernel.event_subscriber') as $id => $attributes) { + // We must assume that the class value has been correcly filled, even if the service is created by a factory + $class = $container->getDefinition($id)->getClass(); + + $refClass = new \ReflectionClass($class); + $interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface'; + if (!$refClass->implementsInterface($interface)) { + throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface)); + } + + $definition->addMethodCall('addSubscriberService', array($id, $class)); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/RoutingResolverPass.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/RoutingResolverPass.php new file mode 100644 index 0000000..322f7ba --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/RoutingResolverPass.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\Bundle\FrameworkBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Adds tagged routing.loader services to routing.resolver service + * + * @author Fabien Potencier + */ +class RoutingResolverPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (false === $container->hasDefinition('routing.resolver')) { + return; + } + + $definition = $container->getDefinition('routing.resolver'); + + foreach ($container->findTaggedServiceIds('routing.loader') as $id => $attributes) { + $definition->addMethodCall('addLoader', array(new Reference($id))); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TemplatingPass.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TemplatingPass.php new file mode 100644 index 0000000..4ab3a9a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TemplatingPass.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\Bundle\FrameworkBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +class TemplatingPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if ($container->hasDefinition('templating')) { + return; + } + + if ($container->hasDefinition('templating.engine.php')) { + $helpers = array(); + foreach ($container->findTaggedServiceIds('templating.helper') as $id => $attributes) { + if (isset($attributes[0]['alias'])) { + $helpers[$attributes[0]['alias']] = $id; + } + } + + if (count($helpers) > 0) { + $definition = $container->getDefinition('templating.engine.php'); + $definition->addMethodCall('setHelpers', array($helpers)); + } + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationDumperPass.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationDumperPass.php new file mode 100644 index 0000000..b7ba860 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationDumperPass.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\Bundle\FrameworkBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Adds tagged translation.formatter services to translation writer + */ +class TranslationDumperPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('translation.writer')) { + return; + } + + $definition = $container->getDefinition('translation.writer'); + + foreach ($container->findTaggedServiceIds('translation.dumper') as $id => $attributes) { + $definition->addMethodCall('addDumper', array($attributes[0]['alias'], new Reference($id))); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationExtractorPass.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationExtractorPass.php new file mode 100644 index 0000000..d982ced --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationExtractorPass.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\Bundle\FrameworkBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Adds tagged translation.extractor services to translation extractor + */ +class TranslationExtractorPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('translation.extractor')) { + return; + } + + $definition = $container->getDefinition('translation.extractor'); + + foreach ($container->findTaggedServiceIds('translation.extractor') as $id => $attributes) { + if (!isset($attributes[0]['alias'])) { + throw new \RuntimeException(sprintf('The alias for the tag "translation.extractor" of service "%s" must be set.', $id)); + } + + $definition->addMethodCall('addExtractor', array($attributes[0]['alias'], new Reference($id))); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php new file mode 100644 index 0000000..4e45016 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.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\Bundle\FrameworkBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +class TranslatorPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('translator.default')) { + return; + } + + $loaders = array(); + foreach ($container->findTaggedServiceIds('translation.loader') as $id => $attributes) { + $loaders[$id][] = $attributes[0]['alias']; + if (isset($attributes[0]['legacy-alias'])) { + $loaders[$id][] = $attributes[0]['legacy-alias']; + } + } + + if ($container->hasDefinition('translation.loader')) { + $definition = $container->getDefinition('translation.loader'); + foreach ($loaders as $id => $formats) { + foreach ($formats as $format) { + $definition->addMethodCall('addLoader', array($format, new Reference($id))); + } + } + } + + $container->findDefinition('translator.default')->replaceArgument(2, $loaders); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php new file mode 100644 index 0000000..7ffdca1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.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\Bundle\FrameworkBundle\DependencyInjection; + +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; + +/** + * FrameworkExtension configuration structure. + * + * @author Jeremy Mikola + */ +class Configuration implements ConfigurationInterface +{ + private $debug; + + /** + * Constructor + * + * @param Boolean $debug Whether to use the debug mode + */ + public function __construct($debug) + { + $this->debug = (Boolean) $debug; + } + + /** + * Generates the configuration tree builder. + * + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder + */ + public function getConfigTreeBuilder() + { + $treeBuilder = new TreeBuilder(); + $rootNode = $treeBuilder->root('framework'); + + $rootNode + ->children() + ->scalarNode('charset')->info('general configuration')->end() + ->scalarNode('trust_proxy_headers')->defaultFalse()->end() + ->scalarNode('secret')->isRequired()->end() + ->scalarNode('ide')->defaultNull()->end() + ->booleanNode('test')->end() + ->scalarNode('default_locale')->defaultValue('en')->end() + ->end() + ; + + $this->addFormSection($rootNode); + $this->addEsiSection($rootNode); + $this->addProfilerSection($rootNode); + $this->addRouterSection($rootNode); + $this->addSessionSection($rootNode); + $this->addTemplatingSection($rootNode); + $this->addTranslatorSection($rootNode); + $this->addValidationSection($rootNode); + $this->addAnnotationsSection($rootNode); + + return $treeBuilder; + } + + private function addFormSection(ArrayNodeDefinition $rootNode) + { + $rootNode + ->children() + ->arrayNode('form') + ->info('form configuration') + ->canBeUnset() + ->treatNullLike(array('enabled' => true)) + ->treatTrueLike(array('enabled' => true)) + ->children() + ->booleanNode('enabled')->defaultTrue()->end() + ->end() + ->end() + ->arrayNode('csrf_protection') + ->canBeUnset() + ->treatNullLike(array('enabled' => true)) + ->treatTrueLike(array('enabled' => true)) + ->children() + ->booleanNode('enabled')->defaultTrue()->end() + ->scalarNode('field_name')->defaultValue('_token')->end() + ->end() + ->end() + ->end() + ; + } + + private function addEsiSection(ArrayNodeDefinition $rootNode) + { + $rootNode + ->children() + ->arrayNode('esi') + ->info('esi configuration') + ->canBeUnset() + ->treatNullLike(array('enabled' => true)) + ->treatTrueLike(array('enabled' => true)) + ->children() + ->booleanNode('enabled')->defaultTrue()->end() + ->end() + ->end() + ->end() + ; + } + + private function addProfilerSection(ArrayNodeDefinition $rootNode) + { + $rootNode + ->children() + ->arrayNode('profiler') + ->info('profiler configuration') + ->canBeUnset() + ->children() + ->booleanNode('only_exceptions')->defaultFalse()->end() + ->booleanNode('only_master_requests')->defaultFalse()->end() + ->scalarNode('dsn')->defaultValue('file:%kernel.cache_dir%/profiler')->end() + ->scalarNode('username')->defaultValue('')->end() + ->scalarNode('password')->defaultValue('')->end() + ->scalarNode('lifetime')->defaultValue(86400)->end() + ->arrayNode('matcher') + ->canBeUnset() + ->performNoDeepMerging() + ->children() + ->scalarNode('ip')->end() + ->scalarNode('path') + ->info('use the urldecoded format') + ->example('^/path to resource/') + ->end() + ->scalarNode('service')->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ; + } + + private function addRouterSection(ArrayNodeDefinition $rootNode) + { + $rootNode + ->children() + ->arrayNode('router') + ->info('router configuration') + ->canBeUnset() + ->children() + ->scalarNode('resource')->isRequired()->end() + ->scalarNode('type')->end() + ->scalarNode('http_port')->defaultValue(80)->end() + ->scalarNode('https_port')->defaultValue(443)->end() + ->scalarNode('strict_parameters') + ->info( + 'set to false to disable exceptions when a route is '. + 'generated with invalid parameters (and return null instead)' + ) + ->defaultTrue() + ->end() + ->end() + ->end() + ->end() + ; + } + + private function addSessionSection(ArrayNodeDefinition $rootNode) + { + $rootNode + ->children() + ->arrayNode('session') + ->info('session configuration') + ->canBeUnset() + ->children() + ->booleanNode('auto_start')->defaultFalse()->end() + ->scalarNode('storage_id')->defaultValue('session.storage.native')->end() + ->scalarNode('handler_id')->defaultValue('session.handler.native_file')->end() + ->scalarNode('name')->end() + ->scalarNode('cookie_lifetime')->end() + ->scalarNode('cookie_path')->end() + ->scalarNode('cookie_domain')->end() + ->booleanNode('cookie_secure')->end() + ->booleanNode('cookie_httponly')->end() + ->scalarNode('gc_divisor')->end() + ->scalarNode('gc_probability')->end() + ->scalarNode('gc_maxlifetime')->end() + ->scalarNode('save_path')->defaultValue('%kernel.cache_dir%/sessions')->end() + ->scalarNode('lifetime')->info('DEPRECATED! Please use: cookie_lifetime')->end() + ->scalarNode('path')->info('DEPRECATED! Please use: cookie_path')->end() + ->scalarNode('domain')->info('DEPRECATED! Please use: cookie_domain')->end() + ->booleanNode('secure')->info('DEPRECATED! Please use: cookie_secure')->end() + ->booleanNode('httponly')->info('DEPRECATED! Please use: cookie_httponly')->end() + ->end() + ->end() + ->end() + ; + } + + private function addTemplatingSection(ArrayNodeDefinition $rootNode) + { + $organizeUrls = function($urls) { + $urls += array( + 'http' => array(), + 'ssl' => array(), + ); + + foreach ($urls as $i => $url) { + if (is_integer($i)) { + if (0 === strpos($url, 'https://') || 0 === strpos($url, '//')) { + $urls['http'][] = $urls['ssl'][] = $url; + } else { + $urls['http'][] = $url; + } + unset($urls[$i]); + } + } + + return $urls; + }; + + $rootNode + ->children() + ->arrayNode('templating') + ->info('templating configuration') + ->canBeUnset() + ->children() + ->scalarNode('assets_version')->defaultValue(null)->end() + ->scalarNode('assets_version_format')->defaultValue('%%s?%%s')->end() + ->scalarNode('hinclude_default_template')->defaultNull()->end() + ->arrayNode('form') + ->addDefaultsIfNotSet() + ->fixXmlConfig('resource') + ->children() + ->arrayNode('resources') + ->addDefaultChildrenIfNoneSet() + ->prototype('scalar')->defaultValue('FrameworkBundle:Form')->end() + ->validate() + ->ifTrue(function($v) {return !in_array('FrameworkBundle:Form', $v); }) + ->then(function($v){ + return array_merge(array('FrameworkBundle:Form'), $v); + }) + ->end() + ->end() + ->end() + ->end() + ->end() + ->fixXmlConfig('assets_base_url') + ->children() + ->arrayNode('assets_base_urls') + ->performNoDeepMerging() + ->addDefaultsIfNotSet() + ->beforeNormalization() + ->ifTrue(function($v) { return !is_array($v); }) + ->then(function($v) { return array($v); }) + ->end() + ->beforeNormalization() + ->always() + ->then($organizeUrls) + ->end() + ->children() + ->arrayNode('http') + ->prototype('scalar')->end() + ->end() + ->arrayNode('ssl') + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + ->scalarNode('cache')->end() + ->end() + ->fixXmlConfig('engine') + ->children() + ->arrayNode('engines') + ->example(array('twig')) + ->isRequired() + ->requiresAtLeastOneElement() + ->beforeNormalization() + ->ifTrue(function($v){ return !is_array($v); }) + ->then(function($v){ return array($v); }) + ->end() + ->prototype('scalar')->end() + ->end() + ->end() + ->fixXmlConfig('loader') + ->children() + ->arrayNode('loaders') + ->beforeNormalization() + ->ifTrue(function($v){ return !is_array($v); }) + ->then(function($v){ return array($v); }) + ->end() + ->prototype('scalar')->end() + ->end() + ->end() + ->fixXmlConfig('package') + ->children() + ->arrayNode('packages') + ->useAttributeAsKey('name') + ->prototype('array') + ->fixXmlConfig('base_url') + ->children() + ->scalarNode('version')->defaultNull()->end() + ->scalarNode('version_format')->defaultValue('%%s?%%s')->end() + ->arrayNode('base_urls') + ->performNoDeepMerging() + ->addDefaultsIfNotSet() + ->beforeNormalization() + ->ifTrue(function($v) { return !is_array($v); }) + ->then(function($v) { return array($v); }) + ->end() + ->beforeNormalization() + ->always() + ->then($organizeUrls) + ->end() + ->children() + ->arrayNode('http') + ->prototype('scalar')->end() + ->end() + ->arrayNode('ssl') + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ; + } + + private function addTranslatorSection(ArrayNodeDefinition $rootNode) + { + $rootNode + ->children() + ->arrayNode('translator') + ->info('translator configuration') + ->canBeUnset() + ->treatNullLike(array('enabled' => true)) + ->treatTrueLike(array('enabled' => true)) + ->children() + ->booleanNode('enabled')->defaultTrue()->end() + ->scalarNode('fallback')->defaultValue('en')->end() + ->end() + ->end() + ->end() + ; + } + + private function addValidationSection(ArrayNodeDefinition $rootNode) + { + $rootNode + ->children() + ->arrayNode('validation') + ->info('validation configuration') + ->canBeUnset() + ->treatNullLike(array('enabled' => true)) + ->treatTrueLike(array('enabled' => true)) + ->children() + ->booleanNode('enabled')->defaultTrue()->end() + ->scalarNode('cache')->end() + ->booleanNode('enable_annotations')->defaultFalse()->end() + ->end() + ->end() + ->end() + ; + } + + private function addAnnotationsSection(ArrayNodeDefinition $rootNode) + { + $rootNode + ->children() + ->arrayNode('annotations') + ->info('annotation configuration') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('cache')->defaultValue('file')->end() + ->scalarNode('file_cache_dir')->defaultValue('%kernel.cache_dir%/annotations')->end() + ->booleanNode('debug')->defaultValue($this->debug)->end() + ->end() + ->end() + ->end() + ; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php new file mode 100644 index 0000000..60bd4e4 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -0,0 +1,682 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\DependencyInjection; + +use Symfony\Component\Config\Loader\LoaderInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Config\Resource\DirectoryResource; +use Symfony\Component\Finder\Finder; +use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use Symfony\Component\Config\FileLocator; + +/** + * FrameworkExtension. + * + * @author Fabien Potencier + * @author Jeremy Mikola + */ +class FrameworkExtension extends Extension +{ + /** + * Responds to the app.config configuration parameter. + * + * @param array $configs + * @param ContainerBuilder $container + */ + public function load(array $configs, ContainerBuilder $container) + { + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + + $loader->load('web.xml'); + $loader->load('services.xml'); + + // A translator must always be registered (as support is included by + // default in the Form component). If disabled, an identity translator + // will be used and everything will still work as expected. + $loader->load('translation.xml'); + + if ($container->getParameter('kernel.debug')) { + $loader->load('debug.xml'); + $container->setDefinition('event_dispatcher', $container->findDefinition('debug.event_dispatcher')); + $container->setAlias('debug.event_dispatcher', 'event_dispatcher'); + + $container->setDefinition('controller_resolver', $container->findDefinition('debug.controller_resolver')); + $container->setAlias('debug.controller_resolver', 'controller_resolver'); + } + + $configuration = $this->getConfiguration($configs, $container); + $config = $this->processConfiguration($configuration, $configs); + + if (isset($config['charset'])) { + $container->setParameter('kernel.charset', $config['charset']); + } + $container->setParameter('kernel.secret', $config['secret']); + + $container->setParameter('kernel.trust_proxy_headers', $config['trust_proxy_headers']); + + $container->setParameter('kernel.default_locale', $config['default_locale']); + + if (!empty($config['test'])) { + $loader->load('test.xml'); + } + + if (isset($config['session'])) { + $this->registerSessionConfiguration($config['session'], $container, $loader); + } + + if (isset($config['form']) && !empty($config['form']['enabled'])) { + $this->registerFormConfiguration($config, $container, $loader); + $config['validation']['enabled'] = true; + } + + if (!empty($config['validation']['enabled'])) { + $this->registerValidationConfiguration($config['validation'], $container, $loader); + } + + if (isset($config['esi'])) { + $this->registerEsiConfiguration($config['esi'], $loader); + } + + if (isset($config['profiler'])) { + $this->registerProfilerConfiguration($config['profiler'], $container, $loader); + } + + if (isset($config['router'])) { + $this->registerRouterConfiguration($config['router'], $container, $loader); + } + + if (isset($config['templating'])) { + $this->registerTemplatingConfiguration($config['templating'], $config['ide'], $container, $loader); + } + + if (isset($config['translator'])) { + $this->registerTranslatorConfiguration($config['translator'], $container); + } + + $this->registerAnnotationsConfiguration($config['annotations'], $container, $loader); + + $this->addClassesToCompile(array( + 'Symfony\\Component\\HttpFoundation\\ParameterBag', + 'Symfony\\Component\\HttpFoundation\\HeaderBag', + 'Symfony\\Component\\HttpFoundation\\FileBag', + 'Symfony\\Component\\HttpFoundation\\ServerBag', + 'Symfony\\Component\\HttpFoundation\\Request', + 'Symfony\\Component\\HttpFoundation\\Response', + 'Symfony\\Component\\HttpFoundation\\ResponseHeaderBag', + + 'Symfony\\Component\\Config\\FileLocator', + + 'Symfony\\Component\\EventDispatcher\\EventDispatcherInterface', + 'Symfony\\Component\\EventDispatcher\\EventDispatcher', + 'Symfony\\Component\\EventDispatcher\\Event', + 'Symfony\\Component\\EventDispatcher\\EventSubscriberInterface', + 'Symfony\\Component\\EventDispatcher\\ContainerAwareEventDispatcher', + + 'Symfony\\Component\\HttpKernel\\HttpKernel', + 'Symfony\\Component\\HttpKernel\\EventListener\\ResponseListener', + 'Symfony\\Component\\HttpKernel\\EventListener\\RouterListener', + 'Symfony\\Component\\HttpKernel\\Controller\\ControllerResolver', + 'Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface', + 'Symfony\\Component\\HttpKernel\\Event\\KernelEvent', + 'Symfony\\Component\\HttpKernel\\Event\\FilterControllerEvent', + 'Symfony\\Component\\HttpKernel\\Event\\FilterResponseEvent', + 'Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent', + 'Symfony\\Component\\HttpKernel\\Event\\GetResponseForControllerResultEvent', + 'Symfony\\Component\\HttpKernel\\Event\\GetResponseForExceptionEvent', + 'Symfony\\Component\\HttpKernel\\KernelEvents', + 'Symfony\\Component\\HttpKernel\\Config\\FileLocator', + + 'Symfony\\Bundle\\FrameworkBundle\\Controller\\ControllerNameParser', + 'Symfony\\Bundle\\FrameworkBundle\\Controller\\ControllerResolver', + // Cannot be included because annotations will parse the big compiled class file + // 'Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller', + 'Symfony\\Bundle\\FrameworkBundle\\HttpKernel', + )); + } + + public function getConfiguration(array $config, ContainerBuilder $container) + { + return new Configuration($container->getParameter('kernel.debug')); + } + + /** + * Loads Form configuration. + * + * @param array $config A configuration array + * @param ContainerBuilder $container A ContainerBuilder instance + * @param XmlFileLoader $loader An XmlFileLoader instance + */ + private function registerFormConfiguration($config, ContainerBuilder $container, XmlFileLoader $loader) + { + $loader->load('form.xml'); + if (isset($config['csrf_protection'])) { + if (!isset($config['session'])) { + throw new \LogicException('CSRF protection needs that sessions are enabled.'); + } + $loader->load('form_csrf.xml'); + + $container->setParameter('form.type_extension.csrf.enabled', $config['csrf_protection']['enabled']); + $container->setParameter('form.type_extension.csrf.field_name', $config['csrf_protection']['field_name']); + } + } + + /** + * Loads the ESI configuration. + * + * @param array $config An ESI configuration array + * @param XmlFileLoader $loader An XmlFileLoader instance + */ + private function registerEsiConfiguration(array $config, XmlFileLoader $loader) + { + if (!empty($config['enabled'])) { + $loader->load('esi.xml'); + } + } + + /** + * Loads the profiler configuration. + * + * @param array $config A profiler configuration array + * @param ContainerBuilder $container A ContainerBuilder instance + * @param XmlFileLoader $loader An XmlFileLoader instance + */ + private function registerProfilerConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) + { + $loader->load('profiling.xml'); + $loader->load('collectors.xml'); + + $container->setParameter('profiler_listener.only_exceptions', $config['only_exceptions']); + $container->setParameter('profiler_listener.only_master_requests', $config['only_master_requests']); + + // Choose storage class based on the DSN + $supported = array( + 'sqlite' => 'Symfony\Component\HttpKernel\Profiler\SqliteProfilerStorage', + 'mysql' => 'Symfony\Component\HttpKernel\Profiler\MysqlProfilerStorage', + 'file' => 'Symfony\Component\HttpKernel\Profiler\FileProfilerStorage', + 'mongodb' => 'Symfony\Component\HttpKernel\Profiler\MongoDbProfilerStorage', + 'memcache' => 'Symfony\Component\HttpKernel\Profiler\MemcacheProfilerStorage', + 'memcached' => 'Symfony\Component\HttpKernel\Profiler\MemcachedProfilerStorage', + 'redis' => 'Symfony\Component\HttpKernel\Profiler\RedisProfilerStorage', + ); + list($class, ) = explode(':', $config['dsn'], 2); + if (!isset($supported[$class])) { + throw new \LogicException(sprintf('Driver "%s" is not supported for the profiler.', $class)); + } + + $container->setParameter('profiler.storage.dsn', $config['dsn']); + $container->setParameter('profiler.storage.username', $config['username']); + $container->setParameter('profiler.storage.password', $config['password']); + $container->setParameter('profiler.storage.lifetime', $config['lifetime']); + + $container->getDefinition('profiler.storage')->setClass($supported[$class]); + + if (isset($config['matcher'])) { + if (isset($config['matcher']['service'])) { + $container->setAlias('profiler.request_matcher', $config['matcher']['service']); + } elseif (isset($config['matcher']['ip']) || isset($config['matcher']['path'])) { + $definition = $container->register('profiler.request_matcher', 'Symfony\\Component\\HttpFoundation\\RequestMatcher'); + $definition->setPublic(false); + + if (isset($config['matcher']['ip'])) { + $definition->addMethodCall('matchIp', array($config['matcher']['ip'])); + } + + if (isset($config['matcher']['path'])) { + $definition->addMethodCall('matchPath', array($config['matcher']['path'])); + } + } + } + } + + /** + * Loads the router configuration. + * + * @param array $config A router configuration array + * @param ContainerBuilder $container A ContainerBuilder instance + * @param XmlFileLoader $loader An XmlFileLoader instance + */ + private function registerRouterConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) + { + $loader->load('routing.xml'); + + $container->setParameter('router.resource', $config['resource']); + $router = $container->findDefinition('router.default'); + + $argument = $router->getArgument(2); + $argument['strict_parameters'] = $config['strict_parameters']; + if (isset($config['type'])) { + $argument['resource_type'] = $config['type']; + } + $router->replaceArgument(2, $argument); + + $container->setParameter('request_listener.http_port', $config['http_port']); + $container->setParameter('request_listener.https_port', $config['https_port']); + + $this->addClassesToCompile(array( + 'Symfony\\Component\\Routing\\Matcher\\UrlMatcherInterface', + 'Symfony\\Component\\Routing\\Generator\\UrlGeneratorInterface', + 'Symfony\\Component\\Routing\\RouterInterface', + 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher', + 'Symfony\\Component\\Routing\\Generator\\UrlGenerator', + 'Symfony\\Component\\Routing\\Matcher\\RedirectableUrlMatcherInterface', + 'Symfony\\Component\\Routing\\RequestContextAwareInterface', + 'Symfony\\Component\\Routing\\RequestContext', + 'Symfony\\Component\\Routing\\Router', + 'Symfony\\Bundle\\FrameworkBundle\\Routing\\RedirectableUrlMatcher', + $container->findDefinition('router.default')->getClass(), + )); + } + + /** + * Loads the session configuration. + * + * @param array $config A session configuration array + * @param ContainerBuilder $container A ContainerBuilder instance + * @param XmlFileLoader $loader An XmlFileLoader instance + */ + private function registerSessionConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) + { + $loader->load('session.xml'); + + // session + $container->getDefinition('session_listener')->addArgument($config['auto_start']); + + // session storage + $container->setAlias('session.storage', $config['storage_id']); + $options = array(); + foreach (array('name', 'cookie_lifetime', 'cookie_path', 'cookie_domain', 'cookie_secure', 'cookie_httponly', 'auto_start', 'gc_maxlifetime', 'gc_probability', 'gc_divisor') as $key) { + if (isset($config[$key])) { + $options[$key] = $config[$key]; + } + } + + //we deprecated session options without cookie_ prefix, but we are still supporting them, + //Let's merge the ones that were supplied without prefix + foreach (array('lifetime', 'path', 'domain', 'secure', 'httponly') as $key) { + if (!isset($options['cookie_'.$key]) && isset($config[$key])) { + $options['cookie_'.$key] = $config[$key]; + } + } + $container->setParameter('session.storage.options', $options); + + // session handler (the internal callback registered with PHP session management) + $container->setAlias('session.handler', $config['handler_id']); + + $container->setParameter('session.save_path', $config['save_path']); + + $this->addClassesToCompile(array( + 'Symfony\\Bundle\\FrameworkBundle\\EventListener\\SessionListener', + 'Symfony\\Component\\HttpFoundation\\Session\\Storage\\SessionStorageInterface', + 'Symfony\\Component\\HttpFoundation\\Session\\Storage\\NativeSessionStorage', + 'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\FileSessionHandler', + 'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Proxy\\AbstractProxy', + 'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Proxy\\SessionHandlerProxy', + $container->getDefinition('session')->getClass(), + )); + + if ($container->hasDefinition($config['storage_id'])) { + $this->addClassesToCompile(array( + $container->findDefinition('session.storage')->getClass(), + )); + } + } + + /** + * Loads the templating configuration. + * + * @param array $config A templating configuration array + * @param string $ide + * @param ContainerBuilder $container A ContainerBuilder instance + * @param XmlFileLoader $loader An XmlFileLoader instance + */ + private function registerTemplatingConfiguration(array $config, $ide, ContainerBuilder $container, XmlFileLoader $loader) + { + $loader->load('templating.xml'); + $loader->load('templating_php.xml'); + + $links = array( + 'textmate' => 'txmt://open?url=file://%%f&line=%%l', + 'macvim' => 'mvim://open?url=file://%%f&line=%%l', + ); + + $container->setParameter('templating.helper.code.file_link_format', isset($links[$ide]) ? $links[$ide] : $ide); + $container->setParameter('templating.helper.form.resources', $config['form']['resources']); + $container->setParameter('templating.hinclude.default_template', $config['hinclude_default_template']); + + if ($container->getParameter('kernel.debug')) { + $loader->load('templating_debug.xml'); + } + + // create package definitions and add them to the assets helper + $defaultPackage = $this->createPackageDefinition($container, $config['assets_base_urls']['http'], $config['assets_base_urls']['ssl'], $config['assets_version'], $config['assets_version_format']); + $container->setDefinition('templating.asset.default_package', $defaultPackage); + $namedPackages = array(); + foreach ($config['packages'] as $name => $package) { + $namedPackage = $this->createPackageDefinition($container, $package['base_urls']['http'], $package['base_urls']['ssl'], $package['version'], $package['version_format'], $name); + $container->setDefinition('templating.asset.package.'.$name, $namedPackage); + $namedPackages[$name] = new Reference('templating.asset.package.'.$name); + } + $container->getDefinition('templating.helper.assets')->setArguments(array( + new Reference('templating.asset.default_package'), + $namedPackages, + )); + + // Apply request scope to assets helper if one or more packages are request-scoped + $requireRequestScope = array_reduce( + $namedPackages, + function($v, Reference $ref) use ($container) { + return $v || 'request' === $container->getDefinition($ref)->getScope(); + }, + 'request' === $defaultPackage->getScope() + ); + + if ($requireRequestScope) { + $container->getDefinition('templating.helper.assets')->setScope('request'); + } + + if (!empty($config['loaders'])) { + $loaders = array_map(function($loader) { return new Reference($loader); }, $config['loaders']); + + // Use a delegation unless only a single loader was registered + if (1 === count($loaders)) { + $container->setAlias('templating.loader', (string) reset($loaders)); + } else { + $container->getDefinition('templating.loader.chain')->addArgument($loaders); + $container->setAlias('templating.loader', 'templating.loader.chain'); + } + } + + $container->setParameter('templating.loader.cache.path', null); + if (isset($config['cache'])) { + // Wrap the existing loader with cache (must happen after loaders are registered) + $container->setDefinition('templating.loader.wrapped', $container->findDefinition('templating.loader')); + $loaderCache = $container->getDefinition('templating.loader.cache'); + $container->setParameter('templating.loader.cache.path', $config['cache']); + + $container->setDefinition('templating.loader', $loaderCache); + } + + $this->addClassesToCompile(array( + 'Symfony\\Bundle\\FrameworkBundle\\Templating\\GlobalVariables', + 'Symfony\\Bundle\\FrameworkBundle\\Templating\\EngineInterface', + 'Symfony\\Component\\Templating\\StreamingEngineInterface', + 'Symfony\\Component\\Templating\\TemplateNameParserInterface', + 'Symfony\\Component\\Templating\\TemplateNameParser', + 'Symfony\\Component\\Templating\\EngineInterface', + 'Symfony\\Component\\Config\\FileLocatorInterface', + 'Symfony\\Component\\Templating\\TemplateReferenceInterface', + 'Symfony\\Component\\Templating\\TemplateReference', + 'Symfony\\Bundle\\FrameworkBundle\\Templating\\TemplateReference', + 'Symfony\\Bundle\\FrameworkBundle\\Templating\\TemplateNameParser', + $container->findDefinition('templating.locator')->getClass(), + )); + + if (in_array('php', $config['engines'], true)) { + $this->addClassesToCompile(array( + 'Symfony\\Component\\Templating\\PhpEngine', + 'Symfony\\Component\\Templating\\Loader\\LoaderInterface', + 'Symfony\\Component\\Templating\\Storage\\Storage', + 'Symfony\\Component\\Templating\\Storage\\FileStorage', + 'Symfony\\Bundle\\FrameworkBundle\\Templating\\PhpEngine', + 'Symfony\\Bundle\\FrameworkBundle\\Templating\\Loader\\FilesystemLoader', + )); + } + + $container->setParameter('templating.engines', $config['engines']); + $engines = array_map(function($engine) { return new Reference('templating.engine.'.$engine); }, $config['engines']); + + // Use a delegation unless only a single engine was registered + if (1 === count($engines)) { + $container->setAlias('templating', (string) reset($engines)); + } else { + $container->getDefinition('templating.engine.delegating')->replaceArgument(1, $engines); + $container->setAlias('templating', 'templating.engine.delegating'); + } + } + + /** + * Returns a definition for an asset package. + */ + private function createPackageDefinition(ContainerBuilder $container, array $httpUrls, array $sslUrls, $version, $format, $name = null) + { + if (!$httpUrls) { + $package = new DefinitionDecorator('templating.asset.path_package'); + $package + ->setPublic(false) + ->setScope('request') + ->replaceArgument(1, $version) + ->replaceArgument(2, $format) + ; + + return $package; + } + + if ($httpUrls == $sslUrls) { + $package = new DefinitionDecorator('templating.asset.url_package'); + $package + ->setPublic(false) + ->replaceArgument(0, $sslUrls) + ->replaceArgument(1, $version) + ->replaceArgument(2, $format) + ; + + return $package; + } + + $prefix = $name ? 'templating.asset.package.'.$name : 'templating.asset.default_package'; + + $httpPackage = new DefinitionDecorator('templating.asset.url_package'); + $httpPackage + ->replaceArgument(0, $httpUrls) + ->replaceArgument(1, $version) + ->replaceArgument(2, $format) + ; + $container->setDefinition($prefix.'.http', $httpPackage); + + if ($sslUrls) { + $sslPackage = new DefinitionDecorator('templating.asset.url_package'); + $sslPackage + ->replaceArgument(0, $sslUrls) + ->replaceArgument(1, $version) + ->replaceArgument(2, $format) + ; + } else { + $sslPackage = new DefinitionDecorator('templating.asset.path_package'); + $sslPackage + ->setScope('request') + ->replaceArgument(1, $version) + ->replaceArgument(2, $format) + ; + } + $container->setDefinition($prefix.'.ssl', $sslPackage); + + $package = new DefinitionDecorator('templating.asset.request_aware_package'); + $package + ->setPublic(false) + ->setScope('request') + ->replaceArgument(1, $prefix.'.http') + ->replaceArgument(2, $prefix.'.ssl') + ; + + return $package; + } + + /** + * Loads the translator configuration. + * + * @param array $config A translator configuration array + * @param ContainerBuilder $container A ContainerBuilder instance + */ + private function registerTranslatorConfiguration(array $config, ContainerBuilder $container) + { + if (!empty($config['enabled'])) { + // Use the "real" translator instead of the identity default + $container->setAlias('translator', 'translator.default'); + $translator = $container->findDefinition('translator.default'); + $translator->addMethodCall('setFallbackLocale', array($config['fallback'])); + + // Discover translation directories + $dirs = array(); + if (class_exists('Symfony\Component\Validator\Validator')) { + $r = new \ReflectionClass('Symfony\Component\Validator\Validator'); + + $dirs[] = dirname($r->getFilename()).'/Resources/translations'; + } + if (class_exists('Symfony\Component\Form\Form')) { + $r = new \ReflectionClass('Symfony\Component\Form\Form'); + + $dirs[] = dirname($r->getFilename()).'/Resources/translations'; + } + $overridePath = $container->getParameter('kernel.root_dir').'/Resources/%s/translations'; + foreach ($container->getParameter('kernel.bundles') as $bundle => $class) { + $reflection = new \ReflectionClass($class); + if (is_dir($dir = dirname($reflection->getFilename()).'/Resources/translations')) { + $dirs[] = $dir; + } + if (is_dir($dir = sprintf($overridePath, $bundle))) { + $dirs[] = $dir; + } + } + if (is_dir($dir = $container->getParameter('kernel.root_dir').'/Resources/translations')) { + $dirs[] = $dir; + } + + // Register translation resources + if ($dirs) { + foreach ($dirs as $dir) { + $container->addResource(new DirectoryResource($dir)); + } + $finder = Finder::create() + ->files() + ->filter(function (\SplFileInfo $file) { + return 2 === substr_count($file->getBasename(), '.') && preg_match('/\.\w+$/', $file->getBasename()); + }) + ->in($dirs) + ; + + foreach ($finder as $file) { + // filename is domain.locale.format + list($domain, $locale, $format) = explode('.', $file->getBasename(), 3); + $translator->addMethodCall('addResource', array($format, (string) $file, $locale, $domain)); + } + } + } + } + + /** + * Loads the validator configuration. + * + * @param array $config A validation configuration array + * @param ContainerBuilder $container A ContainerBuilder instance + * @param XmlFileLoader $loader An XmlFileLoader instance + */ + private function registerValidationConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) + { + $loader->load('validator.xml'); + + $container->setParameter('validator.mapping.loader.xml_files_loader.mapping_files', $this->getValidatorXmlMappingFiles($container)); + $container->setParameter('validator.mapping.loader.yaml_files_loader.mapping_files', $this->getValidatorYamlMappingFiles($container)); + + if (array_key_exists('enable_annotations', $config) && $config['enable_annotations']) { + $loaderChain = $container->getDefinition('validator.mapping.loader.loader_chain'); + $arguments = $loaderChain->getArguments(); + array_unshift($arguments[0], new Reference('validator.mapping.loader.annotation_loader')); + $loaderChain->setArguments($arguments); + } + + if (isset($config['cache'])) { + $container->getDefinition('validator.mapping.class_metadata_factory') + ->replaceArgument(1, new Reference('validator.mapping.cache.'.$config['cache'])); + $container->setParameter( + 'validator.mapping.cache.prefix', + 'validator_'.md5($container->getParameter('kernel.root_dir')) + ); + } + } + + private function getValidatorXmlMappingFiles(ContainerBuilder $container) + { + $reflClass = new \ReflectionClass('Symfony\Component\Form\FormInterface'); + $files = array(dirname($reflClass->getFileName()).'/Resources/config/validation.xml'); + $container->addResource(new FileResource($files[0])); + + foreach ($container->getParameter('kernel.bundles') as $bundle) { + $reflection = new \ReflectionClass($bundle); + if (is_file($file = dirname($reflection->getFilename()).'/Resources/config/validation.xml')) { + $files[] = realpath($file); + $container->addResource(new FileResource($file)); + } + } + + return $files; + } + + private function getValidatorYamlMappingFiles(ContainerBuilder $container) + { + $files = array(); + + foreach ($container->getParameter('kernel.bundles') as $bundle) { + $reflection = new \ReflectionClass($bundle); + if (is_file($file = dirname($reflection->getFilename()).'/Resources/config/validation.yml')) { + $files[] = realpath($file); + $container->addResource(new FileResource($file)); + } + } + + return $files; + } + + private function registerAnnotationsConfiguration(array $config, ContainerBuilder $container,$loader) + { + $loader->load('annotations.xml'); + + if ('file' === $config['cache']) { + $cacheDir = $container->getParameterBag()->resolveValue($config['file_cache_dir']); + if (!is_dir($cacheDir) && false === @mkdir($cacheDir, 0777, true)) { + throw new \RuntimeException(sprintf('Could not create cache directory "%s".', $cacheDir)); + } + + $container + ->getDefinition('annotations.file_cache_reader') + ->replaceArgument(1, $cacheDir) + ->replaceArgument(2, $config['debug']) + ; + $container->setAlias('annotation_reader', 'annotations.file_cache_reader'); + } elseif ('none' !== $config['cache']) { + $container + ->getDefinition('annotations.cached_reader') + ->replaceArgument(1, new Reference($config['cache'])) + ->replaceArgument(2, $config['debug']) + ; + $container->setAlias('annotation_reader', 'annotations.cached_reader'); + } + } + + /** + * Returns the base path for the XSD files. + * + * @return string The XSD base path + */ + public function getXsdValidationBasePath() + { + return __DIR__.'/../Resources/config/schema'; + } + + public function getNamespace() + { + return 'http://symfony.com/schema/dic/symfony'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/EventListener/SessionListener.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/EventListener/SessionListener.php new file mode 100644 index 0000000..ad39634 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/EventListener/SessionListener.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\Bundle\FrameworkBundle\EventListener; + +use Symfony\Component\DependencyInjection\ContainerInterface; + +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * Sets the session on the request. + * + * This will also start the session if it was already started during a previous + * request. + * + * @author Johannes M. Schmitt + */ +class SessionListener implements EventSubscriberInterface +{ + /** + * @var ContainerInterface + */ + private $container; + + /** + * @var boolean + */ + private $autoStart; + + public function __construct(ContainerInterface $container, $autoStart = false) + { + $this->container = $container; + $this->autoStart = $autoStart; + } + + public function onKernelRequest(GetResponseEvent $event) + { + if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) { + return; + } + + if (!$this->container->has('session')) { + return; + } + + $request = $event->getRequest(); + if ($request->hasSession()) { + return; + } + + $request->setSession($session = $this->container->get('session')); + + if ($this->autoStart || $request->hasPreviousSession()) { + $session->start(); + } + } + + static public function getSubscribedEvents() + { + return array( + KernelEvents::REQUEST => array('onKernelRequest', 128), + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/EventListener/TestSessionListener.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/EventListener/TestSessionListener.php new file mode 100644 index 0000000..55fbb75 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/EventListener/TestSessionListener.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\Bundle\FrameworkBundle\EventListener; + +use Symfony\Component\HttpFoundation\Cookie; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * TestSessionListener. + * + * Saves session in test environment. + * + * @author Bulat Shakirzyanov + * @author Fabien Potencier + */ +class TestSessionListener implements EventSubscriberInterface +{ + protected $container; + + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + public function onKernelRequest(GetResponseEvent $event) + { + if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) { + return; + } + + // bootstrap the session + if (!$this->container->has('session')) { + return; + } + + $session = $this->container->get('session'); + $cookies = $event->getRequest()->cookies; + + if ($cookies->has($session->getName())) { + $session->setId($cookies->get($session->getName())); + } else { + $session->migrate(false); + } + } + + /** + * Checks if session was initialized and saves if current request is master + * Runs on 'kernel.response' in test environment + * + * @param FilterResponseEvent $event + */ + public function onKernelResponse(FilterResponseEvent $event) + { + if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) { + return; + } + + if ($session = $event->getRequest()->getSession()) { + $session->save(); + + $params = session_get_cookie_params(); + + $event->getResponse()->headers->setCookie(new Cookie($session->getName(), $session->getId(), 0 === $params['lifetime'] ? 0 : time() + $params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly'])); + } + } + + static public function getSubscribedEvents() + { + return array( + KernelEvents::REQUEST => array('onKernelRequest', 192), + KernelEvents::RESPONSE => array('onKernelResponse', -128), + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php new file mode 100644 index 0000000..544f202 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.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\Bundle\FrameworkBundle; + +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConstraintValidatorsPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddValidatorInitializersPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\FormPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TemplatingPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\RegisterKernelListenersPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\RoutingResolverPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ProfilerPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslatorPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddCacheWarmerPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddCacheClearerPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ContainerBuilderDebugDumpPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CompilerDebugDumpPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationExtractorPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationDumperPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\PassConfig; +use Symfony\Component\DependencyInjection\Scope; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Bundle\Bundle; + +/** + * Bundle. + * + * @author Fabien Potencier + */ +class FrameworkBundle extends Bundle +{ + public function boot() + { + if ($this->container->getParameter('kernel.trust_proxy_headers')) { + Request::trustProxyData(); + } + } + + public function build(ContainerBuilder $container) + { + parent::build($container); + + $container->addScope(new Scope('request')); + + $container->addCompilerPass(new RoutingResolverPass()); + $container->addCompilerPass(new ProfilerPass()); + $container->addCompilerPass(new RegisterKernelListenersPass(), PassConfig::TYPE_AFTER_REMOVING); + $container->addCompilerPass(new TemplatingPass()); + $container->addCompilerPass(new AddConstraintValidatorsPass()); + $container->addCompilerPass(new AddValidatorInitializersPass()); + $container->addCompilerPass(new FormPass()); + $container->addCompilerPass(new TranslatorPass()); + $container->addCompilerPass(new AddCacheWarmerPass()); + $container->addCompilerPass(new AddCacheClearerPass()); + $container->addCompilerPass(new TranslationExtractorPass()); + $container->addCompilerPass(new TranslationDumperPass()); + + if ($container->getParameter('kernel.debug')) { + $container->addCompilerPass(new ContainerBuilderDebugDumpPass(), PassConfig::TYPE_AFTER_REMOVING); + $container->addCompilerPass(new CompilerDebugDumpPass(), PassConfig::TYPE_AFTER_REMOVING); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/HttpCache/HttpCache.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/HttpCache/HttpCache.php new file mode 100644 index 0000000..fa09602 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/HttpCache/HttpCache.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\Bundle\FrameworkBundle\HttpCache; + +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\HttpCache\HttpCache as BaseHttpCache; +use Symfony\Component\HttpKernel\HttpCache\Esi; +use Symfony\Component\HttpKernel\HttpCache\Store; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +/** + * Manages HTTP cache objects in a Container. + * + * @author Fabien Potencier + */ +abstract class HttpCache extends BaseHttpCache +{ + protected $cacheDir; + protected $kernel; + + /** + * Constructor. + * + * @param HttpKernelInterface $kernel An HttpKernelInterface instance + * @param String $cacheDir The cache directory (default used if null) + */ + public function __construct(HttpKernelInterface $kernel, $cacheDir = null) + { + $this->kernel = $kernel; + $this->cacheDir = $cacheDir; + + parent::__construct($kernel, $this->createStore(), $this->createEsi(), array_merge(array('debug' => $kernel->isDebug()), $this->getOptions())); + } + + /** + * Forwards the Request to the backend and returns the Response. + * + * @param Request $request A Request instance + * @param Boolean $raw Whether to catch exceptions or not + * @param Response $entry A Response instance (the stale entry if present, null otherwise) + * + * @return Response A Response instance + */ + protected function forward(Request $request, $raw = false, Response $entry = null) + { + $this->getKernel()->boot(); + $this->getKernel()->getContainer()->set('cache', $this); + $this->getKernel()->getContainer()->set('esi', $this->getEsi()); + + return parent::forward($request, $raw, $entry); + } + + /** + * Returns an array of options to customize the Cache configuration. + * + * @return array An array of options + */ + protected function getOptions() + { + return array(); + } + + protected function createEsi() + { + return new Esi(); + } + + protected function createStore() + { + return new Store($this->cacheDir ?: $this->kernel->getCacheDir().'/http_cache'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/HttpKernel.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/HttpKernel.php new file mode 100644 index 0000000..523bd17 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/HttpKernel.php @@ -0,0 +1,239 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\StreamedResponse; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpKernel\HttpKernel as BaseHttpKernel; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; + +/** + * This HttpKernel is used to manage scope changes of the DI container. + * + * @author Fabien Potencier + * @author Johannes M. Schmitt + */ +class HttpKernel extends BaseHttpKernel +{ + protected $container; + + private $esiSupport; + + public function __construct(EventDispatcherInterface $dispatcher, ContainerInterface $container, ControllerResolverInterface $controllerResolver) + { + parent::__construct($dispatcher, $controllerResolver); + + $this->container = $container; + } + + public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) + { + $request->headers->set('X-Php-Ob-Level', ob_get_level()); + + $this->container->enterScope('request'); + $this->container->set('request', $request, 'request'); + + try { + $response = parent::handle($request, $type, $catch); + } catch (\Exception $e) { + $this->container->leaveScope('request'); + + throw $e; + } + + $this->container->leaveScope('request'); + + return $response; + } + + /** + * Forwards the request to another controller. + * + * @param string $controller The controller name (a string like BlogBundle:Post:index) + * @param array $attributes An array of request attributes + * @param array $query An array of request query parameters + * + * @return Response A Response instance + */ + public function forward($controller, array $attributes = array(), array $query = array()) + { + $attributes['_controller'] = $controller; + $subRequest = $this->container->get('request')->duplicate($query, null, $attributes); + + return $this->handle($subRequest, HttpKernelInterface::SUB_REQUEST); + } + + /** + * Renders a Controller and returns the Response content. + * + * Note that this method generates an esi:include tag only when both the standalone + * option is set to true and the request has ESI capability (@see Symfony\Component\HttpKernel\HttpCache\ESI). + * + * Available options: + * + * * attributes: An array of request attributes (only when the first argument is a controller) + * * query: An array of request query parameters (only when the first argument is a controller) + * * ignore_errors: true to return an empty string in case of an error + * * alt: an alternative controller to execute in case of an error (can be a controller, a URI, or an array with the controller, the attributes, and the query arguments) + * * standalone: whether to generate an esi:include tag or not when ESI is supported + * * comment: a comment to add when returning an esi:include tag + * + * @param string $controller A controller name to execute (a string like BlogBundle:Post:index), or a relative URI + * @param array $options An array of options + * + * @return string The Response content + */ + public function render($controller, array $options = array()) + { + $options = array_merge(array( + 'attributes' => array(), + 'query' => array(), + 'ignore_errors' => !$this->container->getParameter('kernel.debug'), + 'alt' => array(), + 'standalone' => false, + 'comment' => '', + ), $options); + + if (!is_array($options['alt'])) { + $options['alt'] = array($options['alt']); + } + + if (null === $this->esiSupport) { + $this->esiSupport = $this->container->has('esi') && $this->container->get('esi')->hasSurrogateEsiCapability($this->container->get('request')); + } + + if ($this->esiSupport && (true === $options['standalone'] || 'esi' === $options['standalone'])) { + $uri = $this->generateInternalUri($controller, $options['attributes'], $options['query']); + + $alt = ''; + if ($options['alt']) { + $alt = $this->generateInternalUri($options['alt'][0], isset($options['alt'][1]) ? $options['alt'][1] : array(), isset($options['alt'][2]) ? $options['alt'][2] : array()); + } + + return $this->container->get('esi')->renderIncludeTag($uri, $alt, $options['ignore_errors'], $options['comment']); + } + + if ('js' === $options['standalone']) { + $uri = $this->generateInternalUri($controller, $options['attributes'], $options['query'], false); + $defaultContent = null; + + if ($template = $this->container->getParameter('templating.hinclude.default_template')) { + $defaultContent = $this->container->get('templating')->render($template); + } + + return $this->renderHIncludeTag($uri, $defaultContent); + } + + $request = $this->container->get('request'); + + // controller or URI? + if (0 === strpos($controller, '/')) { + $subRequest = Request::create($request->getUriForPath($controller), 'get', array(), $request->cookies->all(), array(), $request->server->all()); + if ($session = $request->getSession()) { + $subRequest->setSession($session); + } + } else { + $options['attributes']['_controller'] = $controller; + + if (!isset($options['attributes']['_format'])) { + $options['attributes']['_format'] = $request->getRequestFormat(); + } + + $options['attributes']['_route'] = '_internal'; + $subRequest = $request->duplicate($options['query'], null, $options['attributes']); + $subRequest->setMethod('GET'); + } + + $level = ob_get_level(); + try { + $response = $this->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false); + + if (!$response->isSuccessful()) { + throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $request->getUri(), $response->getStatusCode())); + } + + if (!$response instanceof StreamedResponse) { + return $response->getContent(); + } + + $response->sendContent(); + } catch (\Exception $e) { + if ($options['alt']) { + $alt = $options['alt']; + unset($options['alt']); + $options['attributes'] = isset($alt[1]) ? $alt[1] : array(); + $options['query'] = isset($alt[2]) ? $alt[2] : array(); + + return $this->render($alt[0], $options); + } + + if (!$options['ignore_errors']) { + throw $e; + } + + // let's clean up the output buffers that were created by the sub-request + while (ob_get_level() > $level) { + ob_get_clean(); + } + } + } + + /** + * Generates an internal URI for a given controller. + * + * This method uses the "_internal" route, which should be available. + * + * @param string $controller A controller name to execute (a string like BlogBundle:Post:index), or a relative URI + * @param array $attributes An array of request attributes + * @param array $query An array of request query parameters + * + * @return string An internal URI + */ + public function generateInternalUri($controller, array $attributes = array(), array $query = array(), $secure = true) + { + if (0 === strpos($controller, '/')) { + return $controller; + } + + $path = http_build_query($attributes, '', '&'); + $uri = $this->container->get('router')->generate($secure ? '_internal' : '_internal_public', array( + 'controller' => $controller, + 'path' => $path ?: 'none', + '_format' => $this->container->get('request')->getRequestFormat(), + )); + + if ($queryString = http_build_query($query, '', '&')) { + $uri .= '?'.$queryString; + } + + return $uri; + } + + /** + * Renders an HInclude tag. + * + * @param string $uri A URI + */ + public function renderHIncludeTag($uri, $defaultContent = null) + { + return sprintf('%s', $uri, $defaultContent); + } + + public function hasEsiSupport() + { + return $this->esiSupport; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/LICENSE b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/LICENSE new file mode 100644 index 0000000..cdffe7a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 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/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.xml new file mode 100644 index 0000000..1c0c312 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.xml @@ -0,0 +1,30 @@ + + + + + + Doctrine\Common\Annotations\AnnotationReader + Doctrine\Common\Annotations\CachedReader + Doctrine\Common\Annotations\FileCacheReader + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.xml new file mode 100644 index 0000000..33763c3 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.xml @@ -0,0 +1,60 @@ + + + + + + Symfony\Component\HttpKernel\DataCollector\ConfigDataCollector + Symfony\Bundle\FrameworkBundle\DataCollector\RequestDataCollector + Symfony\Component\HttpKernel\DataCollector\ExceptionDataCollector + Symfony\Component\HttpKernel\DataCollector\EventDataCollector + Symfony\Component\HttpKernel\DataCollector\LoggerDataCollector + Symfony\Component\HttpKernel\DataCollector\TimeDataCollector + Symfony\Component\HttpKernel\DataCollector\MemoryDataCollector + Symfony\Bundle\FrameworkBundle\DataCollector\RouterDataCollector + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.xml new file mode 100644 index 0000000..51b239e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.xml @@ -0,0 +1,32 @@ + + + + + + Symfony\Component\HttpKernel\Debug\ContainerAwareTraceableEventDispatcher + Symfony\Component\HttpKernel\Debug\Stopwatch + %kernel.cache_dir%/%kernel.container_class%.xml + Symfony\Bundle\FrameworkBundle\Controller\TraceableControllerResolver + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/esi.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/esi.xml new file mode 100644 index 0000000..9e1d57f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/esi.xml @@ -0,0 +1,20 @@ + + + + + + Symfony\Component\HttpKernel\HttpCache\Esi + Symfony\Component\HttpKernel\EventListener\EsiListener + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml new file mode 100644 index 0000000..d3efd46 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml @@ -0,0 +1,144 @@ + + + + + + Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension + Symfony\Component\Form\FormFactory + Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/form_csrf.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/form_csrf.xml new file mode 100644 index 0000000..72442bc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/form_csrf.xml @@ -0,0 +1,24 @@ + + + + + + Symfony\Component\Form\Extension\Csrf\CsrfProvider\SessionCsrfProvider + + + + + + %kernel.secret% + + + + + + %form.type_extension.csrf.enabled% + %form.type_extension.csrf.field_name% + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml new file mode 100644 index 0000000..a866660 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml @@ -0,0 +1,34 @@ + + + + + + Symfony\Component\HttpKernel\Profiler\Profiler + Symfony\Component\HttpKernel\EventListener\ProfilerListener + + + + + + + + + + + %profiler.storage.dsn% + %profiler.storage.username% + %profiler.storage.password% + %profiler.storage.lifetime% + + + + + + + %profiler_listener.only_exceptions% + %profiler_listener.only_master_requests% + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/router.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/router.php new file mode 100644 index 0000000..fb833cc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/router.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/* + * This file implements rewrite rules for PHP built-in web server. + * + * See: http://www.php.net/manual/en/features.commandline.webserver.php + * + * If you have custom directory layout, then you have to write your own router + * and pass it as a value to 'router' option of server:run command. + * + * @author: Michał Pipa + * @author: Albert Jessurum + */ + +if (is_file($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . $_SERVER['REQUEST_URI'])) { + return false; +} + +$_SERVER['SCRIPT_FILENAME'] = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'app_dev.php'; + +require 'app_dev.php'; diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml new file mode 100644 index 0000000..78aedcc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml @@ -0,0 +1,95 @@ + + + + + + Symfony\Bundle\FrameworkBundle\Routing\Router + Symfony\Component\Routing\RequestContext + Symfony\Bundle\FrameworkBundle\Routing\DelegatingLoader + Symfony\Component\Config\Loader\LoaderResolver + Symfony\Component\Routing\Loader\XmlFileLoader + Symfony\Component\Routing\Loader\YamlFileLoader + Symfony\Component\Routing\Loader\PhpFileLoader + Symfony\Component\Routing\Generator\UrlGenerator + Symfony\Component\Routing\Generator\UrlGenerator + Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper + Symfony\Bundle\FrameworkBundle\Routing\RedirectableUrlMatcher + Symfony\Bundle\FrameworkBundle\Routing\RedirectableUrlMatcher + Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper + Symfony\Bundle\FrameworkBundle\CacheWarmer\RouterCacheWarmer + %kernel.name%%kernel.environment%UrlMatcher + %kernel.name%%kernel.environment%UrlGenerator + Symfony\Component\HttpKernel\EventListener\RouterListener + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %router.resource% + + %kernel.cache_dir% + %kernel.debug% + %router.options.generator_class% + %router.options.generator_base_class% + %router.options.generator_dumper_class% + %router.options.generator.cache_class% + %router.options.matcher_class% + %router.options.matcher_base_class% + %router.options.matcher_dumper_class% + %router.options.matcher.cache_class% + + + + + + + + + + GET + localhost + http + %request_listener.http_port% + %request_listener.https_port% + + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing/internal.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing/internal.xml new file mode 100644 index 0000000..556c45b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing/internal.xml @@ -0,0 +1,18 @@ + + + + + + FrameworkBundle:Internal:index + .+ + [^.]+ + + + + FrameworkBundle:Internal:index + .+ + [^.]+ + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd new file mode 100644 index 0000000..6524528 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml new file mode 100644 index 0000000..36f01f0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml @@ -0,0 +1,55 @@ + + + + + + Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher + Symfony\Bundle\FrameworkBundle\HttpKernel + Symfony\Component\Filesystem\Filesystem + Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerAggregate + Symfony\Component\HttpKernel\CacheClearer\ChainCacheClearer + Symfony\Component\HttpKernel\Config\FileLocator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %kernel.root_dir%/Resources + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/session.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/session.xml new file mode 100644 index 0000000..2763158 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/session.xml @@ -0,0 +1,50 @@ + + + + + + Symfony\Component\HttpFoundation\Session\Session + Symfony\Component\HttpFoundation\Session\Flash\AutoExpireFlashBag + Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag + Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage + Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage + Symfony\Component\HttpFoundation\Session\Storage\Handler\FileSessionHandler + Symfony\Bundle\FrameworkBundle\EventListener\SessionListener + + + + + + + + + + + %session.storage.options% + + + + + + + + + %kernel.cache_dir%/sessions + + + + %session.save_path% + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating.xml new file mode 100644 index 0000000..40269cc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating.xml @@ -0,0 +1,61 @@ + + + + + + Symfony\Bundle\FrameworkBundle\Templating\DelegatingEngine + Symfony\Bundle\FrameworkBundle\Templating\TemplateNameParser + Symfony\Bundle\FrameworkBundle\CacheWarmer\TemplatePathsCacheWarmer + Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateLocator + Symfony\Bundle\FrameworkBundle\Templating\Loader\FilesystemLoader + Symfony\Component\Templating\Loader\CacheLoader + Symfony\Component\Templating\Loader\ChainLoader + Symfony\Bundle\FrameworkBundle\CacheWarmer\TemplateFinder + + + + + + + + + + + + + + + %kernel.cache_dir% + + + + + + %kernel.root_dir%/Resources + + + + + + + + + + + + + + + %templating.loader.cache.path% + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_debug.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_debug.xml new file mode 100644 index 0000000..0d3cebe --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_debug.xml @@ -0,0 +1,17 @@ + + + + + + Symfony\Bundle\FrameworkBundle\Templating\Debugger + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml new file mode 100644 index 0000000..3d13360 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml @@ -0,0 +1,108 @@ + + + + + + Symfony\Bundle\FrameworkBundle\Templating\PhpEngine + Symfony\Component\Templating\Helper\SlotsHelper + Symfony\Component\Templating\Helper\CoreAssetsHelper + Symfony\Bundle\FrameworkBundle\Templating\Helper\ActionsHelper + Symfony\Bundle\FrameworkBundle\Templating\Helper\RouterHelper + Symfony\Bundle\FrameworkBundle\Templating\Helper\RequestHelper + Symfony\Bundle\FrameworkBundle\Templating\Helper\SessionHelper + Symfony\Bundle\FrameworkBundle\Templating\Helper\CodeHelper + Symfony\Bundle\FrameworkBundle\Templating\Helper\TranslatorHelper + Symfony\Bundle\FrameworkBundle\Templating\Helper\FormHelper + Symfony\Bundle\FrameworkBundle\Templating\GlobalVariables + Symfony\Bundle\FrameworkBundle\Templating\Asset\PathPackage + Symfony\Component\Templating\Asset\UrlPackage + Symfony\Bundle\FrameworkBundle\Templating\Asset\PackageFactory + + + + + + + + + %kernel.charset% + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %templating.helper.code.file_link_format% + %kernel.root_dir% + %kernel.charset% + + + + + + + + + + + + %templating.helper.form.resources% + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml new file mode 100644 index 0000000..4e609a0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml @@ -0,0 +1,32 @@ + + + + + + Symfony\Bundle\FrameworkBundle\Client + + Symfony\Component\BrowserKit\History + Symfony\Component\BrowserKit\CookieJar + Symfony\Bundle\FrameworkBundle\EventListener\TestSessionListener + + + + + + %test.client.parameters% + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml new file mode 100644 index 0000000..6a37782 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml @@ -0,0 +1,139 @@ + + + + + + Symfony\Bundle\FrameworkBundle\Translation\Translator + Symfony\Component\Translation\IdentityTranslator + Symfony\Component\Translation\MessageSelector + Symfony\Component\Translation\Loader\PhpFileLoader + Symfony\Component\Translation\Loader\YamlFileLoader + Symfony\Component\Translation\Loader\XliffFileLoader + Symfony\Component\Translation\Loader\PoFileLoader + Symfony\Component\Translation\Loader\MoFileLoader + Symfony\Component\Translation\Loader\QtTranslationsLoader + Symfony\Component\Translation\Loader\CsvFileLoader + Symfony\Component\Translation\Loader\IcuResFileLoader + Symfony\Component\Translation\Loader\IcuDatFileLoader + Symfony\Component\Translation\Loader\IniFileLoader + Symfony\Component\Translation\Dumper\PhpFileDumper + Symfony\Component\Translation\Dumper\XliffFileDumper + Symfony\Component\Translation\Dumper\PoFileDumper + Symfony\Component\Translation\Dumper\MoFileDumper + Symfony\Component\Translation\Dumper\YamlFileDumper + Symfony\Component\Translation\Dumper\QtFileDumper + Symfony\Component\Translation\Dumper\CsvFileDumper + Symfony\Component\Translation\Dumper\IniFileDumper + Symfony\Component\Translation\Dumper\IcuResFileDumper + Symfony\Bundle\FrameworkBundle\Translation\PhpExtractor + Symfony\Bundle\FrameworkBundle\Translation\TranslationLoader + Symfony\Component\Translation\Extractor\ChainExtractor + Symfony\Component\Translation\Writer\TranslationWriter + + + + + + + + + %kernel.cache_dir%/translations + %kernel.debug% + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/validator.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/validator.xml new file mode 100644 index 0000000..2dad8ca --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/validator.xml @@ -0,0 +1,65 @@ + + + + + + Symfony\Component\Validator\Validator + Symfony\Component\Validator\Mapping\ClassMetadataFactory + Symfony\Component\Validator\Mapping\Cache\ApcCache + + Symfony\Component\Validator\Mapping\Loader\LoaderChain + Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader + Symfony\Component\Validator\Mapping\Loader\AnnotationLoader + Symfony\Component\Validator\Mapping\Loader\XmlFilesLoader + Symfony\Component\Validator\Mapping\Loader\YamlFilesLoader + Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory + + + + + + + + + + + + + + + %validator.mapping.cache.prefix% + + + + + + + + + + + + + + + + + + + + + + + %validator.mapping.loader.xml_files_loader.mapping_files% + + + + %validator.mapping.loader.yaml_files_loader.mapping_files% + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml new file mode 100644 index 0000000..d34ecdf --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml @@ -0,0 +1,43 @@ + + + + + + Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver + Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser + Symfony\Component\HttpKernel\EventListener\ResponseListener + Symfony\Component\HttpKernel\EventListener\StreamedResponseListener + Symfony\Component\HttpKernel\EventListener\LocaleListener + + + + + + + + + + + + + + + + + + %kernel.charset% + + + + + + + + + %kernel.default_locale% + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/css/exception.css b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/css/exception.css new file mode 100644 index 0000000..86454c1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/css/exception.css @@ -0,0 +1,228 @@ +/* +Copyright (c) 2010, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.com/yui/license.html +version: 3.1.2 +build: 56 +*/ +.sf-exceptionreset html{color:#000;background:#FFF;}.sf-exceptionreset body,.sf-exceptionreset div,.sf-exceptionreset dl,.sf-exceptionreset dt,.sf-exceptionreset dd,.sf-exceptionreset ul,.sf-exceptionreset ol,.sf-exceptionreset li,.sf-exceptionreset h1,.sf-exceptionreset h2,.sf-exceptionreset h3,.sf-exceptionreset h4,.sf-exceptionreset h5,.sf-exceptionreset h6,.sf-exceptionreset pre,.sf-exceptionreset code,.sf-exceptionreset form,.sf-exceptionreset fieldset,.sf-exceptionreset legend,.sf-exceptionreset input,.sf-exceptionreset textarea,.sf-exceptionreset p,.sf-exceptionreset blockquote,.sf-exceptionreset th,.sf-exceptionreset td{margin:0;padding:0;}.sf-exceptionreset table{border-collapse:collapse;border-spacing:0;}.sf-exceptionreset fieldset,.sf-exceptionreset img{border:0;}.sf-exceptionreset address,.sf-exceptionreset caption,.sf-exceptionreset cite,.sf-exceptionreset code,.sf-exceptionreset dfn,.sf-exceptionreset em,.sf-exceptionreset strong,.sf-exceptionreset th,.sf-exceptionreset var{font-style:normal;font-weight:normal;}.sf-exceptionreset li{list-style:none;}.sf-exceptionreset caption,.sf-exceptionreset th{text-align:left;}.sf-exceptionreset h1,.sf-exceptionreset h2,.sf-exceptionreset h3,.sf-exceptionreset h4,.sf-exceptionreset h5,.sf-exceptionreset h6{font-size:100%;font-weight:normal;}.sf-exceptionreset q:before,.sf-exceptionreset q:after{content:'';}.sf-exceptionreset abbr,.sf-exceptionreset acronym{border:0;font-variant:normal;}.sf-exceptionreset sup{vertical-align:text-top;}.sf-exceptionreset sub{vertical-align:text-bottom;}.sf-exceptionreset input,.sf-exceptionreset textarea,.sf-exceptionreset select{font-family:inherit;font-size:inherit;font-weight:inherit;}.sf-exceptionreset input,.sf-exceptionreset textarea,.sf-exceptionreset select{*font-size:100%;}.sf-exceptionreset legend{color:#000;} + +.sf-exceptionreset html, +.sf-exceptionreset body { + width: 100%; + min-height: 100%; + _height: 100%; + margin: 0; + padding: 0; +} +.sf-exceptionreset body { + font: 1em "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif; + text-align: left; + background-color: #efefef; +} + +.sf-exceptionreset abbr { + border-bottom: 1px dotted #000; + cursor: help; +} + +.sf-exceptionreset p { + font-size: 14px; + line-height: 20px; + color: #868686; + padding-bottom: 20px; +} + +.sf-exceptionreset strong { + color: #313131; + font-weight: bold; +} + +.sf-exceptionreset a { + color: #6c6159; +} +.sf-exceptionreset a img { + border: none; +} +.sf-exceptionreset a:hover { + text-decoration: underline; +} + +.sf-exceptionreset em { + font-style: italic; +} + +.sf-exceptionreset h2, +.sf-exceptionreset h3 { + font-weight: bold; +} +.sf-exceptionreset h1 { + font-family: Georgia, "Times New Roman", Times, serif; + font-size: 20px; + color: #313131; + word-break: break-all; +} + +.sf-exceptionreset li { + padding-bottom: 10px; +} + +.sf-exceptionreset .traces { + padding-bottom: 14px; +} +.sf-exceptionreset .traces li { + font-size: 12px; + color: #868686; + padding: 5px 4px; + list-style-type: decimal; + margin-left: 20px; + white-space: break-word; +} +.sf-exceptionreset #logs .traces li.error { + font-style: normal; + color: #AA3333; + background: #f9ecec; +} +/* fix for Opera not liking empty
  • */ +.sf-exceptionreset .traces li:after { + content: "\00A0"; +} + +.sf-exceptionreset .trace { + border: 1px solid #D3D3D3; + padding: 10px; + overflow: auto; + margin: 10px 0 20px; +} + +.sf-exceptionreset .block, +.sf-exceptionreset .block_exception { + -moz-border-radius: 16px; + -webkit-border-radius: 16px; + border-radius: 16px; + margin-bottom: 20px; +} +.sf-exceptionreset .block { + background-color: #FFFFFF; + border: 1px solid #dfdfdf; + padding: 40px 50px; +} +.sf-exceptionreset .block_exception { + background-color: #f6f6f6; + border: 1px solid #dfdfdf; + padding: 30px 28px; +} +.sf-exceptionreset .block_exception div { + color: #313131; + font-size: 10px; +} + +.sf-exceptionreset .block_exception_detected .illustration_exception, +.sf-exceptionreset .block_exception_detected .text_exception { + float: left; +} +.sf-exceptionreset .block_exception_detected .illustration_exception { + width: 152px; +} +.sf-exceptionreset .block_exception_detected .text_exception { + width: 670px; + padding: 30px 44px 24px 46px; + position: relative; +} + +.sf-exceptionreset .text_exception .open_quote, +.sf-exceptionreset .text_exception .close_quote { + position: absolute; +} +.sf-exceptionreset .open_quote { + top: 0; + left: 0; +} +.sf-exceptionreset .close_quote { + bottom: 0; + right: 50px; +} + +.sf-exceptionreset .block_exception p { + font-family: Arial, Helvetica, sans-serif; +} +.sf-exceptionreset .block_exception p a, +.sf-exceptionreset .block_exception p a:hover { + color: #565656; +} + +.sf-exceptionreset h2 { + font-size: 16px; + font-family: Arial, Helvetica, sans-serif; + padding-bottom: 16px; +} + +.sf-exceptionreset li a { + background: none; + color: #868686; + text-decoration: none; +} + +.sf-exceptionreset li a:hover { + background: none; + color: #313131; + text-decoration: underline; +} + +.sf-exceptionreset .logs h2 { + float: left; + width: 654px; +} + +.sf-exceptionreset .error_count { + float: right; + width: 170px; + text-align: right; +} + +.sf-exceptionreset .error_count span { + display: inline-block; + background-color: #aacd4e; + -moz-border-radius: 6px; + -webkit-border-radius: 6px; + border-radius: 6px; + padding: 4px; + color: white; + margin-right: 2px; + font-size: 11px; + font-weight: bold; +} + +.sf-exceptionreset .toggle { + vertical-align: middle; +} + +.sf-exceptionreset .linked ul, +.sf-exceptionreset .linked li { + display: inline; +} + +.sf-exceptionreset #output_content { + color: #000; + font-size: 12px; +} + +.sf-exceptionreset ol { + padding: 10px 0; +} +.sf-exceptionreset ol li { + list-style: decimal; + margin-left: 20px; + padding: 2px; + padding-bottom: 20px; +} +.sf-exceptionreset ol ol li { + list-style-position: inside; + margin-left: 0; + white-space: nowrap; + font-size: 12px; + padding-bottom: 0; +} +.sf-exceptionreset li .selected { + background-color: #ffd; +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/css/exception_layout.css b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/css/exception_layout.css new file mode 100644 index 0000000..da4fc19 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/css/exception_layout.css @@ -0,0 +1,136 @@ +html { + background: #eee; +} + +body { + font: 11px Verdana, Arial, sans-serif; + color: #333; +} + +.sf-exceptionreset, .sf-exceptionreset .block, .sf-exceptionreset #message { + margin: auto; +} + +img { + border: 0; +} + +.clear { + clear: both; + height: 0; + font-size: 0; + line-height: 0; +} + +.clear_fix:after { + content: "\0020"; + display: block; + height: 0; + clear: both; + visibility: hidden; +} +.clear_fix { + display: inline-block; +} +* html .clear_fix { + height: 1%; +} +.clear_fix { + display: block; +} + +.header { + padding: 30px 30px 20px 30px; +} + +.header_logo { + float: left; +} + +.search { + float: right; + padding-top: 20px; +} + +.search label { + line-height: 28px; + vertical-align: middle; +} + +.search input { + width: 188px; + margin-right: 10px; + font-size: 12px; + border: 1px solid #dadada; + background: #FFFFFF url(../images/input_bg.gif) repeat-x left top; + padding: 5px 6px; + color: #565656; +} + +.search input[type="search"] { + -webkit-appearance: textfield; +} + +.search button { + -webkit-appearance: button-bevel; + float: none; + padding: 0; + margin: 0; + overflow: visible; + width: auto; + text-decoration: none; + cursor: pointer; + white-space: nowrap; + display: inline-block; + text-align: center; + vertical-align: middle; + border: 0; + background: none; +} + +.search button:-moz-focus-inner { + padding: 0; + border: none; +} + +.search button:hover { + text-decoration: none; +} + +.search button span span, +.search button span span span { + position: static; +} + +.search button span { + position: relative; + text-decoration: none; + display: block; + height: 28px; + float: left; + padding: 0 0 0 8px; + background: transparent url(../images/border_l.png) no-repeat top left; +} + +.search button span span { + padding: 0 8px 0 0; + background: transparent url(../images/border_r.png) right top no-repeat; +} + +.search button span span span { + padding: 0 7px; + font: bold 11px Arial, Helvetica, sans-serif; + color: #6b6b6b; + line-height: 28px; + background: transparent url(../images/btn_bg.png) repeat-x top left; +} + +#content { + width: 970px; + margin: 0 auto; +} + +pre { + white-space: normal; + font-family: Arial, Helvetica, sans-serif; +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/blue_picto_less.gif b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/blue_picto_less.gif new file mode 100644 index 0000000000000000000000000000000000000000..dc70f6a66cd468f06725b27bd35fbf2a1f121be7 GIT binary patch literal 197 zcmZ?wbhEHb6k-r!I3mPw{q6UbW6w9<{*bcc;hV3&61F|)KK1hP$De6C9$tO(J%8`x z^qr4-PruCF^SJ-a%bV|h{QvhaZtH{p|Nk=(2NZv@FfstG(g7(4+3CRQv_OT?M|kdw zl@<*%+*nl3AJ^v0@8i0(;J={!hv^c}x{jq7EpTDY^Of5yIWuVe{u@4FhxfJkvMjiu Qv&D_=NPc2PhZBP}02D({KmY&$ literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/blue_picto_more.gif b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/blue_picto_more.gif new file mode 100644 index 0000000000000000000000000000000000000000..098e388616bf08387e170f294569efa3fabd7d8b GIT binary patch literal 213 zcmZ?wbhEHb6k-r!I3mn&{q6Vr?|-E2c)0QQhn8c{Q+7PO`sVwaufHCD{Mmi#Wx}=x z`FkJtpLve^YX(Xwd!)Vlq3luGa$EH1=Dff- k*{|A?#)-y}Z?pVFiw`FHF$7EyT^s1Mu31G+Ns+-C0Ksxq{{R30 literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/border_l.png b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/border_l.png new file mode 100644 index 0000000000000000000000000000000000000000..df27713055121a905d1105f17c4e4c9ca48b9798 GIT binary patch literal 249 zcmVNK0>rvd3;C00000NkvXXu0mjfS~+5n literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/border_r.png b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/border_r.png new file mode 100644 index 0000000000000000000000000000000000000000..fdd6dc6699d7418a90f22f706045fb40beb49cad GIT binary patch literal 253 zcmVSk!+zrx!6>i2 ztY;=K!`pA2RRv{r!*zXL%pXT()lp(xgbN3a-0R9amHu`3X5BqX00000NkvXXu0mjf D?AT_F literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/btn_bg.png b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/btn_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..303c12952684a30aa8d0903d42c3cddf6dbfaa17 GIT binary patch literal 87 zcmeAS@N?(olHy`uVBq!ia0vp^j6f{I!2%??LS)^6l$@uFV+hCf_3mj l3wbl4$&Bg~CC(=dOPoJGVbN2P?*PlOse(~bP+qZ8&e*Ad;-1*0kA78$7 z`R?7jH?H5fdiCmq`wvc?JoW9{HwIFG;!hSv1_l8J9grrFoer!s7by2VVVIlYu{yapvAW>KdDo%y|1sa$EVOTxm1J6*MUJ_ xZKi;(9(M?re%-=(dK?1GoaxoUY^)5kSE!pYxz^-q@G-J2)Z}B1c2H!n1^}rAZQB3< literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/exception_detected.gif b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/exception_detected.gif new file mode 100644 index 0000000000000000000000000000000000000000..fc412874d6f88ff0c5793f1087986984fd08c9de GIT binary patch literal 3996 zcmV;N4`c90Nk%w1VQ>I^0Qdg@<>lq!>&m~`dO<-!!otGP;iB2+wyn=ptgNhpf`ZJ< z%-ra`($dmhU0t!Uv5t<8$H&LF)oEyGXuiI_>FMc!fPkQ&pq`$djEs!6wYAdYrseI? zw9;hC-j+;EOnZBKoSd9sU|`D1%8H7Lq@<+0yu9At-rU^WW@ctsSXkHB*O!-<&(F_w zb#+8UL|a>1hK7cknwq-0x>Z$Gl9G~reSL0jZfa_3@9*!ZsHljDh@zsRn3$N5kdSb2 zaBOUBgoK1qQBi(=epXgiMn*hsg{_3+>9yx8cj^78V<-G;K#U-S6p z`uz3v`Re!j?!w!Ev(jO-(_^vGUB%mp+vvOa`|$Mi^t#q^@$>50+1b(LpY8GD-0HTq z(`Limg2>&G&*Pi)`RL&7zU%YV@b=)c(O|I9T-)2*#Kgqc=d8fme7V+b>F?T8Q&YCn zXvf}))#R<%=Cj%9u+A0FEg&sewAZ0G0a z(b3V<<)hy0y2jj#xYcXy^w+DatJLPDlgz@bldxSu^7QQR@bK~R@#^s0(9qD}>cw+&bG+Af^!4)b_u}&O?#|+w&*7iQ-H+$) z)VF?Ou+S=FUu(Q%)vC&??*?rUFsoLkcKR-YJ z|NpAZPWJZpA^8LW00930EC2ui0B`_&06+-;0RIUbNU)&6g9j&ROQrA9C30~hMl^Ow zOsZGftRdXUv7^V29AC-tN3x{JlPFWFT*>m$GmtQ0t{Ta*rp=o;ZEhnI6C@c^Ho?@X zW+!LLC796g$rZ()s(w(Rnpx7%$&x?)dPS(hsb3l{{rvcQ;-p`enjLx~^knmm)GmjX zr19!6R=+U*=J0{4$6ppqQ{V*hCm^fQ!!~!REtn0lW0q(A^g}a+j~Z3}qL_*5gw2*Q z{RX{>&@Yoe(1L0%SZt6PO_g2xO(D5Nijyd6!j4Kb$KQcQ{RlzDoMkgqLTCLU;xhO# z&UUOprgBcby2(zYqH8xu%A0lT2RcCi+D^W_M|La^^fAxAeR)RlN*)+b@Q8&0{POGH z&%giv5bhk|-he$Jaf5!xB(c#ENj#vRGe~TNgc4=wM}U9@wK73B7!vrABlzv7MTq(V zkbr*}$g^JzE%?We7Tx@yUl}9>;hz;rDByvM`B~s$Oh^FIB9Hz}fCL3v5XsL63`(FR ze;%-qM2A0?hs23bW|^fGR8~nKgAni-#4Sn4Qi_W$G%+CzJlc>%gkEmo%@W_?}^of8U46HMJQ9~v4j`>RIx=K{n#PNWKa0R zOK6Am$ksGP zKYD=mg-!90Ck9Su{Go?ib@(GlZcs^ah^m=P@dp=*%n|7sne?NHKW+4bsz0O+Led)j z2(XtQS7cF%KTCvB6{r2M;g2r;=)%%!?M<8P!Z*F5CqeY=%dnrxF!OME+$;mspW@i# z%Ech7wTw!SfOG@^6VM<*F)rwrLNOoY08f`8*R0HrJu;!hn@J?m1Tt*$7X&mq^Q=S@ zpQNB)3^dmaBmw$)aD;$Jtgv4K5du=gel|Gr4-z3*IJF5C>UY7^R`AyfK}jf`9}o&U zJ)K_Z%={J#F{&PeI`XK-X0}c=!x7-NvodlLV&hQC_fJ|V44msc= z(8*yd83__oGrnEbPulS02w67M^pDSIAi$q;B*RFaqHD*>G!x^rhZywLUeG!bpA_(9>O!+$s~Fzoc#0A3`h+=&!e>LyCorl2uXrWkw+MmY%wpdr_{6vd&blhn-^&$ zLXslMf#C<80)VE5KUDDA&mq_JV+b2~NY@|O(2s2S;}p7hLT>DUhJKWTB>6MLDEh$( zl5C%mH7OD1y^<9h5pDzKmIV6erzH+dQd|z zx=@l>=+9K#ATQ02opELKH@UsYb8?ELfnz8GPuELUgJc1@y;U(m;|Y zNTDAGSVC`D;)(K*L1HVJ!y#2s2|@H@3{P-_y9^;4f6$>Hq2QMn8j%Q7RY4MpAc$#wENFk#MeL z3FmO9J0H3K5@YD|p93+6Hcf(#jWi<$IQttvq@jY<0kkIp=m1XyX94~c0RuXC!IQMm z0t|d3q5Mbz037Kn|4fjr=eGPJP=?50F4O{tVRz z`xyW(!nz-4e1Zu4v4RO&wt^&}jvo?GLRCWsx^%Pv1qlFwllWl)2!umtkW;8)`C)~+ zDS-)tP11fO;Jc}zG-@Akn~Q9qfW-1h0jgTP zg9$8U5EDe80~9m>1s|Bl&h`p2W<;X^>agNrOtA=5aAUpNfrL41kvny~VxkyE$T+sK z%_Ur-oFQh07zQfNlE@(y5AB2VTD+1d7{Hw4cnytj@(9}1j1fD2j3-`lu>jC1$j+&R zk3B?0m%u#Sd8%UxmODIB@R^q!O3B0w3N$l4W7SA8#1M3E5r%M} z!UeEMVl1-=vp*DJ>XVoY(AyLM%Ab6gGkjqSV2}b8Y+{S;9GT}i`2{HV%m^!s z@>7awk|$UK4qd<{VL+1yrbi**HaWR=wtW~jG@>Xe(S)K>qKGSW*&kf##~ol9l{NSS zD~6CvKe&)TG|=hmQt-zbys*NRq*>LSI7|vDL6QToVG6$pURQYa2YCi?M( zQ0>|7{y4<^4p{{!aH1)vIH5mcgO^X;fhFf7PoZr>g|Zmp3dgqgAgtYwQ-u2(B(cL4 z_S}mUVu4N#4D%B}!v!`7XDgVB$|00voI(i9Hv$NiN}`bJvDXCC&mzhHA-CWJDU8Ai zYoJrNH}QnRK z2r&r-zyY~44XKc2QWz7iumA;+3>@Yh#t?&BSS5>46Bq6H6N0^EgRtPpi3p%^U%4bin&E&u|6Fozreu?hu{cm+@&F>qZj zk^;jJh-G*LC9oepa0^ht1WW)0kVC1Q2j0{J;a6_#;Sw0Q&)mUn7tDkq!}Z1jFzFSychI zP+b_HAF{AHA`mtnZ~;Gc1ZDFgN(CY=qh2ASj%6SL(0~Ns5F!u2Qb=G^`9TEAuv7iP z0!M%gFa(nmfQ%F{0Us~}&fr=6a17y) zT`r&uw8$SRU;+-nAH@Iw&Zr-efF$_=1N_Jj6Tkon@BlCniy@N)=QUf8<03O40Yp#+ z4KQB)aRXsv1Wy@P6QT?|Fas_U1Wv;sO)!e1Xd}4cGXYItk3`}Evd{z-pimwl z3p6P@0tNv>AeUJ}0uka1rFjDXfCD#Knl?ZJ&7fE7MK`*5mq5uM3VjDT_z|nqu-K zqQxVb7@l8q3{PU4N}>YZDVEV_j7OjZTf-v{&;(Y)BN?CsBuOMjLZ8*81ip}6`SAju zpjSzdH2q-%fG{O*QUm@W0V~y+4@Fa>2nC@iT)0R#J~N_BAY2{7S|eJbZxRy$0RTJJ C!j+l; literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/exception_detected.png b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/exception_detected.png new file mode 100644 index 0000000000000000000000000000000000000000..c56c3d2ae3dc77c511c8f123335a3b73b604f01d GIT binary patch literal 3637 zcmV-54$AR~P)c!CEqQKdIu+Utp%}%z{ zXvN!!)#R<@?9S@&+|uKwzu9`P&|1UWh1=-6@bl>L^Xk;(tGCo__4f4T?a{>Bhpf(0 z&ET8k?99E_c&o=?^3LF$%ixo-(OufBVW60l({QddT<)PK)sO|LH=<(0R-G=G! z+Og4I-Rro!*KxDbVY1R+_WJDd_vGB_wy@D!>GILX-iqSx!{_nMuh3Zi{`>X$>hSj9 z!P|cL`|!ZpeAnl!=J3n$_u{_Uc+caT>hsgn<)hi@u>Su2*yyh8^w+%DbJpjo-|W1r z&QQwUmc!hFw$x|t_1x?8)y(0Qz1ViT)^GRv?!?@L!rOqZ&sfmoo%#Fo&f=NI-H7!0 z=-%wQ$={E;)@}Oy_51zz@Alr~@5RdCk>TyZ&El8QF7?Y_p`i`wV8 z&*7iD)^yb7rM}pC$lZ^@+JWKf$La6b?(*cb(qiA~!|(FuzuA4X(q#7b_T}Z}zP`Sa zl9Fg>Xk=t$L_|bCKR;MlSbKYWsHmva)YS6w^0l?KW@cteN=lB7j^5th@bK`Onwm^Z zOmlN{*Vot3(9m03Tb!JnprD{ZK|x?(VBz86gwwG`T6(v_x1JlhK7bwQBm95+lq>cYHDiC z%*;qgNa^Y6?Ck86l$4~Tq=JHi#Kgqf+S>8)@v^eA!otGq>+8Y6!SwX>$H&K0Q&X6j zn4X@VPEJm&tgNrEuYiDn?d|Q#%F36Qmu_xu*x1;FgoMw}&(YD*($dn9kdX89^Ho(< z;^N}5v9WAyY@(u~R#sN4tE+x~etms?+}zyn@9(<0y12NwP|ZzQ00001bW%=J06^y0 zW&i*R<4Ht8RCwC$nSERpWfsTBTvOaKkG+Aen|0e>REoeh;FKU>3kre>h)Vc!5xEIM zND!KUfthXDo7?V=iaub7_);p68Kqnu^p3Assacj~mSvl!xx3a@d!F%r?tPHGICGi! zYrlWMJTvh8o^$4$=bV|5bkOCBuD|Kl?aJ<)9^HJp_PpY^(yzr;SNFQ6H?*bCwbxy5 zzS<2p`a(PS_3igN6V>|v{wBCQ*Yq4=H z;~yO2IdCr5fei4%p`m!c_fCBPj4%{9Vd2BTMPNi^)NrvvKG=T5{0R&YjWNI(F#=#@ zbZp$Hcz^^XMvJ>@yMkT82oK?y=*YN;#H2WgPex*FVhWBMKLL})irilM59k8|DX9;q zdFUi2MopUR4^xmc#)4K$I!+D97>m<_F%xW7OawQNw718Az%WD%6GWzG0Su3_W(R|1 z5)yIo6LCgP?xO&CICKV%2bhTo`IrijjACtjter~L1Kbo~_%sTNkVG;y(*nMQm<>6| z$$uR4io#}LdJ&&}^lV!;rbXcsK$pkN!La}{Fa-qe@$6AQA=-+O2b+IMDL^Vt4=KUY zFiSBGn~SmWbMZ+4UyRH^x>$-C_hVQA7Dj|7VOSy-0+i8pU14)GxXHzmoC(q8mT=67 zkHxfk7-fT}aDG09$3QAy%Xlme47Y}bS*;^Oah~mdBr&z=OuZOt|drvWh@ zOG4u?)IS-mk-1rUNDO@fAM#Bt2n5fh+!QKq0Xrfkzg3!VbL#mAC){+I-M^6&*PMj~WlRP?0mDd0Z_5v@h>g*bmEH?I&! z>M0l3K^uz3xoYqNSF02f!D0-T#3K4Gz%m=8kadusX-UEi>sWsnP1`&aU>wZD2q9*4cip+^}<8pyF?UJRB( z8O|?596bsj2S|%a!KvjKX@My2Y+E4)7ZqbbMmQ4rFoJ?7xrlt?YjZc|gWKuag1}8y z5>5#kiG{WjjLE}j7={zT5@hZ&Y(-3i$0H*bTA)4JZN0DZ6Wg|ET5yupKN~aW z45jEChsB6fAd%->aU#Ho;Nft2UX&!ACT3vxlQCr&3Asr~jE9UkOd7?l2}p@a1f2}L z<1&w@Bh z9lZP)n8l#M`rgwF1ala&NYY1Flk_O%J5%v5MqYp4)p4)(=^`276@Ta$H~m#I#>+v_ z5&B+b{Bz8e;5GjJByZ^FZ9?AW?bnh;&v<3tjRPdFdGHo6NZ=#=JNPl^MKFNHhk~=C zT=6&E&h+UbnL?Ldf7kQa+11Riv)A9(e${&Zfkl$pEV`#xUk_hOdzh^z22sCfyWP^g zyO^SuSEOH`Yr)NpQYUb$ka>eUL-1t}v3c?}=P4&te){0fNt4-7Vy|eLo$#rJU+I6fguf1-Tc?I_Fw?2;@(JHlWT(9H zDkG{iy^D&qG=ASaLHQufcgW$IP<1rWiNkyW&J}z><8?<&6I8hiKUCZcP`E`$RLQ-9 z19aje=K_u{`Pe&SKUuo;9a)>9o=>L=E2yK4aLB?6c;wcq+VQbZ8T-r|MfosIvi}o0 zXknKM9;bV%NNzO2{n}sb`kW3wRlRZK2}Z1zod;j2lDw&k)qlB_E^Ve0Cuu2PHL!KZ z`I@*(S1FobxH~EpZv;Q$ksy=c*Nix%O4V;N;?yUS+MwMsc{SHz$7T5&#yP4P%aigS z1_k9~2P)R9@6lRo6%wpv#EzZhV~ua+(^^`nGF{-7sbn!{ll;a*qtfUQ<9w&CWCXvPTeOYsG+od*vUdmLe6xBv`&!w@ScSu&;8|^geUyIhE~z?q z#5wPW-`8v9Z|72HiCBG}ah5G^U>e)rUB%e$D#n(aIZ?aY$mU8np0n!Wuf-&&vH5*Q ztZj7FijV(EKMx$-;~amZvQ^;es0HDs~*$F18u_8`$UEJg1=Q*!iz> z%*h@j_fY<#vF6am3R>o|@9ho})B_2s4toVzu8k^;M5)qjr%FezI^66~6y1WdEGz$J z>;m5k8;=^w3sqIrT|DW|%Cf3oP?C8hpJ+OBe!bmr?#o*lvEjrT{eo)C4~*F8aFAnU z!-Dd1##vWY$y}UjX|3LJRJi!#250`LvML+aqZ_%IwP8u~330gmWb>EoQr4YRy)1*( zjco;0N^Un*vQp7T?_0r}22Hdd`+?F*3Uf9BnXo8#wSZ*FSlt(Mn{D(?dAVw|+lY==K*ob4@={JrSly%d{Vu0v27 zDx%=Iy)jXiO{|lNgSkFX0FiWu2p1MaIR5FoGW(j`H1Wt*AeN1GHS%M!jfeYf`bukgoDP{?7 zV{Q(d6`H6TyVz|VQY3Sb9d9xhwatQqS2|9&DqUs?D#zR*vsF3ia${q&>TsKQN>L?~ zP#qVX@xNiOLsj-xIu)uFSy6v<>Q(SZa+8qN=562AG}JVn-{qio#c}rhYc{>4rT zRHVOpt7dym)h`Zipm~Z^iJO}2ytvYUx>juYH z0D^Y*AYBhfdtYY{Z|hju|4aK!Hk+|Em85|8xE4{xAAL-`mID zH_!AxD^!6aQ2l(X{{j%F{b%_vkq2~9io<_Sr~((D`c5-Am*GEu3{XLy<9{BgKoZc3 z2-p8yFh8x7asq1Uvii>rRWRQQ250VyAfim;BEHvs2)+P7g{zfnbt3LIKNvq5tYvY!UK&bj(3Q7V-u^$a7^EJg@9f#LU;{Kr(Tt1(0s@wR46q?b^YiD=S2#O6 z{{R`_fK34qoCo6lAR34K99LIYyap72%!rOqjVej6(%^<@- z2B>`d_N}q2tLv_>ukTkRv!lS0swdLLTpmpZCd~U002ovPDHLkV1jKGbGrZl literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/input_bg.gif b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/input_bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..7c0efc1087c3cedd2a95deaef7322d4770170ff3 GIT binary patch literal 63 zcmZ?wbhEHbWMp7vSj52a_3PL7@8AFZ`}fzcU$0)hVt@g~pDbXe4u}M)WngCUU{vO0 Gum%7TE)u5z literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/logo_symfony.gif b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/logo_symfony.gif new file mode 100644 index 0000000000000000000000000000000000000000..703cf45fc78e6d31d4a9af460252b536b1c9854e GIT binary patch literal 1698 zcmV;T23`3_Nk%w1VYUE10K^&q%gfAUVr4x$Kl1YON=QuQ<>lDe*q4@=v9Pj!eSesj znO9X=ad2|Jy}yf!jHIKbv9Yp#e1F*3*>P`jS5;V~q@}*Tzl({C|Ns9mE;9fB{{R30 z000000000000000A^8LW000^QEC2ui0JZ==06+!*peBxFX^z0-1i_MJ3+p_pEh_&5dM^QH^o`2q?YC;|Y#eo6?SBFL~IkO9*W zUWrg(6a+6t1e9~gkzoUD0u)q?cL8IkHxMNMW_YDz4U&xn4G;-%fMrJwrreB*aD?3_ z1wa){Fo|t|jsdNTB$!ozNI7K6ROJ$p6pPVgF9`4wMB>|mt0D|wjG70m21m-KH6S4q zhKOfKG;JyM!j7010!F!0IkQPpts|OdaKxZQty_Z;XW06P@mIDOfgM&{!i#`0fD`e3 zQEdyS&0Nj2C9?Kr8lnz-R4p>0a~KE_K`S#&yS5Dk42ZH}fWWNn-@r{EpxZBi&EUv6 z8aN0#2?2n~qoYCA9N}^4*n51eZlv`Vo}$7KN0+^P4l3M z2>3zos9Q+@lo%19fEJ&v_eMl=Ver}i6~3L26fm|Wb=^(lB>@IXO1OprcmzanA$V+L zb^~<*z@))9>6GxyTD2hYPk$N-mINXQ^p_PtcqCwBVHzYQp9trqhK*03$jI3zp=`EL z4gk;<4l+DyFhEu)P)UL+z8NDzFH^jr%?TK>h?fa6iXfN(BusNv6&G%ik!z~7xy6*t zIl-j}Y9eFPWF!!y%L|M_g5H-VU{nL2eF8edifzfKN)iT20F<12yZv3FsjK z;Rr5efTm$DL^*<=i7qz6og;{q#A5}anraE7fn!1!py{+pbtXdbOp509;L?wY*qD(5 z06@@Q5uSu`O>_G}VTmEZ{vb*JgE&xUL1w2rpe-Fev@4h-90G~<(Y|8JzQl6785e#5UFuM(io2~!?FPxpW2UiiX#KE~* z@e34008|A3Hij{FaHUIu9SUF;&k<9N3>-uiQxHZ4U%WA%01CV85UvN?MKf#F{QQ#6 zwS{a20W27sMHohcl(Pv9{JSJU??&s;yP0%mi5&wxi^V4(W-tK+3tD074XPv%P67Jn zgWlPu)oR5^7&M*1$rz+WHy1@*`e+rU;lOHbgVTm}65KMKgaFOHA#`1H_0h5o&rIGb zE)5zmMj3GkP)KY67-azeT>((?w-JLB@U8#{nAQ0qC1>EkRbD)Is|#A0lK2~y79sN} zNG@y24sdXt_r~;iTHpx_=E*BaSP{$|$EWviZgdX{vBSluA zfC7ZqxHo|4cW)@0O6rG$hWUwSS3w4Z5G8{2&1zKz6h<&!@COo>P*Ep(L223&B{pG- z2y^&^Ds~qJqs^mjH~7XN@K6{!CC`PjdZDVeRKRC^iZLxrq7p~2JUof2D@uqT9E_kv z39)c17fSdz2oVk(|*9gP26mT@rLI(4sh?6#MCjsXOoCcz2gl2{9QVN>M zDBh=%)a0N50dPS1QV22^6&KcVi9jlXAybu*3hZqF zu;Jn-Qqr8K6@)kfNWj!GMXb&_vW`!zqp1P`D-sM~lX-ZeEsNm?6HFs{LTHX2-e5P0 zkjo5$5s}2!XM@Adqk=r!%(|SQh-ZjzVV3BW)ka{=J|u_>4l{-2o)9YhVN4aQ+W{Xl zVi%ZY#c|acCDCl7u_MR{1AEbx1k!1WaqiPJ^IWEzLb9vsZ1bQIlEVaoGL-Z@6r#YP s-o}b>F^nP~2bk%~rANzE00$7X3b6#@NZAEF2Ha}_46x5i%M$_sJDrx#NB{r; literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/logo_symfony.png b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/logo_symfony.png new file mode 100644 index 0000000000000000000000000000000000000000..1ce063dbd18de9998794b299f9f752f212dddc8a GIT binary patch literal 1459 zcmV;k1x)&hP)K0000{P)t-s|NsBX z%gm&srHhJ;WMXAkRar1DGUesvv9PjANKEqb@^Nr-*x1;KUY;)etdtJmzn?n z|FN;M*x1=|Z*ruhrI(hNetmz7iHyF!zsO|%wEzGB0d!JMQvg8b*k%9#1rSL@K~#9! z)tcLuqaYAPEkzJS63qoW|No(56(U~3kYut}Gv^_(NoY6ap$h0OVuG?_tmeFCtSX`S zA0$e~cVeZ;9J*orsaTUUwB%9AT*0B{f0fM9<*MRIwJJAiUGoh^yqAqMC$2%$E|kbx5e8UKU?5vzLh{HFQxH9KM%@JP2d}K#Y*fgQ-9to7&7QQ ztl-RbxDLL7?DF6n+4lf6fHRPwi(@ZPE(7WA^EcZ$YPYaqt7pj6 zd@1=@05=*W=hUnjUFfOR3(5=Xlc4BNz^{EU=m!1t}> ze#y>!5NpoMWi%ZE`Ww}Lk!*xmd9!HDdbf%_MiZv~xRi;C^QtKLKH8+8uo?+^ocLZl zn@$>q_g?LSGw~6`1m1ylTpb`}Rdm+Msf)E8%`wveSmO$U^X1fl5vPyMQf9;f`%HjK zTz>{qKk4Sj9!(``ARsY0aANUO6A(++S_>CsN9Za=^?3s(a&;D0NTal0D_oH zHGk0cl}EIngFpc{o%2RHdqg`3?UQ>mKLsAJDcBIqrotDCjzBHJlSj$}HpQ1DR)csX zun*vxZr(aN>1d_u;B@v5HU(7p^4H?^7Mp#5y-bp7w$3*9 zDOY4r5b}zQKt~o$HIV?uMY(66#%>eXJ|#(fIbaWNK}y)JiN+FDyk0vOHW-`(cG}x; z#HIqEefq8!ga@*Q{BeI_Mw-}eNf+*Uww$Y%uyt5-H}rdt*xiI&`E^hmyuG;iIy=Mo z+7lCtEEnXQ0T>!3jZN?Cyls!z^c0Nb@~|bl%vGlM*@O8M9#gf(6|8CiN{Ll1Jjm`v zY++ncvUX!c)ITaJ?CB$7>8pH1sq-{}bMuR$#b5e#=bWhQsU3Rz<%7bKJQosHL{#M?qe`Bp z32481PN=|ck5i&9P>Enea%bHYUz73KFBR@vBG@dovo>F(2HItApXVCQ^l&*X9*L)s zM3SH__csLqDt>rL%ReQ39=Y>Gh5S|3yUoqdTx+gzYN>MiLm7DNGg6y`MSfe&=D-0A zKPh^Psw}dQT~|hKdY}5DDLWI5;hdOskqPR|xXmq`<>XIIJ_*X6I;b%@{+mErqE18C zy2wv96>wW*DK-Ap)uPB%qKZV^Aau@Z+9P?}s3L!XZP_vlTML=t{Q>1VgP8{u0!9D; N002ovPDHLkV1gV()aL*I literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/open_quote.gif b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public/images/open_quote.gif new file mode 100644 index 0000000000000000000000000000000000000000..0e116ceadd25fcab384427f1e9076869a3201c82 GIT binary patch literal 281 zcmZ?wbhEHblwlBKI3mDs>(=dOPoJGVbN2P?*PlOse(~bP+qZ8&e*Ad;-1*0kA78$7 z`R?7jH?H5fdiCmq`wvc?JoW9{HwIFG;!hSv1_l8J9grrFoer$i6jb^I3@sQ}u5x>z z<3DHJD*^ihx9-&3S<@Hi&+>qift8t8=!L0J^V|#UbM7srenderBlock('widget_attributes') ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/checkbox_widget.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/checkbox_widget.html.php new file mode 100644 index 0000000..fff427d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/checkbox_widget.html.php @@ -0,0 +1,5 @@ +renderBlock('widget_attributes') ?> + value="escape($value) ?>" + checked="checked" +/> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_options.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_options.html.php new file mode 100644 index 0000000..eae0d92 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_options.html.php @@ -0,0 +1 @@ +renderBlock('choice_widget_options') ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget.html.php new file mode 100644 index 0000000..99db4ac --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget.html.php @@ -0,0 +1,5 @@ + +renderBlock('choice_widget_expanded') ?> + +renderBlock('choice_widget_collapsed') ?> + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php new file mode 100644 index 0000000..b0c601e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php @@ -0,0 +1,13 @@ + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_expanded.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_expanded.html.php new file mode 100644 index 0000000..58de38d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_expanded.html.php @@ -0,0 +1,6 @@ +
    renderBlock('widget_container_attributes') ?>> + + widget($child) ?> + label($child) ?> + +
    diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_options.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_options.html.php new file mode 100644 index 0000000..66c664f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_options.html.php @@ -0,0 +1,11 @@ + $choice): ?> + isChoiceGroup($choice)): ?> + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/collection_widget.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/collection_widget.html.php new file mode 100644 index 0000000..9f6a94b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/collection_widget.html.php @@ -0,0 +1,4 @@ + + escape($view['form']->row($prototype)) ?> + +widget($form, array('attr' => $attr)) ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/container_attributes.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/container_attributes.html.php new file mode 100644 index 0000000..3edfa44 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/container_attributes.html.php @@ -0,0 +1 @@ +renderBlock('widget_container_attributes') ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/date_widget.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/date_widget.html.php new file mode 100644 index 0000000..439443c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/date_widget.html.php @@ -0,0 +1,11 @@ + + renderBlock('form_widget_simple'); ?> + +
    renderBlock('widget_container_attributes') ?>> + widget($form['year']), + $view['form']->widget($form['month']), + $view['form']->widget($form['day']), + ), $date_pattern) ?> +
    + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/datetime_widget.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/datetime_widget.html.php new file mode 100644 index 0000000..6864874 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/datetime_widget.html.php @@ -0,0 +1,7 @@ + + renderBlock('form_widget_simple'); ?> + +
    renderBlock('widget_container_attributes') ?>> + widget($form['date']).' '.$view['form']->widget($form['time']) ?> +
    + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/email_widget.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/email_widget.html.php new file mode 100644 index 0000000..0ef4d9d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/email_widget.html.php @@ -0,0 +1 @@ +renderBlock('form_widget_simple', array('type' => isset($type) ? $type : 'email')) ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_enctype.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_enctype.html.php new file mode 100644 index 0000000..baab129 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_enctype.html.php @@ -0,0 +1 @@ +renderBlock('form_enctype') ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_errors.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_errors.html.php new file mode 100644 index 0000000..d4cbe1b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_errors.html.php @@ -0,0 +1 @@ +renderBlock('form_errors') ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_label.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_label.html.php new file mode 100644 index 0000000..71d055c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_label.html.php @@ -0,0 +1 @@ +renderBlock('form_label') ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_rest.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_rest.html.php new file mode 100644 index 0000000..fe9bae0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_rest.html.php @@ -0,0 +1 @@ +renderBlock('form_rest') ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_row.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_row.html.php new file mode 100644 index 0000000..8077ff3 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_row.html.php @@ -0,0 +1 @@ +renderBlock('form_row') ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_rows.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_rows.html.php new file mode 100644 index 0000000..b9a07bc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_rows.html.php @@ -0,0 +1 @@ +renderBlock('form_rows') ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_widget.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_widget.html.php new file mode 100644 index 0000000..2621130 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_widget.html.php @@ -0,0 +1 @@ +renderBlock('form_widget_simple') ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_enctype.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_enctype.html.php new file mode 100644 index 0000000..5a5e4b1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_enctype.html.php @@ -0,0 +1 @@ +getVar('multipart')): ?>enctype="multipart/form-data" diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_errors.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_errors.html.php new file mode 100644 index 0000000..339e3d0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_errors.html.php @@ -0,0 +1,21 @@ + +
      + +
    • getMessagePluralization()) { + echo $view['translator']->trans( + $error->getMessageTemplate(), + $error->getMessageParameters(), + 'validators' + ); + } else { + echo $view['translator']->transChoice( + $error->getMessageTemplate(), + $error->getMessagePluralization(), + $error->getMessageParameters(), + 'validators' + ); + }?>
    • + +
    + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_label.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_label.html.php new file mode 100644 index 0000000..c8f7947 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_label.html.php @@ -0,0 +1,3 @@ + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_rest.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_rest.html.php new file mode 100644 index 0000000..89041c6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_rest.html.php @@ -0,0 +1,5 @@ + + isRendered()): ?> + row($child) ?> + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_row.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_row.html.php new file mode 100644 index 0000000..6f99415 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_row.html.php @@ -0,0 +1,7 @@ +
    + label($form, isset($label) ? $label : null) ?> + + errors($form) ?> + + widget($form) ?> +
    diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_rows.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_rows.html.php new file mode 100644 index 0000000..a5f1dfb --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_rows.html.php @@ -0,0 +1,4 @@ +errors($form) ?> + + row($child) ?> + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget.html.php new file mode 100644 index 0000000..0e63418 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget.html.php @@ -0,0 +1,5 @@ + +renderBlock('form_widget_compound')?> + +renderBlock('form_widget_simple')?> + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_compound.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_compound.html.php new file mode 100644 index 0000000..705664b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_compound.html.php @@ -0,0 +1,4 @@ +
    renderBlock('widget_container_attributes') ?>> + renderBlock('form_rows') ?> + rest($form) ?> +
    diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_simple.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_simple.html.php new file mode 100644 index 0000000..29649cf --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_simple.html.php @@ -0,0 +1,5 @@ +value="escape($value) ?>" + renderBlock('widget_attributes') ?> +/> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden_row.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden_row.html.php new file mode 100644 index 0000000..3239d8f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden_row.html.php @@ -0,0 +1 @@ +widget($form) ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden_widget.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden_widget.html.php new file mode 100644 index 0000000..7dc71ae --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden_widget.html.php @@ -0,0 +1 @@ +renderBlock('form_widget_simple', array('type' => isset($type) ? $type : "hidden")) ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/integer_widget.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/integer_widget.html.php new file mode 100644 index 0000000..14000a5 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/integer_widget.html.php @@ -0,0 +1 @@ +renderBlock('form_widget_simple', array('type' => isset($type) ? $type : "number")) ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/money_widget.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/money_widget.html.php new file mode 100644 index 0000000..6c84a87 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/money_widget.html.php @@ -0,0 +1 @@ +renderBlock('form_widget_simple'), $money_pattern) ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php new file mode 100644 index 0000000..c3344d8 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php @@ -0,0 +1 @@ +renderBlock('form_widget_simple', array('type' => isset($type) ? $type : "text")) ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php new file mode 100644 index 0000000..ab0bcaf --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php @@ -0,0 +1 @@ +renderBlock('form_widget_simple', array('type' => isset($type) ? $type : "password")) ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php new file mode 100644 index 0000000..38b51c0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php @@ -0,0 +1 @@ +renderBlock('form_widget_simple', array('type' => isset($type) ? $type : "text")) ?> % diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/radio_widget.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/radio_widget.html.php new file mode 100644 index 0000000..3ecad14 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/radio_widget.html.php @@ -0,0 +1,5 @@ +renderBlock('widget_attributes') ?> + value="escape($value) ?>" + checked="checked" +/> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/repeated_row.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/repeated_row.html.php new file mode 100644 index 0000000..b9a07bc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/repeated_row.html.php @@ -0,0 +1 @@ +renderBlock('form_rows') ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php new file mode 100644 index 0000000..e071e95 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php @@ -0,0 +1 @@ +renderBlock('form_widget_simple', array('type' => isset($type) ? $type : "search")) ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/textarea_widget.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/textarea_widget.html.php new file mode 100644 index 0000000..a82744b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/textarea_widget.html.php @@ -0,0 +1 @@ + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/time_widget.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/time_widget.html.php new file mode 100644 index 0000000..fb7f94c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/time_widget.html.php @@ -0,0 +1,18 @@ + + renderBlock('form_widget_simple'); ?> + +
    renderBlock('widget_container_attributes') ?>> + widget($form['hour'], array('attr' => array('size' => 1))); + echo ':'; + echo $view['form']->widget($form['minute'], array('attr' => array('size' => 1))); + + if ($with_seconds) { + echo ':'; + echo $view['form']->widget($form['second'], array('attr' => array('size' => 1))); + } + ?> +
    + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/url_widget.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/url_widget.html.php new file mode 100644 index 0000000..d88767b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/url_widget.html.php @@ -0,0 +1 @@ +renderBlock('form_widget_simple', array('type' => isset($type) ? $type : "url")) ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget_attributes.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget_attributes.html.php new file mode 100644 index 0000000..210b84c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget_attributes.html.php @@ -0,0 +1,10 @@ +id="escape($id) ?>" +name="escape($full_name) ?>" +readonly="readonly" +disabled="disabled" +required="required" +maxlength="escape($max_length) ?>" +pattern="escape($pattern) ?>" + $v): ?> + escape($k), $view->escape(in_array($v, array('placeholder', 'title')) ? $view['translator']->trans($v, array(), $translation_domain) : $v)) ?> + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget_container_attributes.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget_container_attributes.html.php new file mode 100644 index 0000000..2a8e979 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget_container_attributes.html.php @@ -0,0 +1,2 @@ +id="escape($id) ?>" + $v) { printf('%s="%s" ', $view->escape($k), $view->escape($v)); } ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_errors.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_errors.html.php new file mode 100644 index 0000000..154b6e2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_errors.html.php @@ -0,0 +1,51 @@ + + +
      + +
    • getMessagePluralization()) { + echo $view['translator']->trans( + $error->getMessageTemplate(), + $error->getMessageParameters(), + 'validators' + ); + } else { + echo $view['translator']->transChoice( + $error->getMessageTemplate(), + $error->getMessagePluralization(), + $error->getMessageParameters(), + 'validators' + ); + }?>
    • + +
    + + + 0): ?> + + + +
      + +
    • getMessagePluralization()) { + echo $view['translator']->trans( + $error->getMessageTemplate(), + $error->getMessageParameters(), + 'validators' + ); + } else { + echo $view['translator']->transChoice( + $error->getMessageTemplate(), + $error->getMessagePluralization(), + $error->getMessageParameters(), + 'validators' + ); + }?>
    • + +
    + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_row.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_row.html.php new file mode 100644 index 0000000..03daaf1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_row.html.php @@ -0,0 +1,11 @@ + + + label($form, isset($label) ? $label : null) ?> + + + + errors($form) ?> + + widget($form) ?> + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_widget_compound.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_widget_compound.html.php new file mode 100644 index 0000000..9c90f15 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_widget_compound.html.php @@ -0,0 +1,4 @@ +renderBlock('widget_container_attributes') ?>> + renderBlock('form_rows') ?> + rest($form) ?> +
    diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/hidden_row.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/hidden_row.html.php new file mode 100644 index 0000000..dd433ea --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/hidden_row.html.php @@ -0,0 +1,6 @@ + + + widget($form) ?> + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php new file mode 100644 index 0000000..a1baa9a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.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\Bundle\FrameworkBundle\Routing; + +use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser; +use Symfony\Component\Config\Loader\DelegatingLoader as BaseDelegatingLoader; +use Symfony\Component\Config\Loader\LoaderResolverInterface; +use Symfony\Component\HttpKernel\Log\LoggerInterface; + +/** + * DelegatingLoader delegates route loading to other loaders using a loader resolver. + * + * This implementation resolves the _controller attribute from the short notation + * to the fully-qualified form (from a:b:c to class:method). + * + * @author Fabien Potencier + */ +class DelegatingLoader extends BaseDelegatingLoader +{ + protected $parser; + protected $logger; + + /** + * Constructor. + * + * @param ControllerNameParser $parser A ControllerNameParser instance + * @param LoggerInterface $logger A LoggerInterface instance + * @param LoaderResolverInterface $resolver A LoaderResolverInterface instance + */ + public function __construct(ControllerNameParser $parser, LoggerInterface $logger = null, LoaderResolverInterface $resolver) + { + $this->parser = $parser; + $this->logger = $logger; + + parent::__construct($resolver); + } + + /** + * Loads a resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return RouteCollection A RouteCollection instance + */ + public function load($resource, $type = null) + { + $collection = parent::load($resource, $type); + + foreach ($collection->all() as $route) { + if ($controller = $route->getDefault('_controller')) { + try { + $controller = $this->parser->parse($controller); + } catch (\Exception $e) { + // unable to optimize unknown notation + } + + $route->setDefault('_controller', $controller); + } + } + + return $collection; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Routing/RedirectableUrlMatcher.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Routing/RedirectableUrlMatcher.php new file mode 100644 index 0000000..ffbb648 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Routing/RedirectableUrlMatcher.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\Bundle\FrameworkBundle\Routing; + +use Symfony\Component\Routing\Matcher\RedirectableUrlMatcher as BaseMatcher; + +/** + * @author Fabien Potencier + */ +class RedirectableUrlMatcher extends BaseMatcher +{ + /** + * Redirects the user to another URL. + * + * @param string $path The path info to redirect to. + * @param string $route The route that matched + * @param string $scheme The URL scheme (null to keep the current one) + * + * @return array An array of parameters + */ + public function redirect($path, $route, $scheme = null) + { + return array( + '_controller' => 'Symfony\\Bundle\\FrameworkBundle\\Controller\\RedirectController::urlRedirectAction', + 'path' => $path, + 'permanent' => true, + 'scheme' => $scheme, + 'httpPort' => $this->context->getHttpPort(), + 'httpsPort' => $this->context->getHttpsPort(), + '_route' => $route, + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php new file mode 100644 index 0000000..1013334 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Routing/Router.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\Bundle\FrameworkBundle\Routing; + +use Symfony\Component\Routing\Router as BaseRouter; +use Symfony\Component\Routing\RequestContext; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface; + +/** + * This Router only creates the Loader only when the cache is empty. + * + * @author Fabien Potencier + */ +class Router extends BaseRouter implements WarmableInterface +{ + private $container; + + /** + * Constructor. + * + * @param ContainerInterface $container A ContainerInterface instance + * @param mixed $resource The main resource to load + * @param array $options An array of options + * @param RequestContext $context The context + */ + public function __construct(ContainerInterface $container, $resource, array $options = array(), RequestContext $context = null) + { + $this->container = $container; + + $this->resource = $resource; + $this->context = null === $context ? new RequestContext() : $context; + $this->setOptions($options); + } + + /** + * {@inheritdoc} + */ + public function getRouteCollection() + { + if (null === $this->collection) { + $this->collection = $this->container->get('routing.loader')->load($this->resource, $this->options['resource_type']); + $this->resolveParameters($this->collection); + } + + return $this->collection; + } + + /** + * {@inheritdoc} + */ + public function warmUp($cacheDir) + { + $currentDir = $this->getOption('cache_dir'); + + // force cache generation + $this->setOption('cache_dir', $cacheDir); + $this->getMatcher(); + $this->getGenerator(); + + $this->setOption('cache_dir', $currentDir); + } + + /** + * Replaces placeholders with service container parameter values in route defaults and requirements. + * + * @param $collection + */ + private function resolveParameters(RouteCollection $collection) + { + foreach ($collection as $route) { + if ($route instanceof RouteCollection) { + $this->resolveParameters($route); + } else { + foreach ($route->getDefaults() as $name => $value) { + if (!$value || '%' !== $value[0] || '%' !== substr($value, -1)) { + continue; + } + + $key = substr($value, 1, -1); + if ($this->container->hasParameter($key)) { + $route->setDefault($name, $this->container->getParameter($key)); + } + } + + foreach ($route->getRequirements() as $name => $value) { + if (!$value || '%' !== $value[0] || '%' !== substr($value, -1)) { + continue; + } + + $key = substr($value, 1, -1); + if ($this->container->hasParameter($key)) { + $route->setRequirement($name, $this->container->getParameter($key)); + } + } + } + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Asset/PackageFactory.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Asset/PackageFactory.php new file mode 100644 index 0000000..de36a32 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Asset/PackageFactory.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\Bundle\FrameworkBundle\Templating\Asset; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpFoundation\Request; + +/** + * Creates packages based on whether the current request is secure. + * + * @author Kris Wallsmith + */ +class PackageFactory +{ + private $container; + + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + /** + * Returns either the HTTP or SSL version of an asset package. + * + * @param Request $request The current request + * @param string $httpId The id for the package to use when the current request is HTTP + * @param string $sslId The id for the package to use when the current request is SSL + * + * @return PackageInterface The package + */ + public function getPackage(Request $request, $httpId, $sslId) + { + return $this->container->get($request->isSecure() ? $sslId : $httpId); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Asset/PathPackage.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Asset/PathPackage.php new file mode 100644 index 0000000..6aa8c58 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Asset/PathPackage.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\Bundle\FrameworkBundle\Templating\Asset; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Templating\Asset\PathPackage as BasePathPackage; + +/** + * The path packages adds a version and a base path to asset URLs. + * + * @author Kris Wallsmith + */ +class PathPackage extends BasePathPackage +{ + /** + * Constructor. + * + * @param Request $request The current request + * @param string $version The version + * @param string $format The version format + */ + public function __construct(Request $request, $version = null, $format = null) + { + parent::__construct($request->getBasePath(), $version, $format); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Debugger.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Debugger.php new file mode 100644 index 0000000..e63d034 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Debugger.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\Bundle\FrameworkBundle\Templating; + +use Symfony\Component\Templating\DebuggerInterface; +use Symfony\Component\HttpKernel\Log\LoggerInterface; + +/** + * Binds the Symfony templating loader debugger to the Symfony logger. + * + * @author Fabien Potencier + */ +class Debugger implements DebuggerInterface +{ + protected $logger; + + /** + * Constructor. + * + * @param LoggerInterface $logger A LoggerInterface instance + */ + public function __construct(LoggerInterface $logger = null) + { + $this->logger = $logger; + } + + /** + * Logs a message. + * + * @param string $message A message to log + */ + public function log($message) + { + if (null !== $this->logger) { + $this->logger->debug($message); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/DelegatingEngine.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/DelegatingEngine.php new file mode 100644 index 0000000..d7a62c1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/DelegatingEngine.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\Bundle\FrameworkBundle\Templating; + +use Symfony\Component\Templating\DelegatingEngine as BaseDelegatingEngine; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface; +use Symfony\Component\HttpFoundation\Response; + +/** + * DelegatingEngine selects an engine for a given template. + * + * @author Fabien Potencier + */ +class DelegatingEngine extends BaseDelegatingEngine implements EngineInterface +{ + protected $container; + + /** + * Constructor. + * + * @param ContainerInterface $container The DI container + * @param array $engineIds An array of engine Ids + */ + public function __construct(ContainerInterface $container, array $engineIds) + { + $this->container = $container; + $this->engines = $engineIds; + } + + /** + * {@inheritdoc} + */ + public function supports($name) + { + foreach ($this->engines as $i => $engine) { + if (is_string($engine)) { + $engine = $this->engines[$i] = $this->container->get($engine); + } + + if ($engine->supports($name)) { + return true; + } + } + + return false; + } + + /** + * {@inheritdoc} + */ + protected function getEngine($name) + { + foreach ($this->engines as $i => $engine) { + if (is_string($engine)) { + $engine = $this->engines[$i] = $this->container->get($engine); + } + + if ($engine->supports($name)) { + return $engine; + } + } + + throw new \RuntimeException(sprintf('No engine is able to work with the template "%s".', $name)); + } + + /** + * Renders a view and returns a Response. + * + * @param string $view The view name + * @param array $parameters An array of parameters to pass to the view + * @param Response $response A Response instance + * + * @return Response A Response instance + */ + public function renderResponse($view, array $parameters = array(), Response $response = null) + { + if (null === $response) { + $response = new Response(); + } + + $response->setContent($this->render($view, $parameters)); + + return $response; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/EngineInterface.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/EngineInterface.php new file mode 100644 index 0000000..0b12570 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/EngineInterface.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\Bundle\FrameworkBundle\Templating; + +use Symfony\Component\Templating\EngineInterface as BaseEngineInterface; +use Symfony\Component\HttpFoundation\Response; + +/** + * EngineInterface is the interface each engine must implement. + * + * @author Fabien Potencier + */ +interface EngineInterface extends BaseEngineInterface +{ + /** + * Renders a view and returns a Response. + * + * @param string $view The view name + * @param array $parameters An array of parameters to pass to the view + * @param Response $response A Response instance + * + * @return Response A Response instance + */ + function renderResponse($view, array $parameters = array(), Response $response = null); +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/GlobalVariables.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/GlobalVariables.php new file mode 100644 index 0000000..f77ca12 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/GlobalVariables.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\Bundle\FrameworkBundle\Templating; + +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * GlobalVariables is the entry point for Symfony global variables in Twig templates. + * + * @author Fabien Potencier + */ +class GlobalVariables +{ + protected $container; + + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + /** + * Returns the security context service. + * + * @return Symfony\Component\Security\Core\SecurityContext|void The security context + */ + public function getSecurity() + { + if ($this->container->has('security.context')) { + return $this->container->get('security.context'); + } + } + + /** + * Returns the current user. + * + * @return mixed|void + * + * @see Symfony\Component\Security\Core\Authentication\Token\TokenInterface::getUser() + */ + public function getUser() + { + if (!$security = $this->getSecurity()) { + return; + } + + if (!$token = $security->getToken()) { + return; + } + + $user = $token->getUser(); + if (!is_object($user)) { + return; + } + + return $user; + } + + /** + * Returns the current request. + * + * @return Symfony\Component\HttpFoundation\Request|void The http request object + */ + public function getRequest() + { + if ($this->container->has('request') && $request = $this->container->get('request')) { + return $request; + } + } + + /** + * Returns the current session. + * + * @return Symfony\Component\HttpFoundation\Session\Session|void The session + */ + public function getSession() + { + if ($request = $this->getRequest()) { + return $request->getSession(); + } + } + + /** + * Returns the current app environment. + * + * @return string The current environment string (e.g 'dev') + */ + public function getEnvironment() + { + return $this->container->getParameter('kernel.environment'); + } + + /** + * Returns the current app debug mode. + * + * @return Boolean The current debug mode + */ + public function getDebug() + { + return (Boolean) $this->container->getParameter('kernel.debug'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/ActionsHelper.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/ActionsHelper.php new file mode 100644 index 0000000..d10ef85 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/ActionsHelper.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\Bundle\FrameworkBundle\Templating\Helper; + +use Symfony\Component\Templating\Helper\Helper; +use Symfony\Bundle\FrameworkBundle\HttpKernel; + +/** + * ActionsHelper manages action inclusions. + * + * @author Fabien Potencier + */ +class ActionsHelper extends Helper +{ + protected $kernel; + + /** + * Constructor. + * + * @param HttpKernel $kernel A HttpKernel instance + */ + public function __construct(HttpKernel $kernel) + { + $this->kernel = $kernel; + } + + /** + * Returns the Response content for a given controller or URI. + * + * @param string $controller A controller name to execute (a string like BlogBundle:Post:index), or a relative URI + * @param array $attributes An array of request attributes + * @param array $options An array of options + * + * @see Symfony\Bundle\FrameworkBundle\HttpKernel::render() + */ + public function render($controller, array $attributes = array(), array $options = array()) + { + $options['attributes'] = $attributes; + + return $this->kernel->render($controller, $options); + } + + /** + * Returns the canonical name of this helper. + * + * @return string The canonical name + */ + public function getName() + { + return 'actions'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/CodeHelper.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/CodeHelper.php new file mode 100644 index 0000000..1997df9 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/CodeHelper.php @@ -0,0 +1,222 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Templating\Helper; + +use Symfony\Component\Templating\Helper\Helper; + +if (!defined('ENT_SUBSTITUTE')) { + define('ENT_SUBSTITUTE', 8); +} + +/** + * CodeHelper. + * + * @author Fabien Potencier + */ +class CodeHelper extends Helper +{ + protected $fileLinkFormat; + protected $rootDir; + protected $charset; + + /** + * Constructor. + * + * @param string $fileLinkFormat The format for links to source files + * @param string $rootDir The project root directory + * @param string $charset The charset + */ + public function __construct($fileLinkFormat, $rootDir, $charset) + { + $this->fileLinkFormat = empty($fileLinkFormat) ? ini_get('xdebug.file_link_format') : $fileLinkFormat; + $this->rootDir = str_replace('\\', '/', $rootDir).'/'; + $this->charset = $charset; + } + + /** + * Formats an array as a string. + * + * @param array $args The argument array + * + * @return string + */ + public function formatArgsAsText(array $args) + { + return strip_tags($this->formatArgs($args)); + } + + public function abbrClass($class) + { + $parts = explode('\\', $class); + $short = array_pop($parts); + + return sprintf("%s", $class, $short); + } + + public function abbrMethod($method) + { + if (false !== strpos($method, '::')) { + list($class, $method) = explode('::', $method, 2); + $result = sprintf("%s::%s()", $this->abbrClass($class), $method); + } elseif ('Closure' === $method) { + $result = sprintf("%s", $method, $method); + } else { + $result = sprintf("%s()", $method, $method); + } + + return $result; + } + + /** + * Formats an array as a string. + * + * @param array $args The argument array + * + * @return string + */ + public function formatArgs(array $args) + { + $result = array(); + foreach ($args as $key => $item) { + if ('object' === $item[0]) { + $parts = explode('\\', $item[1]); + $short = array_pop($parts); + $formattedValue = sprintf("object(%s)", $item[1], $short); + } elseif ('array' === $item[0]) { + $formattedValue = sprintf("array(%s)", is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]); + } elseif ('string' === $item[0]) { + $formattedValue = sprintf("'%s'", htmlspecialchars($item[1], ENT_QUOTES, $this->getCharset())); + } elseif ('null' === $item[0]) { + $formattedValue = 'null'; + } elseif ('boolean' === $item[0]) { + $formattedValue = ''.strtolower(var_export($item[1], true)).''; + } elseif ('resource' === $item[0]) { + $formattedValue = 'resource'; + } else { + $formattedValue = str_replace("\n", '', var_export(htmlspecialchars((string) $item[1], ENT_QUOTES, $this->getCharset()), true)); + } + + $result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue); + } + + return implode(', ', $result); + } + + /** + * Returns an excerpt of a code file around the given line number. + * + * @param string $file A file path + * @param int $line The selected line number + * + * @return string An HTML string + */ + public function fileExcerpt($file, $line) + { + if (is_readable($file)) { + $code = highlight_file($file, true); + // remove main code/span tags + $code = preg_replace('#^\s*(.*)\s*#s', '\\1', $code); + $content = preg_split('#
    #', $code); + + $lines = array(); + for ($i = max($line - 3, 1), $max = min($line + 3, count($content)); $i <= $max; $i++) { + $lines[] = ''.self::fixCodeMarkup($content[$i - 1]).'
  • '; + } + + return '
      '.implode("\n", $lines).'
    '; + } + } + + /** + * Formats a file path. + * + * @param string $file An absolute file path + * @param integer $line The line number + * @param string $text Use this text for the link rather than the file path + * + * @return string + */ + public function formatFile($file, $line, $text = null) + { + if (null === $text) { + $file = trim($file); + $fileStr = $file; + if (0 === strpos($fileStr, $this->rootDir)) { + $fileStr = str_replace($this->rootDir, '', str_replace('\\', '/', $fileStr)); + $fileStr = sprintf('kernel.root_dir/%s', $this->rootDir, $fileStr); + } + + $text = "$fileStr at line $line"; + } + + if (false !== $link = $this->getFileLink($file, $line)) { + return sprintf('%s', htmlspecialchars($link, ENT_QUOTES | ENT_SUBSTITUTE, $this->charset), $text); + } + + return $text; + } + + /** + * Returns the link for a given file/line pair. + * + * @param string $file An absolute file path + * @param integer $line The line number + * + * @return string A link of false + */ + public function getFileLink($file, $line) + { + if ($this->fileLinkFormat && is_file($file)) { + return strtr($this->fileLinkFormat, array('%f' => $file, '%l' => $line)); + } + + return false; + } + + public function formatFileFromText($text) + { + $that = $this; + + return preg_replace_callback('/in ("|")?(.+?)\1(?: +(?:on|at))? +line (\d+)/s', function ($match) use ($that) { + return 'in '.$that->formatFile($match[2], $match[3]); + }, $text); + } + + /** + * Returns the canonical name of this helper. + * + * @return string The canonical name + */ + public function getName() + { + return 'code'; + } + + static protected function fixCodeMarkup($line) + { + // ending tag from previous line + $opening = strpos($line, ''); + if (false !== $closing && (false === $opening || $closing < $opening)) { + $line = substr_replace($line, '', $closing, 7); + } + + // missing tag at the end of line + $opening = strpos($line, ''); + if (false !== $opening && (false === $closing || $closing > $opening)) { + $line .= ''; + } + + return $line; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/FormHelper.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/FormHelper.php new file mode 100644 index 0000000..517186b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/FormHelper.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\Bundle\FrameworkBundle\Templating\Helper; + +use Symfony\Component\Templating\Helper\Helper; +use Symfony\Component\Templating\EngineInterface; +use Symfony\Component\Form\FormView; +use Symfony\Component\Form\Exception\FormException; +use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface; +use Symfony\Component\Form\Extension\Core\View\ChoiceView; +use Symfony\Component\Form\Util\FormUtil; + +/** + * FormHelper provides helpers to help display forms. + * + * @author Fabien Potencier + * @author Bernhard Schussek + */ +class FormHelper extends Helper +{ + protected $engine; + + protected $csrfProvider; + + protected $varStack; + + protected $context; + + protected $resources; + + protected $themes; + + protected $templates; + + /** + * Constructor. + * + * @param EngineInterface $engine The templating engine + * @param CsrfProviderInterface $csrfProvider The CSRF provider + * @param array $resources An array of theme names + */ + public function __construct(EngineInterface $engine, CsrfProviderInterface $csrfProvider = null, array $resources = array()) + { + $this->engine = $engine; + $this->csrfProvider = $csrfProvider; + $this->resources = $resources; + $this->varStack = array(); + $this->context = array(); + $this->templates = array(); + $this->themes = array(); + } + + public function isChoiceGroup($label) + { + return FormUtil::isChoiceGroup($label); + } + + public function isChoiceSelected(FormView $view, ChoiceView $choice) + { + return FormUtil::isChoiceSelected($choice->getValue(), $view->getVar('value')); + } + + /** + * Sets a theme for a given view. + * + * The theme format is ":". + * + * @param FormView $view A FormView instance + * @param string|array $themes A theme or an array of theme + */ + public function setTheme(FormView $view, $themes) + { + $this->themes[$view->getVar('id')] = (array) $themes; + $this->templates = array(); + } + + /** + * Renders the HTML enctype in the form tag, if necessary. + * + * Example usage templates: + * + * enctype() ?>> + * + * @param FormView $view The view for which to render the encoding type + * + * @return string The html markup + */ + public function enctype(FormView $view) + { + return $this->renderSection($view, 'enctype'); + } + + /** + * Renders the HTML for a given view. + * + * Example usage: + * + * widget() ?> + * + * You can pass options during the call: + * + * widget(array('attr' => array('class' => 'foo'))) ?> + * + * widget(array('separator' => '+++++)) ?> + * + * @param FormView $view The view for which to render the widget + * @param array $variables Additional variables passed to the template + * + * @return string The html markup + */ + public function widget(FormView $view, array $variables = array()) + { + return $this->renderSection($view, 'widget', $variables); + } + + /** + * Renders the entire form field "row". + * + * @param FormView $view The view for which to render the row + * @param array $variables Additional variables passed to the template + * + * @return string The html markup + */ + public function row(FormView $view, array $variables = array()) + { + return $this->renderSection($view, 'row', $variables); + } + + /** + * Renders the label of the given view. + * + * @param FormView $view The view for which to render the label + * @param string $label The label + * @param array $variables Additional variables passed to the template + * + * @return string The html markup + */ + public function label(FormView $view, $label = null, array $variables = array()) + { + if ($label !== null) { + $variables += array('label' => $label); + } + + return $this->renderSection($view, 'label', $variables); + } + + /** + * Renders the errors of the given view. + * + * @param FormView $view The view to render the errors for + * + * @return string The html markup + */ + public function errors(FormView $view) + { + return $this->renderSection($view, 'errors'); + } + + /** + * Renders views which have not already been rendered. + * + * @param FormView $view The parent view + * @param array $variables An array of variables + * + * @return string The html markup + */ + public function rest(FormView $view, array $variables = array()) + { + return $this->renderSection($view, 'rest', $variables); + } + + /** + * Returns a CSRF token. + * + * Use this helper for CSRF protection without the overhead of creating a + * form. + * + * + * echo $view['form']->csrfToken('rm_user_'.$user->getId()); + * + * + * Check the token in your action using the same intention. + * + * + * $csrfProvider = $this->get('form.csrf_provider'); + * if (!$csrfProvider->isCsrfTokenValid('rm_user_'.$user->getId(), $token)) { + * throw new \RuntimeException('CSRF attack detected.'); + * } + * + * + * @param string $intention The intention of the protected action + * + * @return string A CSRF token + */ + public function csrfToken($intention) + { + if (!$this->csrfProvider instanceof CsrfProviderInterface) { + throw new \BadMethodCallException('CSRF token can only be generated if a CsrfProviderInterface is injected in the constructor.'); + } + + return $this->csrfProvider->generateCsrfToken($intention); + } + + /** + * Renders a template. + * + * 1. This function first looks for a block named "__
    ", + * 2. if such a block is not found the function will look for a block named + * "_
    ", + * 3. the type name is recursively replaced by the parent type name until a + * corresponding block is found + * + * @param FormView $view The form view + * @param string $section The section to render (i.e. 'row', 'widget', 'label', ...) + * @param array $variables Additional variables + * + * @return string The html markup + * + * @throws FormException if no template block exists to render the given section of the view + */ + protected function renderSection(FormView $view, $section, array $variables = array()) + { + $mainTemplate = in_array($section, array('row', 'widget')); + if ($mainTemplate && $view->isRendered()) { + + return ''; + } + + $template = null; + + $custom = '_'.$view->getVar('id'); + $rendering = $custom.$section; + + if (isset($this->varStack[$rendering])) { + $typeIndex = $this->varStack[$rendering]['typeIndex'] - 1; + $types = $this->varStack[$rendering]['types']; + $variables = array_replace_recursive($this->varStack[$rendering]['variables'], $variables); + } else { + $types = $view->getVar('types'); + $types[] = $custom; + $typeIndex = count($types) - 1; + $variables = array_replace_recursive($view->getVars(), $variables); + $this->varStack[$rendering]['types'] = $types; + } + + $this->varStack[$rendering]['variables'] = $variables; + + do { + $types[$typeIndex] .= '_'.$section; + $template = $this->lookupTemplate($view, $types[$typeIndex]); + + if ($template) { + + $this->varStack[$rendering]['typeIndex'] = $typeIndex; + + $this->context[] = array( + 'variables' => $variables, + 'view' => $view, + ); + + $html = $this->engine->render($template, $variables); + + array_pop($this->context); + unset($this->varStack[$rendering]); + + if ($mainTemplate) { + $view->setRendered(); + } + + return trim($html); + } + } while (--$typeIndex >= 0); + + throw new FormException(sprintf( + 'Unable to render the form as none of the following blocks exist: "%s".', + implode('", "', array_reverse($types)) + )); + } + + /** + * Render a block from a form element. + * + * @param string $name + * @param array $variables Additional variables (those would override the current context) + * + * @throws FormException if the block is not found + * @throws FormException if the method is called out of a form element (no context) + */ + public function renderBlock($name, $variables = array()) + { + if (0 == count($this->context)) { + throw new FormException(sprintf('This method should only be called while rendering a form element.', $name)); + } + + $context = end($this->context); + + $template = $this->lookupTemplate($context['view'], $name); + + if (false === $template) { + throw new FormException(sprintf('No block "%s" found while rendering the form.', $name)); + } + + $variables = array_replace_recursive($context['variables'], $variables); + + return trim($this->engine->render($template, $variables)); + } + + public function getName() + { + return 'form'; + } + + /** + * Returns the name of the template to use to render the block + * + * @param FormView $view The form view + * @param string $block The name of the block + * + * @return string|Boolean The template logical name or false when no template is found + */ + protected function lookupTemplate(FormView $view, $block) + { + $file = $block.'.html.php'; + $id = $view->getVar('id'); + + if (!isset($this->templates[$id][$block])) { + $template = false; + + $themes = $view->hasParent() ? array() : $this->resources; + + if (isset($this->themes[$id])) { + $themes = array_merge($themes, $this->themes[$id]); + } + + for ($i = count($themes) - 1; $i >= 0; --$i) { + if ($this->engine->exists($templateName = $themes[$i].':'.$file)) { + $template = $templateName; + break; + } + } + + if (false === $template && $view->hasParent()) { + $template = $this->lookupTemplate($view->getParent(), $block); + } + + $this->templates[$id][$block] = $template; + } + + return $this->templates[$id][$block]; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/RequestHelper.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/RequestHelper.php new file mode 100644 index 0000000..49ad326 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/RequestHelper.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\Bundle\FrameworkBundle\Templating\Helper; + +use Symfony\Component\Templating\Helper\Helper; +use Symfony\Component\HttpFoundation\Request; + +/** + * RequestHelper provides access to the current request parameters. + * + * @author Fabien Potencier + */ +class RequestHelper extends Helper +{ + protected $request; + + /** + * Constructor. + * + * @param Request $request A Request instance + */ + public function __construct(Request $request) + { + $this->request = $request; + } + + /** + * Returns a parameter from the current request object. + * + * @param string $key The name of the parameter + * @param string $default A default value + * + * @see Symfony\Component\HttpFoundation\Request::get() + */ + public function getParameter($key, $default = null) + { + return $this->request->get($key, $default); + } + + /** + * Returns the locale + * + * @return string + */ + public function getLocale() + { + return $this->request->getLocale(); + } + + /** + * Returns the canonical name of this helper. + * + * @return string The canonical name + */ + public function getName() + { + return 'request'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/RouterHelper.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/RouterHelper.php new file mode 100644 index 0000000..6ce7896 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/RouterHelper.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\Bundle\FrameworkBundle\Templating\Helper; + +use Symfony\Component\Templating\Helper\Helper; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; + +/** + * RouterHelper manages links between pages in a template context. + * + * @author Fabien Potencier + */ +class RouterHelper extends Helper +{ + protected $generator; + + /** + * Constructor. + * + * @param UrlGeneratorInterface $router A Router instance + */ + public function __construct(UrlGeneratorInterface $router) + { + $this->generator = $router; + } + + /** + * Generates a URL from the given parameters. + * + * @param string $name The name of the route + * @param mixed $parameters An array of parameters + * @param Boolean $absolute Whether to generate an absolute URL + * + * @return string The generated URL + */ + public function generate($name, $parameters = array(), $absolute = false) + { + return $this->generator->generate($name, $parameters, $absolute); + } + + /** + * Returns the canonical name of this helper. + * + * @return string The canonical name + */ + public function getName() + { + return 'router'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/SessionHelper.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/SessionHelper.php new file mode 100644 index 0000000..aac3f6d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/SessionHelper.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\Bundle\FrameworkBundle\Templating\Helper; + +use Symfony\Component\Templating\Helper\Helper; +use Symfony\Component\HttpFoundation\Request; + +/** + * SessionHelper provides read-only access to the session attributes. + * + * @author Fabien Potencier + */ +class SessionHelper extends Helper +{ + protected $session; + + /** + * Constructor. + * + * @param Request $request A Request instance + */ + public function __construct(Request $request) + { + $this->session = $request->getSession(); + } + + /** + * Returns an attribute + * + * @param string $name The attribute name + * @param mixed $default The default value + * + * @return mixed + */ + public function get($name, $default = null) + { + return $this->session->get($name, $default); + } + + public function getFlash($name, array $default = array()) + { + return $this->session->getFlashBag()->get($name, $default); + } + + public function getFlashes() + { + return $this->session->getFlashBag()->all(); + } + + public function hasFlash($name) + { + return $this->session->getFlashBag()->has($name); + } + + /** + * Returns the canonical name of this helper. + * + * @return string The canonical name + */ + public function getName() + { + return 'session'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/TranslatorHelper.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/TranslatorHelper.php new file mode 100644 index 0000000..30816d7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/TranslatorHelper.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\Bundle\FrameworkBundle\Templating\Helper; + +use Symfony\Component\Templating\Helper\Helper; +use Symfony\Component\Translation\TranslatorInterface; + +/** + * TranslatorHelper. + * + * @author Fabien Potencier + */ +class TranslatorHelper extends Helper +{ + protected $translator; + + /** + * Constructor. + * + * @param TranslatorInterface $translator A TranslatorInterface instance + */ + public function __construct(TranslatorInterface $translator) + { + $this->translator = $translator; + } + + /** + * @see TranslatorInterface::trans() + */ + public function trans($id, array $parameters = array(), $domain = 'messages', $locale = null) + { + return $this->translator->trans($id, $parameters, $domain, $locale); + } + + /** + * @see TranslatorInterface::transChoice() + */ + public function transChoice($id, $number, array $parameters = array(), $domain = 'messages', $locale = null) + { + return $this->translator->transChoice($id, $number, $parameters, $domain, $locale); + } + + /** + * Returns the canonical name of this helper. + * + * @return string The canonical name + */ + public function getName() + { + return 'translator'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Loader/FilesystemLoader.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Loader/FilesystemLoader.php new file mode 100644 index 0000000..894f93b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Loader/FilesystemLoader.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\Bundle\FrameworkBundle\Templating\Loader; + +use Symfony\Component\Templating\Storage\FileStorage; +use Symfony\Component\Templating\Loader\LoaderInterface; +use Symfony\Component\Config\FileLocatorInterface; +use Symfony\Component\Templating\TemplateReferenceInterface; + +/** + * FilesystemLoader is a loader that read templates from the filesystem. + * + * @author Fabien Potencier + */ +class FilesystemLoader implements LoaderInterface +{ + protected $locator; + + /** + * Constructor. + * + * @param FileLocatorInterface $locator A FileLocatorInterface instance + */ + public function __construct(FileLocatorInterface $locator) + { + $this->locator = $locator; + } + + /** + * Loads a template. + * + * @param TemplateReferenceInterface $template A template + * + * @return Storage|Boolean false if the template cannot be loaded, a Storage instance otherwise + */ + public function load(TemplateReferenceInterface $template) + { + try { + $file = $this->locator->locate($template); + } catch (\InvalidArgumentException $e) { + return false; + } + + return new FileStorage($file); + } + + /** + * Returns true if the template is still fresh. + * + * @param TemplateReferenceInterface $template The template name as an array + * @param integer $time The last modification time of the cached template (timestamp) + */ + public function isFresh(TemplateReferenceInterface $template, $time) + { + if (false === $storage = $this->load($template)) { + return false; + } + + if (!is_readable((string) $storage)) { + return false; + } + + return filemtime((string) $storage) < $time; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Loader/TemplateLocator.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Loader/TemplateLocator.php new file mode 100644 index 0000000..0ff6b8c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/Loader/TemplateLocator.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\Bundle\FrameworkBundle\Templating\Loader; + +use Symfony\Component\Config\FileLocatorInterface; +use Symfony\Component\Templating\TemplateReferenceInterface; + +/** + * TemplateLocator locates templates in bundles. + * + * @author Fabien Potencier + */ +class TemplateLocator implements FileLocatorInterface +{ + protected $locator; + protected $cache; + + /** + * Constructor. + * + * @param FileLocatorInterface $locator A FileLocatorInterface instance + * @param string $cacheDir The cache path + */ + public function __construct(FileLocatorInterface $locator, $cacheDir = null) + { + if (null !== $cacheDir && is_file($cache = $cacheDir.'/templates.php')) { + $this->cache = require $cache; + } + + $this->locator = $locator; + } + + /** + * Returns a full path for a given file. + * + * @param TemplateReferenceInterface $template A template + * + * @return string The full path for the file + */ + protected function getCacheKey($template) + { + return $template->getLogicalName(); + } + + /** + * Returns a full path for a given file. + * + * @param TemplateReferenceInterface $template A template + * @param string $currentPath Unused + * @param Boolean $first Unused + * + * @return string The full path for the file + * + * @throws \InvalidArgumentException When the template is not an instance of TemplateReferenceInterface + * @throws \InvalidArgumentException When the template file can not be found + */ + public function locate($template, $currentPath = null, $first = true) + { + if (!$template instanceof TemplateReferenceInterface) { + throw new \InvalidArgumentException("The template must be an instance of TemplateReferenceInterface."); + } + + $key = $this->getCacheKey($template); + + if (isset($this->cache[$key])) { + return $this->cache[$key]; + } + + try { + return $this->cache[$key] = $this->locator->locate($template->getPath(), $currentPath); + } catch (\InvalidArgumentException $e) { + throw new \InvalidArgumentException(sprintf('Unable to find template "%s" : "%s".', $template, $e->getMessage()), 0, $e); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/PhpEngine.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/PhpEngine.php new file mode 100644 index 0000000..a93098e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/PhpEngine.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\Bundle\FrameworkBundle\Templating; + +use Symfony\Component\Templating\PhpEngine as BasePhpEngine; +use Symfony\Component\Templating\Loader\LoaderInterface; +use Symfony\Component\Templating\TemplateNameParserInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpFoundation\Response; + +/** + * This engine knows how to render Symfony templates. + * + * @author Fabien Potencier + */ +class PhpEngine extends BasePhpEngine implements EngineInterface +{ + protected $container; + + /** + * Constructor. + * + * @param TemplateNameParserInterface $parser A TemplateNameParserInterface instance + * @param ContainerInterface $container The DI container + * @param LoaderInterface $loader A loader instance + * @param GlobalVariables|null $globals A GlobalVariables instance or null + */ + public function __construct(TemplateNameParserInterface $parser, ContainerInterface $container, LoaderInterface $loader, GlobalVariables $globals = null) + { + $this->container = $container; + + parent::__construct($parser, $loader); + + if (null !== $globals) { + $this->addGlobal('app', $globals); + } + } + + /** + * @throws \InvalidArgumentException When the helper is not defined + */ + public function get($name) + { + if (!isset($this->helpers[$name])) { + throw new \InvalidArgumentException(sprintf('The helper "%s" is not defined.', $name)); + } + + if (is_string($this->helpers[$name])) { + $this->helpers[$name] = $this->container->get($this->helpers[$name]); + $this->helpers[$name]->setCharset($this->charset); + } + + return $this->helpers[$name]; + } + + /** + * {@inheritdoc} + */ + public function setHelpers(array $helpers) + { + $this->helpers = $helpers; + } + + /** + * Renders a view and returns a Response. + * + * @param string $view The view name + * @param array $parameters An array of parameters to pass to the view + * @param Response $response A Response instance + * + * @return Response A Response instance + */ + public function renderResponse($view, array $parameters = array(), Response $response = null) + { + if (null === $response) { + $response = new Response(); + } + + $response->setContent($this->render($view, $parameters)); + + return $response; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php new file mode 100644 index 0000000..944c60f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.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\Bundle\FrameworkBundle\Templating; + +use Symfony\Component\Templating\TemplateNameParser as BaseTemplateNameParser; +use Symfony\Component\Templating\TemplateReferenceInterface; +use Symfony\Component\HttpKernel\KernelInterface; + +/** + * TemplateNameParser converts template names from the short notation + * "bundle:section:template.format.engine" to TemplateReferenceInterface + * instances. + * + * @author Fabien Potencier + */ +class TemplateNameParser extends BaseTemplateNameParser +{ + protected $kernel; + protected $cache; + + /** + * Constructor. + * + * @param KernelInterface $kernel A KernelInterface instance + */ + public function __construct(KernelInterface $kernel) + { + $this->kernel = $kernel; + $this->cache = array(); + } + + /** + * {@inheritdoc} + */ + public function parse($name) + { + if ($name instanceof TemplateReferenceInterface) { + return $name; + } elseif (isset($this->cache[$name])) { + return $this->cache[$name]; + } + + // normalize name + $name = str_replace(':/', ':', preg_replace('#/{2,}#', '/', strtr($name, '\\', '/'))); + + if (false !== strpos($name, '..')) { + throw new \RuntimeException(sprintf('Template name "%s" contains invalid characters.', $name)); + } + + $parts = explode(':', $name); + if (3 !== count($parts)) { + throw new \InvalidArgumentException(sprintf('Template name "%s" is not valid (format is "bundle:section:template.format.engine").', $name)); + } + + $elements = explode('.', $parts[2]); + if (3 > count($elements)) { + throw new \InvalidArgumentException(sprintf('Template name "%s" is not valid (format is "bundle:section:template.format.engine").', $name)); + } + $engine = array_pop($elements); + $format = array_pop($elements); + + $template = new TemplateReference($parts[0], $parts[1], implode('.', $elements), $format, $engine); + + if ($template->get('bundle')) { + try { + $this->kernel->getBundle($template->get('bundle')); + } catch (\Exception $e) { + throw new \InvalidArgumentException(sprintf('Template name "%s" is not valid.', $name), 0, $e); + } + } + + return $this->cache[$name] = $template; + } + + /** + * Convert a filename to a template. + * + * @param string $file The filename + * + * @return TemplateReferenceInterface A template + */ + public function parseFromFilename($file) + { + $parts = explode('/', strtr($file, '\\', '/')); + + $elements = explode('.', array_pop($parts)); + if (3 > count($elements)) { + return false; + } + $engine = array_pop($elements); + $format = array_pop($elements); + + return new TemplateReference('', implode('/', $parts), implode('.', $elements), $format, $engine); + } + +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateReference.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateReference.php new file mode 100644 index 0000000..65a5779 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateReference.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\Bundle\FrameworkBundle\Templating; + +use Symfony\Component\Templating\TemplateReference as BaseTemplateReference; + +/** + * Internal representation of a template. + * + * @author Victor Berchet + */ +class TemplateReference extends BaseTemplateReference +{ + public function __construct($bundle = null, $controller = null, $name = null, $format = null, $engine = null) + { + $this->parameters = array( + 'bundle' => $bundle, + 'controller' => $controller, + 'name' => $name, + 'format' => $format, + 'engine' => $engine, + ); + } + + /** + * Returns the path to the template + * - as a path when the template is not part of a bundle + * - as a resource when the template is part of a bundle + * + * @return string A path to the template or a resource + */ + public function getPath() + { + $controller = str_replace('\\', '/', $this->get('controller')); + + $path = (empty($controller) ? '' : $controller.'/').$this->get('name').'.'.$this->get('format').'.'.$this->get('engine'); + + return empty($this->parameters['bundle']) ? 'views/'.$path : '@'.$this->get('bundle').'/Resources/views/'.$path; + } + + /** + * {@inheritdoc} + */ + public function getLogicalName() + { + return sprintf('%s:%s:%s.%s.%s', $this->parameters['bundle'], $this->parameters['controller'], $this->parameters['name'], $this->parameters['format'], $this->parameters['engine']); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php new file mode 100644 index 0000000..506466d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.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\Bundle\FrameworkBundle\Test; + +use Symfony\Bundle\FrameworkBundle\Client; +use Symfony\Component\Finder\Finder; +use Symfony\Component\HttpKernel\HttpKernelInterface; + +/** + * WebTestCase is the base class for functional tests. + * + * @author Fabien Potencier + */ +abstract class WebTestCase extends \PHPUnit_Framework_TestCase +{ + static protected $class; + static protected $kernel; + + /** + * Creates a Client. + * + * @param array $options An array of options to pass to the createKernel class + * @param array $server An array of server parameters + * + * @return Client A Client instance + */ + static protected function createClient(array $options = array(), array $server = array()) + { + if (null !== static::$kernel) { + static::$kernel->shutdown(); + } + + static::$kernel = static::createKernel($options); + static::$kernel->boot(); + + $client = static::$kernel->getContainer()->get('test.client'); + $client->setServerParameters($server); + + return $client; + } + + /** + * Finds the directory where the phpunit.xml(.dist) is stored. + * + * If you run tests with the PHPUnit CLI tool, everything will work as expected. + * If not, override this method in your test classes. + * + * @return string The directory where phpunit.xml(.dist) is stored + */ + static protected function getPhpUnitXmlDir() + { + if (!isset($_SERVER['argv']) || false === strpos($_SERVER['argv'][0], 'phpunit')) { + throw new \RuntimeException('You must override the WebTestCase::createKernel() method.'); + } + + $dir = static::getPhpUnitCliConfigArgument(); + if ($dir === null && + (is_file(getcwd().DIRECTORY_SEPARATOR.'phpunit.xml') || + is_file(getcwd().DIRECTORY_SEPARATOR.'phpunit.xml.dist'))) { + $dir = getcwd(); + } + + // Can't continue + if ($dir === null) { + throw new \RuntimeException('Unable to guess the Kernel directory.'); + } + + if (!is_dir($dir)) { + $dir = dirname($dir); + } + + return $dir; + } + + /** + * Finds the value of configuration flag from cli + * + * PHPUnit will use the last configuration argument on the command line, so this only returns + * the last configuration argument + * + * @return string The value of the phpunit cli configuration option + */ + static private function getPhpUnitCliConfigArgument() + { + $dir = null; + $reversedArgs = array_reverse($_SERVER['argv']); + foreach ($reversedArgs as $argIndex => $testArg) { + if ($testArg === '-c' || $testArg === '--configuration') { + $dir = realpath($reversedArgs[$argIndex - 1]); + break; + } elseif (strpos($testArg, '--configuration=') === 0) { + $argPath = substr($testArg, strlen('--configuration=')); + $dir = realpath($argPath); + break; + } + } + + return $dir; + } + + /** + * Attempts to guess the kernel location. + * + * When the Kernel is located, the file is required. + * + * @return string The Kernel class name + */ + static protected function getKernelClass() + { + $dir = isset($_SERVER['KERNEL_DIR']) ? $_SERVER['KERNEL_DIR'] : static::getPhpUnitXmlDir(); + + $finder = new Finder(); + $finder->name('*Kernel.php')->depth(0)->in($dir); + $results = iterator_to_array($finder); + if (!count($results)) { + throw new \RuntimeException('Either set KERNEL_DIR in your phpunit.xml according to http://symfony.com/doc/current/book/testing.html#your-first-functional-test or override the WebTestCase::createKernel() method.'); + } + + $file = current($results); + $class = $file->getBasename('.php'); + + require_once $file; + + return $class; + } + + /** + * Creates a Kernel. + * + * Available options: + * + * * environment + * * debug + * + * @param array $options An array of options + * + * @return HttpKernelInterface A HttpKernelInterface instance + */ + static protected function createKernel(array $options = array()) + { + if (null === static::$class) { + static::$class = static::getKernelClass(); + } + + return new static::$class( + isset($options['environment']) ? $options['environment'] : 'test', + isset($options['debug']) ? $options['debug'] : true + ); + } + + /** + * Shuts the kernel down if it was used in the test. + */ + protected function tearDown() + { + if (null !== static::$kernel) { + static::$kernel->shutdown(); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/TemplateFinderTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/TemplateFinderTest.php new file mode 100644 index 0000000..23f2a4f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/TemplateFinderTest.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\Bundle\FrameworkBundle\Tests\CacheWarmer; + +use Symfony\Bundle\FrameworkBundle\Tests\TestCase; +use Symfony\Bundle\FrameworkBundle\Templating\TemplateNameParser; +use Symfony\Bundle\FrameworkBundle\CacheWarmer\TemplateFinder; +use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\BaseBundle\BaseBundle; + + +class TemplateFinderTest extends TestCase +{ + public function testFindAllTemplates() + { + $kernel = $this + ->getMockBuilder('Symfony\Component\HttpKernel\Kernel') + ->disableOriginalConstructor() + ->getMock() + ; + + $kernel + ->expects($this->any()) + ->method('getBundle') + ; + + $kernel + ->expects($this->once()) + ->method('getBundles') + ->will($this->returnValue(array('BaseBundle' => new BaseBundle()))) + ; + + $parser = new TemplateNameParser($kernel); + + $finder = new TemplateFinder($kernel, $parser, __DIR__.'/../Fixtures/Resources'); + + $templates = array_map( + function ($template) { return $template->getLogicalName(); }, + $finder->findAllTemplates() + ); + + $this->assertEquals(6, count($templates), '->findAllTemplates() find all templates in the bundles and global folders'); + $this->assertContains('BaseBundle::base.format.engine', $templates); + $this->assertContains('BaseBundle::this.is.a.template.format.engine', $templates); + $this->assertContains('BaseBundle:controller:base.format.engine', $templates); + $this->assertContains('::this.is.a.template.format.engine', $templates); + $this->assertContains('::resource.format.engine', $templates); + } + +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TestCaseMethod.tpl b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TestCaseMethod.tpl new file mode 100644 index 0000000..5279001 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TestCaseMethod.tpl @@ -0,0 +1,47 @@ +collectRawCodeCoverageInformation({collectCodeCoverageInformation}); + + $test = new {className}('{methodName}', unserialize('{data}'), '{dataName}'); + $test->setDependencyInput(unserialize('{dependencyInput}')); + $test->setInIsolation(TRUE); + + ob_end_clean(); + ob_start(); + $test->run($result); + $output = ob_get_clean(); + + print serialize( + array( + 'testResult' => $test->getResult(), + 'numAssertions' => $test->getNumAssertions(), + 'result' => $result, + 'output' => $output + ) + ); + + ob_start(); +} + +{globals} + +if (isset($GLOBALS['__PHPUNIT_BOOTSTRAP'])) { + require_once $GLOBALS['__PHPUNIT_BOOTSTRAP']; + unset($GLOBALS['__PHPUNIT_BOOTSTRAP']); +} + +{constants} + +__phpunit_run_isolated_test(); +ob_end_clean(); +?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php new file mode 100644 index 0000000..9cc0b77 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.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\Bundle\FrameworkBundle\Tests\Controller; + +use Symfony\Bundle\FrameworkBundle\Tests\TestCase; +use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser; +use Symfony\Component\ClassLoader\UniversalClassLoader; + +class ControllerNameParserTest extends TestCase +{ + protected $loader; + + protected function setUp() + { + $this->loader = new UniversalClassLoader(); + $this->loader->registerNamespaces(array( + 'TestBundle' => __DIR__.'/../Fixtures', + 'TestApplication' => __DIR__.'/../Fixtures', + )); + $this->loader->register(); + } + + public function tearDown() + { + spl_autoload_unregister(array($this->loader, 'loadClass')); + + $this->loader = null; + } + + public function testParse() + { + $parser = $this->createParser(); + + $this->assertEquals('TestBundle\FooBundle\Controller\DefaultController::indexAction', $parser->parse('FooBundle:Default:index'), '->parse() converts a short a:b:c notation string to a class::method string'); + $this->assertEquals('TestBundle\FooBundle\Controller\Sub\DefaultController::indexAction', $parser->parse('FooBundle:Sub\Default:index'), '->parse() converts a short a:b:c notation string to a class::method string'); + $this->assertEquals('TestBundle\Fabpot\FooBundle\Controller\DefaultController::indexAction', $parser->parse('SensioFooBundle:Default:index'), '->parse() converts a short a:b:c notation string to a class::method string'); + $this->assertEquals('TestBundle\Sensio\Cms\FooBundle\Controller\DefaultController::indexAction', $parser->parse('SensioCmsFooBundle:Default:index'), '->parse() converts a short a:b:c notation string to a class::method string'); + $this->assertEquals('TestBundle\FooBundle\Controller\Test\DefaultController::indexAction', $parser->parse('FooBundle:Test\\Default:index'), '->parse() converts a short a:b:c notation string to a class::method string'); + $this->assertEquals('TestBundle\FooBundle\Controller\Test\DefaultController::indexAction', $parser->parse('FooBundle:Test/Default:index'), '->parse() converts a short a:b:c notation string to a class::method string'); + + try { + $parser->parse('foo:'); + $this->fail('->parse() throws an \InvalidArgumentException if the controller is not an a:b:c string'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->parse() throws an \InvalidArgumentException if the controller is not an a:b:c string'); + } + } + + /** + * @dataProvider getMissingControllersTest + */ + public function testMissingControllers($name) + { + $parser = $this->createParser(); + + try { + $parser->parse($name); + $this->fail('->parse() throws a \InvalidArgumentException if the string is in the valid format, but not matching class can be found'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->parse() throws a \InvalidArgumentException if the class is found but does not exist'); + } + } + + public function getMissingControllersTest() + { + return array( + array('FooBundle:Fake:index'), // a normal bundle + array('SensioFooBundle:Fake:index'), // a bundle with children + ); + } + + private function createParser() + { + $bundles = array( + 'SensioFooBundle' => array($this->getBundle('TestBundle\Fabpot\FooBundle', 'FabpotFooBundle'), $this->getBundle('TestBundle\Sensio\FooBundle', 'SensioFooBundle')), + 'SensioCmsFooBundle' => array($this->getBundle('TestBundle\Sensio\Cms\FooBundle', 'SensioCmsFooBundle')), + 'FooBundle' => array($this->getBundle('TestBundle\FooBundle', 'FooBundle')), + 'FabpotFooBundle' => array($this->getBundle('TestBundle\Fabpot\FooBundle', 'FabpotFooBundle'), $this->getBundle('TestBundle\Sensio\FooBundle', 'SensioFooBundle')), + ); + + $kernel = $this->getMock('Symfony\Component\HttpKernel\KernelInterface'); + $kernel + ->expects($this->any()) + ->method('getBundle') + ->will($this->returnCallback(function ($bundle) use ($bundles) { + return $bundles[$bundle]; + })) + ; + + return new ControllerNameParser($kernel); + } + + private function getBundle($namespace, $name) + { + $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\BundleInterface'); + $bundle->expects($this->any())->method('getName')->will($this->returnValue($name)); + $bundle->expects($this->any())->method('getNamespace')->will($this->returnValue($namespace)); + + return $bundle; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php new file mode 100644 index 0000000..dc19ad9 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.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\Bundle\FrameworkBundle\Tests\Controller; + +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\ParameterBag; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Bundle\FrameworkBundle\Controller\RedirectController; +use Symfony\Bundle\FrameworkBundle\Tests\TestCase; + +/** + * @author Marcin Sikon + */ +class RedirectControllerTest extends TestCase +{ + public function testEmptyRoute() + { + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + + $controller = new RedirectController(); + $controller->setContainer($container); + + $returnResponse = $controller->redirectAction(''); + + $this->assertInstanceOf('\Symfony\Component\HttpFoundation\Response', $returnResponse); + + $this->assertEquals(410, $returnResponse->getStatusCode()); + } + + /** + * @dataProvider provider + */ + public function testRoute($permanent, $expectedCode) + { + $request = new Request(); + + $route = 'new-route'; + $url = '/redirect-url'; + $params = array('additional-parameter' => 'value'); + $attributes = array( + 'route' => $route, + 'permanent' => $permanent, + '_route' => 'current-route', + '_route_params' => array( + 'route' => $route, + 'permanent' => $permanent, + ), + ); + $attributes['_route_params'] = $attributes['_route_params'] + $params; + + $request->attributes = new ParameterBag($attributes); + + $router = $this->getMock('Symfony\Component\Routing\RouterInterface'); + $router + ->expects($this->once()) + ->method('generate') + ->with($this->equalTo($route), $this->equalTo($params)) + ->will($this->returnValue($url)); + + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + + + $container + ->expects($this->at(0)) + ->method('get') + ->with($this->equalTo('request')) + ->will($this->returnValue($request)); + + $container + ->expects($this->at(1)) + ->method('get') + ->with($this->equalTo('router')) + ->will($this->returnValue($router)); + + $controller = new RedirectController(); + $controller->setContainer($container); + + $returnResponse = $controller->redirectAction($route, $permanent); + + $this->assertInstanceOf('\Symfony\Component\HttpFoundation\Response', $returnResponse); + + $this->assertTrue($returnResponse->isRedirect($url)); + $this->assertEquals($expectedCode, $returnResponse->getStatusCode()); + } + + public function provider() + { + return array( + array(true, 301), + array(false, 302), + ); + } + + public function testEmptyPath() + { + $controller = new RedirectController(); + $returnResponse = $controller->urlRedirectAction(''); + + $this->assertInstanceOf('\Symfony\Component\HttpFoundation\Response', $returnResponse); + + $this->assertEquals(410, $returnResponse->getStatusCode()); + } + + public function testFullURL() + { + $controller = new RedirectController(); + $returnResponse = $controller->urlRedirectAction('http://foo.bar/'); + + $this->assertInstanceOf('\Symfony\Component\HttpFoundation\Response', $returnResponse); + + $this->assertEquals('http://foo.bar/', $returnResponse->headers->get('Location')); + $this->assertEquals(302, $returnResponse->getStatusCode()); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddCacheWarmerPassTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddCacheWarmerPassTest.php new file mode 100644 index 0000000..03eacc3 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddCacheWarmerPassTest.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\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddCacheWarmerPass; + +class AddCacheWarmerPassTest extends \PHPUnit_Framework_TestCase +{ + public function testThatCacheWarmersAreProcessedInPriorityOrder() + { + $services = array( + 'my_cache_warmer_service1' => array(0 => array('priority' => 100)), + 'my_cache_warmer_service2' => array(0 => array('priority' => 200)), + 'my_cache_warmer_service3' => array() + ); + + $definition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerBuilder'); + + $container->expects($this->atLeastOnce()) + ->method('findTaggedServiceIds') + ->will($this->returnValue($services)); + $container->expects($this->atLeastOnce()) + ->method('getDefinition') + ->with('cache_warmer') + ->will($this->returnValue($definition)); + $container->expects($this->atLeastOnce()) + ->method('hasDefinition') + ->with('cache_warmer') + ->will($this->returnValue(true)); + + $definition->expects($this->once()) + ->method('replaceArgument') + ->with(0, array( + new Reference('my_cache_warmer_service2'), + new Reference('my_cache_warmer_service1'), + new Reference('my_cache_warmer_service3') + )); + + $addCacheWarmerPass = new AddCacheWarmerPass(); + $addCacheWarmerPass->process($container); + } + + public function testThatCompilerPassIsIgnoredIfThereIsNoCacheWarmerDefinition() + { + $definition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerBuilder'); + + $container->expects($this->never())->method('findTaggedServiceIds'); + $container->expects($this->never())->method('getDefinition'); + $container->expects($this->atLeastOnce()) + ->method('hasDefinition') + ->with('cache_warmer') + ->will($this->returnValue(false)); + $definition->expects($this->never())->method('replaceArgument'); + + $addCacheWarmerPass = new AddCacheWarmerPass(); + $addCacheWarmerPass->process($container); + } + + public function testThatCacheWarmersMightBeNotDefined() + { + $definition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerBuilder'); + + $container->expects($this->atLeastOnce()) + ->method('findTaggedServiceIds') + ->will($this->returnValue(array())); + $container->expects($this->never())->method('getDefinition'); + $container->expects($this->atLeastOnce()) + ->method('hasDefinition') + ->with('cache_warmer') + ->will($this->returnValue(true)); + + $definition->expects($this->never())->method('replaceArgument'); + + $addCacheWarmerPass = new AddCacheWarmerPass(); + $addCacheWarmerPass->process($container); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ProfilerPassTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ProfilerPassTest.php new file mode 100644 index 0000000..05c3ec1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ProfilerPassTest.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\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ProfilerPass; + +class ProfilerPassTest extends \PHPUnit_Framework_TestCase +{ + /** + * Tests that collectors that specify a template but no "id" will throw + * an exception (both are needed if the template is specified). Thus, + * a fully-valid tag looks something like this: + * + * + */ + public function testTemplateNoIdThrowsException() + { + // one service, with a template key, but no id + $services = array( + 'my_collector_service' => array(0 => array('template' => 'foo')), + ); + + $builder = $this->getMock('Symfony\Component\DependencyInjection\ContainerBuilder'); + $builder->expects($this->atLeastOnce()) + ->method('findTaggedServiceIds') + ->will($this->returnValue($services)); + + $this->setExpectedException('InvalidArgumentException'); + + $profilerPass = new ProfilerPass(); + $profilerPass->process($builder); + } + + public function testValidCollector() + { + // one service, with a template key, but no id + $services = array( + 'my_collector_service' => array(0 => array('template' => 'foo', 'id' => 'my_collector')), + ); + + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerBuilder'); + $container->expects($this->atLeastOnce()) + ->method('findTaggedServiceIds') + ->will($this->returnValue($services)); + + // fake the getDefinition() to return a Profiler definition + $definition = new Definition('ProfilerClass'); + $container->expects($this->atLeastOnce()) + ->method('getDefinition') + ->will($this->returnValue($definition)); + + // assert that the data_collector.templates parameter should be set + $container->expects($this->once()) + ->method('setParameter') + ->with('data_collector.templates', array('my_collector_service' => array('my_collector', 'foo'))); + + $profilerPass = new ProfilerPass(); + $profilerPass->process($container); + + // grab the method calls off of the "profiler" definition + $methodCalls = $definition->getMethodCalls(); + $this->assertCount(1, $methodCalls); + $this->assertEquals('add', $methodCalls[0][0]); // grab the method part of the first call + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/RegisterKernelListenersPassTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/RegisterKernelListenersPassTest.php new file mode 100644 index 0000000..8e30138 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/RegisterKernelListenersPassTest.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\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\RegisterKernelListenersPass; + +class RegisterKernelListenersPassTest extends \PHPUnit_Framework_TestCase +{ + /** + * Tests that event subscribers not implementing EventSubscriberInterface + * trigger an exception. + * + * @expectedException \InvalidArgumentException + */ + public function testEventSubscriberWithoutInterface() + { + // one service, not implementing any interface + $services = array( + 'my_event_subscriber' => array(0 => array()), + ); + + $definition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); + $definition->expects($this->atLeastOnce()) + ->method('getClass') + ->will($this->returnValue('stdClass')); + + $builder = $this->getMock('Symfony\Component\DependencyInjection\ContainerBuilder'); + $builder->expects($this->any()) + ->method('hasDefinition') + ->will($this->returnValue(true)); + + // We don't test kernel.event_listener here + $builder->expects($this->atLeastOnce()) + ->method('findTaggedServiceIds') + ->will($this->onConsecutiveCalls(array(), $services)); + + $builder->expects($this->atLeastOnce()) + ->method('getDefinition') + ->will($this->returnValue($definition)); + + $registerListenersPass = new RegisterKernelListenersPass(); + $registerListenersPass->process($builder); + } + + public function testValidEventSubscriber() + { + $services = array( + 'my_event_subscriber' => array(0 => array()), + ); + + $definition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); + $definition->expects($this->atLeastOnce()) + ->method('getClass') + ->will($this->returnValue('Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler\SubscriberService')); + + $builder = $this->getMock('Symfony\Component\DependencyInjection\ContainerBuilder'); + $builder->expects($this->any()) + ->method('hasDefinition') + ->will($this->returnValue(true)); + + // We don't test kernel.event_listener here + $builder->expects($this->atLeastOnce()) + ->method('findTaggedServiceIds') + ->will($this->onConsecutiveCalls(array(), $services)); + + $builder->expects($this->atLeastOnce()) + ->method('getDefinition') + ->will($this->returnValue($definition)); + + $registerListenersPass = new RegisterKernelListenersPass(); + $registerListenersPass->process($builder); + } +} + +class SubscriberService implements \Symfony\Component\EventDispatcher\EventSubscriberInterface +{ + static function getSubscribedEvents() {} +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php new file mode 100644 index 0000000..871acb2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.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\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslatorPass; + +class TranslatorPassTest extends \PHPUnit_Framework_TestCase +{ + public function testValidCollector() + { + $definition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); + $definition->expects($this->at(0)) + ->method('addMethodCall') + ->with('addLoader', array('xliff', new Reference('xliff'))); + $definition->expects($this->at(1)) + ->method('addMethodCall') + ->with('addLoader', array('xlf', new Reference('xliff'))); + + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerBuilder'); + $container->expects($this->any()) + ->method('hasDefinition') + ->will($this->returnValue(true)); + $container->expects($this->once()) + ->method('getDefinition') + ->will($this->returnValue($definition)); + $container->expects($this->once()) + ->method('findTaggedServiceIds') + ->will($this->returnValue(array('xliff' => array(array('alias' => 'xliff', 'legacy-alias' => 'xlf'))))); + $container->expects($this->once()) + ->method('findDefinition') + ->will($this->returnValue($this->getMock('Symfony\Component\DependencyInjection\Definition'))); + ; + + $pass = new TranslatorPass(); + $pass->process($container); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/TestBundle/Resources/config/validation.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/TestBundle/Resources/config/validation.xml new file mode 100644 index 0000000..e69de29 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/TestBundle/Resources/config/validation.yml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/TestBundle/Resources/config/validation.yml new file mode 100644 index 0000000..e69de29 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/TestBundle/TestBundle.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/TestBundle/TestBundle.php new file mode 100644 index 0000000..e936bfd --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/TestBundle/TestBundle.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests; + +class TestBundle extends \Symfony\Component\HttpKernel\Bundle\Bundle +{ + +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/deprecated_merge_full.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/deprecated_merge_full.php new file mode 100644 index 0000000..5119fbd --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/deprecated_merge_full.php @@ -0,0 +1,22 @@ +loadFromExtension('framework', array( + 'secret' => 's3cr3t', + 'session' => array( + 'auto_start' => true, + 'storage_id' => 'session.storage.native', + 'handler_id' => 'session.handler.native_file', + 'name' => '_SYMFONY', + 'lifetime' => 2012, + 'path' => '/sf2', + 'domain' => 'sf2.example.com', + 'secure' => false, + 'httponly' => false, + 'cookie_lifetime' => 86400, + 'cookie_path' => '/', + 'cookie_domain' => 'example.com', + 'cookie_secure' => true, + 'cookie_httponly' => true, + ), +)); + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/deprecated_merge_partial.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/deprecated_merge_partial.php new file mode 100644 index 0000000..b15ea89 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/deprecated_merge_partial.php @@ -0,0 +1,19 @@ +loadFromExtension('framework', array( + 'secret' => 's3cr3t', + 'session' => array( + 'auto_start' => true, + 'storage_id' => 'session.storage.native', + 'handler_id' => 'session.handler.native_file', + 'name' => '_SYMFONY', + 'lifetime' => 2012, + 'path' => '/sf2', + 'domain' => 'sf2.example.com', + 'secure' => false, + 'cookie_lifetime' => 86400, + 'cookie_path' => '/', + 'cookie_httponly' => true, + ), +)); + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php new file mode 100644 index 0000000..c9ee3d9 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php @@ -0,0 +1,72 @@ +loadFromExtension('framework', array( + 'secret' => 's3cr3t', + 'default_locale' => 'fr', + 'form' => null, + 'csrf_protection' => array( + 'enabled' => true, + 'field_name' => '_csrf', + ), + 'esi' => array( + 'enabled' => true, + ), + 'profiler' => array( + 'only_exceptions' => true, + ), + 'router' => array( + 'resource' => '%kernel.root_dir%/config/routing.xml', + 'type' => 'xml', + ), + 'session' => array( + 'auto_start' => true, + 'storage_id' => 'session.storage.native', + 'handler_id' => 'session.handler.native_file', + 'name' => '_SYMFONY', + 'lifetime' => 86400, + 'path' => '/', + 'domain' => 'example.com', + 'secure' => true, + 'httponly' => true, + 'gc_maxlifetime' => 90000, + 'gc_divisor' => 108, + 'gc_probability' => 1, + 'save_path' => '/path/to/sessions', + ), + 'templating' => array( + 'assets_version' => 'SomeVersionScheme', + 'assets_base_urls' => 'http://cdn.example.com', + 'cache' => '/path/to/cache', + 'engines' => array('php', 'twig'), + 'loader' => array('loader.foo', 'loader.bar'), + 'packages' => array( + 'images' => array( + 'version' => '1.0.0', + 'base_urls' => array('http://images1.example.com', 'http://images2.example.com'), + ), + 'foo' => array( + 'version' => '1.0.0', + ), + 'bar' => array( + 'base_urls' => array('http://bar1.example.com', 'http://bar2.example.com'), + ), + ), + 'form' => array( + 'resources' => array('theme1', 'theme2') + ), + ), + 'translator' => array( + 'enabled' => true, + 'fallback' => 'fr', + ), + 'validation' => array( + 'enabled' => true, + 'cache' => 'apc', + ), + 'annotations' => array( + 'cache' => 'file', + 'debug' => true, + 'file_cache_dir' => '%kernel.cache_dir%/annotations', + ), + 'ide' => 'file%%link%%format' +)); diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/templating_url_package.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/templating_url_package.php new file mode 100644 index 0000000..a5dda77 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/templating_url_package.php @@ -0,0 +1,14 @@ +loadFromExtension('framework', array( + 'secret' => 's3cr3t', + 'templating' => array( + 'assets_base_urls' => 'https://cdn.example.com', + 'engines' => array('php', 'twig'), + 'packages' => array( + 'images' => array( + 'base_urls' => 'https://images.example.com', + ), + ), + ), +)); diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_annotations.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_annotations.php new file mode 100644 index 0000000..75c8f48 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_annotations.php @@ -0,0 +1,9 @@ +loadFromExtension('framework', array( + 'secret' => 's3cr3t', + 'validation' => array( + 'enabled' => true, + 'enable_annotations' => true, + ), +)); diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/deprecated_merge_full.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/deprecated_merge_full.xml new file mode 100644 index 0000000..7b95b42 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/deprecated_merge_full.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/deprecated_merge_partial.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/deprecated_merge_partial.xml new file mode 100644 index 0000000..701bae5 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/deprecated_merge_partial.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml new file mode 100644 index 0000000..9aea65b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + loader.foo + loader.bar + php + twig + http://cdn.example.com + + http://images1.example.com + http://images2.example.com + + + + http://bar1.example.com + http://bar2.example.com + + + theme1 + theme2 + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/templating_url_package.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/templating_url_package.xml new file mode 100644 index 0000000..0fd2039 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/templating_url_package.xml @@ -0,0 +1,19 @@ + + + + + + + php + twig + https://cdn.example.com + + https://images.example.com + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_annotations.xml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_annotations.xml new file mode 100644 index 0000000..22f1536 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_annotations.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/deprecated_merge_full.yml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/deprecated_merge_full.yml new file mode 100644 index 0000000..e5ec05f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/deprecated_merge_full.yml @@ -0,0 +1,17 @@ +framework: + secret: s3cr3t + session: + auto_start: true + storage_id: session.storage.native + handler_id: session.handler.native_file + name: _SYMFONY + lifetime: 2012 + path: /sf2 + domain: sf2.example.com + secure: false + httponly: false + cookie_lifetime: 86400 + cookie_path: / + cookie_domain: example.com + cookie_secure: true + cookie_httponly: true diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/deprecated_merge_partial.yml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/deprecated_merge_partial.yml new file mode 100644 index 0000000..67ea8bc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/deprecated_merge_partial.yml @@ -0,0 +1,15 @@ +framework: + secret: s3cr3t + session: + auto_start: true + storage_id: session.storage.native + handler_id: session.handler.native_file + name: _SYMFONY + lifetime: 2012 + path: /sf2 + domain: sf2.example.com + secure: false + httponly: false + cookie_lifetime: 86400 + cookie_path: / + cookie_httponly: true diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml new file mode 100644 index 0000000..5e97a55 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml @@ -0,0 +1,55 @@ +framework: + secret: s3cr3t + default_locale: fr + form: ~ + csrf_protection: + enabled: true + field_name: _csrf + esi: + enabled: true + profiler: + only_exceptions: true + router: + resource: %kernel.root_dir%/config/routing.xml + type: xml + session: + auto_start: true + storage_id: session.storage.native + handler_id: session.handler.native_file + name: _SYMFONY + lifetime: 86400 + path: / + domain: example.com + secure: true + httponly: true + gc_probability: 1 + gc_divisor: 108 + gc_maxlifetime: 90000 + save_path: /path/to/sessions + templating: + assets_version: SomeVersionScheme + assets_base_urls: http://cdn.example.com + engines: [php, twig] + loader: [loader.foo, loader.bar] + cache: /path/to/cache + packages: + images: + version: 1.0.0 + base_urls: ["http://images1.example.com", "http://images2.example.com"] + foo: + version: 1.0.0 + bar: + base_urls: ["http://images1.example.com", "http://images2.example.com"] + form: + resources: [theme1, theme2] + translator: + enabled: true + fallback: fr + validation: + enabled: true + cache: apc + annotations: + cache: file + debug: true + file_cache_dir: %kernel.cache_dir%/annotations + ide: file%%link%%format diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/templating_url_package.yml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/templating_url_package.yml new file mode 100644 index 0000000..bfec7a1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/templating_url_package.yml @@ -0,0 +1,8 @@ +framework: + secret: s3cr3t + templating: + assets_base_urls: https://cdn.example.com + engines: [php, twig] + packages: + images: + base_urls: https://images.example.com diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_annotations.yml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_annotations.yml new file mode 100644 index 0000000..41f1796 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_annotations.yml @@ -0,0 +1,5 @@ +framework: + secret: s3cr3t + validation: + enabled: true + enable_annotations: true diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php new file mode 100644 index 0000000..548b7e6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -0,0 +1,305 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection; + +use Symfony\Bundle\FrameworkBundle\Tests\TestCase; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\FrameworkExtension; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; + +abstract class FrameworkExtensionTest extends TestCase +{ + abstract protected function loadFromFile(ContainerBuilder $container, $file); + + public function testCsrfProtection() + { + $container = $this->createContainerFromFile('full'); + + $def = $container->getDefinition('form.type_extension.csrf'); + + $this->assertTrue($container->getParameter('form.type_extension.csrf.enabled')); + $this->assertEquals('%form.type_extension.csrf.enabled%', $def->getArgument(1)); + $this->assertEquals('_csrf', $container->getParameter('form.type_extension.csrf.field_name')); + $this->assertEquals('%form.type_extension.csrf.field_name%', $def->getArgument(2)); + $this->assertEquals('s3cr3t', $container->getParameterBag()->resolveValue($container->findDefinition('form.csrf_provider')->getArgument(1))); + } + + public function testEsi() + { + $container = $this->createContainerFromFile('full'); + + $this->assertTrue($container->hasDefinition('esi'), '->registerEsiConfiguration() loads esi.xml'); + } + + public function testProfiler() + { + $container = $this->createContainerFromFile('full'); + + $this->assertTrue($container->hasDefinition('profiler'), '->registerProfilerConfiguration() loads profiling.xml'); + $this->assertTrue($container->hasDefinition('data_collector.config'), '->registerProfilerConfiguration() loads collectors.xml'); + $this->assertTrue($container->getParameter('profiler_listener.only_exceptions')); + $this->assertEquals('%profiler_listener.only_exceptions%', $container->getDefinition('profiler_listener')->getArgument(2)); + } + + public function testRouter() + { + $container = $this->createContainerFromFile('full'); + + $this->assertTrue($container->has('router'), '->registerRouterConfiguration() loads routing.xml'); + $arguments = $container->findDefinition('router')->getArguments(); + $this->assertEquals($container->getParameter('kernel.root_dir').'/config/routing.xml', $container->getParameter('router.resource'), '->registerRouterConfiguration() sets routing resource'); + $this->assertEquals('%router.resource%', $arguments[1], '->registerRouterConfiguration() sets routing resource'); + $this->assertEquals('xml', $arguments[2]['resource_type'], '->registerRouterConfiguration() sets routing resource type'); + } + + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + */ + public function testRouterRequiresResourceOption() + { + $container = $this->createContainer(); + $loader = new FrameworkExtension(); + $loader->load(array(array('router' => true)), $container); + } + + public function testSession() + { + $container = $this->createContainerFromFile('full'); + + $this->assertTrue($container->hasDefinition('session'), '->registerSessionConfiguration() loads session.xml'); + $this->assertEquals('fr', $container->getParameter('kernel.default_locale')); + $this->assertTrue($container->getDefinition('session_listener')->getArgument(1)); + $this->assertEquals('session.storage.native', (string) $container->getAlias('session.storage')); + $this->assertEquals('session.handler.native_file', (string) $container->getAlias('session.handler')); + + $options = $container->getParameter('session.storage.options'); + $this->assertEquals('_SYMFONY', $options['name']); + $this->assertEquals(86400, $options['cookie_lifetime']); + $this->assertEquals('/', $options['cookie_path']); + $this->assertEquals('example.com', $options['cookie_domain']); + $this->assertTrue($options['cookie_secure']); + $this->assertTrue($options['cookie_httponly']); + $this->assertEquals(108, $options['gc_divisor']); + $this->assertEquals(1, $options['gc_probability']); + $this->assertEquals(90000, $options['gc_maxlifetime']); + + $this->assertEquals('/path/to/sessions', $container->getParameter('session.save_path')); + } + + public function testSessionDeprecatedMergeFull() + { + $container = $this->createContainerFromFile('deprecated_merge_full'); + + $this->assertTrue($container->hasDefinition('session'), '->registerSessionConfiguration() loads session.xml'); + + $options = $container->getParameter('session.storage.options'); + $this->assertEquals('_SYMFONY', $options['name']); + $this->assertEquals(86400, $options['cookie_lifetime']); + $this->assertEquals('/', $options['cookie_path']); + $this->assertEquals('example.com', $options['cookie_domain']); + $this->assertTrue($options['cookie_secure']); + $this->assertTrue($options['cookie_httponly']); + } + + public function testSessionDeprecatedMergePartial() + { + $container = $this->createContainerFromFile('deprecated_merge_partial'); + + $this->assertTrue($container->hasDefinition('session'), '->registerSessionConfiguration() loads session.xml'); + + $options = $container->getParameter('session.storage.options'); + $this->assertEquals('_SYMFONY', $options['name']); + $this->assertEquals(86400, $options['cookie_lifetime']); + $this->assertEquals('/', $options['cookie_path']); + $this->assertEquals('sf2.example.com', $options['cookie_domain']); + $this->assertFalse($options['cookie_secure']); + $this->assertTrue($options['cookie_httponly']); + } + + public function testTemplating() + { + $container = $this->createContainerFromFile('full'); + + $this->assertTrue($container->hasDefinition('templating.name_parser'), '->registerTemplatingConfiguration() loads templating.xml'); + + $this->assertEquals('request', $container->getDefinition('templating.helper.assets')->getScope(), '->registerTemplatingConfiguration() sets request scope on assets helper if one or more packages are request-scoped'); + + // default package should have one http base url and path package ssl url + $this->assertTrue($container->hasDefinition('templating.asset.default_package.http')); + $package = $container->getDefinition('templating.asset.default_package.http'); + $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\DefinitionDecorator', $package); + $this->assertEquals('templating.asset.url_package', $package->getParent()); + $arguments = array_values($package->getArguments()); + $this->assertEquals(array('http://cdn.example.com'), $arguments[0]); + $this->assertEquals('SomeVersionScheme', $arguments[1]); + $this->assertEquals('%%s?%%s', $arguments[2]); + + $this->assertTrue($container->hasDefinition('templating.asset.default_package.ssl')); + $package = $container->getDefinition('templating.asset.default_package.ssl'); + $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\DefinitionDecorator', $package); + $this->assertEquals('templating.asset.path_package', $package->getParent()); + + $this->assertEquals('templating.engine.delegating', (string) $container->getAlias('templating'), '->registerTemplatingConfiguration() configures delegating loader if multiple engines are provided'); + + $this->assertEquals($container->getDefinition('templating.loader.chain'), $container->getDefinition('templating.loader.wrapped'), '->registerTemplatingConfiguration() configures loader chain if multiple loaders are provided'); + + $this->assertEquals($container->getDefinition('templating.loader'), $container->getDefinition('templating.loader.cache'), '->registerTemplatingConfiguration() configures the loader to use cache'); + + $this->assertEquals('%templating.loader.cache.path%', $container->getDefinition('templating.loader.cache')->getArgument(1)); + $this->assertEquals('/path/to/cache', $container->getParameter('templating.loader.cache.path')); + + $this->assertEquals(array('php', 'twig'), $container->getParameter('templating.engines'), '->registerTemplatingConfiguration() sets a templating.engines parameter'); + + $this->assertEquals(array('FrameworkBundle:Form', 'theme1', 'theme2'), $container->getParameter('templating.helper.form.resources'), '->registerTemplatingConfiguration() registers the theme and adds the base theme'); + } + + public function testTemplatingAssetsHelperScopeDependsOnPackageArgumentScopes() + { + $container = $this->createContainerFromFile('templating_url_package'); + + $this->assertNotEquals('request', $container->getDefinition('templating.helper.assets')->getScope(), '->registerTemplatingConfiguration() does not set request scope on assets helper if no packages are request-scoped'); + } + + public function testTranslator() + { + $container = $this->createContainerFromFile('full'); + + $this->assertTrue($container->hasDefinition('translator.default'), '->registerTranslatorConfiguration() loads translation.xml'); + $this->assertEquals('translator.default', (string) $container->getAlias('translator'), '->registerTranslatorConfiguration() redefines translator service from identity to real translator'); + + $resources = array(); + foreach ($container->getDefinition('translator.default')->getMethodCalls() as $call) { + if ('addResource' == $call[0]) { + $resources[] = $call[1]; + } + } + + $files = array_map(function($resource) use ($resources) { return str_replace(realpath(__DIR__.'/../../../../..').'/', '', realpath($resource[1])); }, $resources); + $this->assertContains( + 'Symfony/Component/Validator/Resources/translations/validators.en.xlf', + $files, + '->registerTranslatorConfiguration() finds Validator translation resources' + ); + $this->assertContains( + 'Symfony/Component/Form/Resources/translations/validators.en.xlf', + $files, + '->registerTranslatorConfiguration() finds Form translation resources' + ); + + $calls = $container->getDefinition('translator.default')->getMethodCalls(); + $this->assertEquals('fr', $calls[0][1][0]); + } + + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + */ + public function testTemplatingRequiresAtLeastOneEngine() + { + $container = $this->createContainer(); + $loader = new FrameworkExtension(); + $loader->load(array(array('templating' => null)), $container); + } + + public function testValidation() + { + $container = $this->createContainerFromFile('full'); + + $this->assertTrue($container->hasDefinition('validator'), '->registerValidationConfiguration() loads validator.xml'); + $this->assertTrue($container->hasDefinition('validator.mapping.loader.xml_files_loader'), '->registerValidationConfiguration() defines the XML loader'); + $this->assertTrue($container->hasDefinition('validator.mapping.loader.yaml_files_loader'), '->registerValidationConfiguration() defines the YAML loader'); + + $xmlFiles = $container->getParameter('validator.mapping.loader.xml_files_loader.mapping_files'); + $this->assertContains( + realpath(__DIR__.'/../../../../Component/Form/Resources/config/validation.xml'), + array_map('realpath', $xmlFiles), + '->registerValidationConfiguration() adds Form validation.xml to XML loader' + ); + } + + public function testAnnotations() + { + if (!class_exists('Doctrine\\Common\\Version')) { + $this->markTestSkipped('Doctrine is not available.'); + } + + $container = $this->createContainerFromFile('full'); + + $this->assertEquals($container->getParameter('kernel.cache_dir').'/annotations', $container->getDefinition('annotations.file_cache_reader')->getArgument(1)); + $this->assertInstanceOf('Doctrine\Common\Annotations\FileCacheReader', $container->get('annotation_reader')); + } + + public function testFileLinkFormat() + { + $container = $this->createContainerFromFile('full'); + + $this->assertEquals('file%link%format', $container->getParameter('templating.helper.code.file_link_format')); + } + + public function testValidationAnnotations() + { + $container = $this->createContainerFromFile('validation_annotations'); + + $this->assertTrue($container->hasDefinition('validator.mapping.loader.annotation_loader'), '->registerValidationConfiguration() defines the annotation loader'); + $loaders = $container->getDefinition('validator.mapping.loader.loader_chain')->getArgument(0); + $found = false; + foreach ($loaders as $loader) { + if ('validator.mapping.loader.annotation_loader' === (string) $loader) { + $found = true; + } + } + $this->assertTrue($found, 'validator.mapping.loader.annotation_loader is added to the loader chain.'); + } + + public function testValidationPaths() + { + require_once __DIR__."/Fixtures/TestBundle/TestBundle.php"; + + $container = $this->createContainerFromFile('validation_annotations', array( + 'kernel.bundles' => array('TestBundle' => 'Symfony\Bundle\FrameworkBundle\Tests\TestBundle'), + )); + + $yamlArgs = $container->getParameter('validator.mapping.loader.yaml_files_loader.mapping_files'); + $this->assertCount(1, $yamlArgs); + $this->assertStringEndsWith('TestBundle'.DIRECTORY_SEPARATOR.'Resources'.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'validation.yml', $yamlArgs[0]); + + $xmlArgs = $container->getParameter('validator.mapping.loader.xml_files_loader.mapping_files'); + $this->assertCount(2, $xmlArgs); + $this->assertStringEndsWith('Component'.DIRECTORY_SEPARATOR.'Form/Resources/config/validation.xml', $xmlArgs[0]); + $this->assertStringEndsWith('TestBundle'.DIRECTORY_SEPARATOR.'Resources'.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'validation.xml', $xmlArgs[1]); + } + + protected function createContainer(array $data = array()) + { + return new ContainerBuilder(new ParameterBag(array_merge(array( + 'kernel.bundles' => array('FrameworkBundle' => 'Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle'), + 'kernel.cache_dir' => __DIR__, + 'kernel.compiled_classes' => array(), + 'kernel.debug' => false, + 'kernel.environment' => 'test', + 'kernel.name' => 'kernel', + 'kernel.root_dir' => __DIR__, + ), $data))); + } + + protected function createContainerFromFile($file, $data = array()) + { + $container = $this->createContainer($data); + $container->registerExtension(new FrameworkExtension()); + $this->loadFromFile($container, $file); + + $container->getCompilerPassConfig()->setOptimizationPasses(array()); + $container->getCompilerPassConfig()->setRemovingPasses(array()); + $container->compile(); + + return $container; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/PhpFrameworkExtensionTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/PhpFrameworkExtensionTest.php new file mode 100644 index 0000000..fad373e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/PhpFrameworkExtensionTest.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\Bundle\FrameworkBundle\Tests\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use Symfony\Component\Config\FileLocator; + +class PhpFrameworkExtensionTest extends FrameworkExtensionTest +{ + protected function loadFromFile(ContainerBuilder $container, $file) + { + $loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/Fixtures/php')); + $loader->load($file.'.php'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/XmlFrameworkExtensionTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/XmlFrameworkExtensionTest.php new file mode 100644 index 0000000..2c27eb0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/XmlFrameworkExtensionTest.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\Bundle\FrameworkBundle\Tests\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\Config\FileLocator; + +class XmlFrameworkExtensionTest extends FrameworkExtensionTest +{ + protected function loadFromFile(ContainerBuilder $container, $file) + { + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/Fixtures/xml')); + $loader->load($file.'.xml'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/YamlFrameworkExtensionTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/YamlFrameworkExtensionTest.php new file mode 100644 index 0000000..43070c0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/YamlFrameworkExtensionTest.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\Bundle\FrameworkBundle\Tests\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\Config\FileLocator; + +class YamlFrameworkExtensionTest extends FrameworkExtensionTest +{ + protected function loadFromFile(ContainerBuilder $container, $file) + { + $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/Fixtures/yml')); + $loader->load($file.'.yml'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/EventListener/TestSessionListenerTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/EventListener/TestSessionListenerTest.php new file mode 100644 index 0000000..88fadf2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/EventListener/TestSessionListenerTest.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\Bundle\FrameworkBundle\Tests\EventListener; + +use Symfony\Bundle\FrameworkBundle\EventListener\TestSessionListener; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; + +/** + * SessionListenerTest. + * + * Tests SessionListener. + * + * @author Bulat Shakirzyanov + */ +class TestSessionListenerTest extends \PHPUnit_Framework_TestCase +{ + private $listener; + private $session; + + protected function setUp() + { + $this->listener = new TestSessionListener($this->getMock('Symfony\Component\DependencyInjection\ContainerInterface')); + $this->session = $this->getSession(); + } + + protected function tearDown() + { + $this->listener = null; + $this->session = null; + } + + public function testShouldSaveMasterRequestSession() + { + $this->sessionMustBeSaved(); + + $this->filterResponse(new Request()); + } + + public function testShouldNotSaveSubRequestSession() + { + $this->sessionMustNotBeSaved(); + + $this->filterResponse(new Request(), HttpKernelInterface::SUB_REQUEST); + } + + public function testDoesNotDeleteCookieIfUsingSessionLifetime() + { + $params = session_get_cookie_params(); + session_set_cookie_params(0, $params['path'], $params['domain'], $params['secure'], $params['httponly']); + + $response = $this->filterResponse(new Request(), HttpKernelInterface::MASTER_REQUEST); + $cookies = $response->headers->getCookies(); + + $this->assertEquals(0, reset($cookies)->getExpiresTime()); + } + + private function filterResponse(Request $request, $type = HttpKernelInterface::MASTER_REQUEST) + { + $request->setSession($this->session); + $response = new Response(); + $kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface'); + $event = new FilterResponseEvent($kernel, $request, $type, $response); + + $this->listener->onKernelResponse($event); + + $this->assertSame($response, $event->getResponse()); + + return $response; + } + + private function sessionMustNotBeSaved() + { + $this->session->expects($this->never()) + ->method('save'); + } + + private function sessionMustBeSaved() + { + $this->session->expects($this->once()) + ->method('save'); + } + + private function getSession() + { + $mock = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\Session') + ->disableOriginalConstructor() + ->getMock(); + + // set return value for getName() + $mock->expects($this->any())->method('getName')->will($this->returnValue('MOCKSESSID')); + + return $mock; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/BaseBundle/BaseBundle.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/BaseBundle/BaseBundle.php new file mode 100644 index 0000000..494a18d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/BaseBundle/BaseBundle.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\Bundle\FrameworkBundle\Tests\Fixtures\BaseBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class BaseBundle extends Bundle +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/BaseBundle/Resources/views/base.format.engine b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/BaseBundle/Resources/views/base.format.engine new file mode 100644 index 0000000..e69de29 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/BaseBundle/Resources/views/controller/base.format.engine b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/BaseBundle/Resources/views/controller/base.format.engine new file mode 100644 index 0000000..e69de29 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/BaseBundle/Resources/views/this.is.a.template.format.engine b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/BaseBundle/Resources/views/this.is.a.template.format.engine new file mode 100644 index 0000000..e69de29 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/resource.format.engine b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/resource.format.engine new file mode 100644 index 0000000..e69de29 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/this.is.a.template.format.engine b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/this.is.a.template.format.engine new file mode 100644 index 0000000..e69de29 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/translation.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/translation.html.php new file mode 100644 index 0000000..48ea9fd --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/translation.html.php @@ -0,0 +1,2 @@ +This template is used for translation message extraction tests +trans('new key') ?> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Fabpot/FooBundle/Controller/DefaultController.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Fabpot/FooBundle/Controller/DefaultController.php new file mode 100644 index 0000000..c4bee6c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Fabpot/FooBundle/Controller/DefaultController.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 TestBundle\Fabpot\FooBundle\Controller; + +/** + * DefaultController. + * + * @author Fabien Potencier + */ +class DefaultController +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Fabpot/FooBundle/FabpotFooBundle.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Fabpot/FooBundle/FabpotFooBundle.php new file mode 100644 index 0000000..17894ba --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Fabpot/FooBundle/FabpotFooBundle.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 TestBundle\Fabpot\FooBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +/** + * Bundle. + * + * @author Fabien Potencier + */ +class FabpotFooBundle extends Bundle +{ + /** + * {@inheritdoc} + */ + public function getParent() + { + return 'SensioFooBundle'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/FooBundle/Controller/DefaultController.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/FooBundle/Controller/DefaultController.php new file mode 100644 index 0000000..ddda38c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/FooBundle/Controller/DefaultController.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 TestBundle\FooBundle\Controller; + +/** + * DefaultController. + * + * @author Fabien Potencier + */ +class DefaultController +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/FooBundle/Controller/Sub/DefaultController.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/FooBundle/Controller/Sub/DefaultController.php new file mode 100644 index 0000000..3c889e7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/FooBundle/Controller/Sub/DefaultController.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 TestBundle\FooBundle\Controller\Sub; + +/** + * DefaultController. + * + * @author Fabien Potencier + */ +class DefaultController +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/FooBundle/Controller/Test/DefaultController.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/FooBundle/Controller/Test/DefaultController.php new file mode 100644 index 0000000..1bffc7f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/FooBundle/Controller/Test/DefaultController.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 TestBundle\FooBundle\Controller\Test; + +/** + * DefaultController. + * + * @author Fabien Potencier + */ +class DefaultController +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/FooBundle/FooBundle.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/FooBundle/FooBundle.php new file mode 100644 index 0000000..656f17c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/FooBundle/FooBundle.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 TestBundle\FooBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +/** + * Bundle. + * + * @author Fabien Potencier + */ +class FooBundle extends Bundle +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Sensio/Cms/FooBundle/Controller/DefaultController.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Sensio/Cms/FooBundle/Controller/DefaultController.php new file mode 100644 index 0000000..1bb8038 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Sensio/Cms/FooBundle/Controller/DefaultController.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 TestBundle\Sensio\Cms\FooBundle\Controller; + +/** + * DefaultController. + * + * @author Fabien Potencier + */ +class DefaultController +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Sensio/Cms/FooBundle/SensioCmsFooBundle.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Sensio/Cms/FooBundle/SensioCmsFooBundle.php new file mode 100644 index 0000000..58967d8 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Sensio/Cms/FooBundle/SensioCmsFooBundle.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 TestBundle\Sensio\Cms\FooBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +/** + * Bundle. + * + * @author Fabien Potencier + */ +class SensioCmsFooBundle extends Bundle +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Sensio/FooBundle/Controller/DefaultController.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Sensio/FooBundle/Controller/DefaultController.php new file mode 100644 index 0000000..86486f0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Sensio/FooBundle/Controller/DefaultController.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 TestBundle\Sensio\FooBundle\Controller; + +/** + * DefaultController. + * + * @author Fabien Potencier + */ +class DefaultController +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Sensio/FooBundle/SensioFooBundle.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Sensio/FooBundle/SensioFooBundle.php new file mode 100644 index 0000000..d1bc5dc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Sensio/FooBundle/SensioFooBundle.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 TestBundle\Sensio\FooBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +/** + * Bundle. + * + * @author Fabien Potencier + */ +class SensioFooBundle extends Bundle +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SessionController.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SessionController.php new file mode 100644 index 0000000..8d39576 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SessionController.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\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller; + +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\DependencyInjection\ContainerAware; + +class SessionController extends ContainerAware +{ + public function welcomeAction($name=null) + { + $request = $this->container->get('request'); + $session = $request->getSession(); + + // new session case + if (!$session->has('name')) { + if (!$name) { + return new Response('You are new here and gave no name.'); + } + + // remember name + $session->set('name', $name); + + return new Response(sprintf('Hello %s, nice to meet you.', $name)); + } + + // existing session + $name = $session->get('name'); + + return new Response(sprintf('Welcome back %s, nice to meet you.', $name)); + } + + public function logoutAction() + { + $request = $this->container->get('request')->getSession('session')->invalidate(); + + return new Response('Session cleared.'); + } + + public function setFlashAction($message) + { + $request = $this->container->get('request'); + $session = $request->getSession(); + $session->getFlashBag()->set('notice', $message); + + return new RedirectResponse($this->container->get('router')->generate('session_showflash')); + } + + public function showFlashAction() + { + $request = $this->container->get('request'); + $session = $request->getSession(); + + if ($session->getFlashBag()->has('notice')) { + list($output) = $session->getFlashBag()->get('notice'); + } else { + $output = 'No flash was set.'; + } + + return new Response($output); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml new file mode 100644 index 0000000..7462fbf --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml @@ -0,0 +1,20 @@ +session_welcome: + pattern: /session + defaults: { _controller: TestBundle:Session:welcome } + +session_welcome_name: + pattern: /session/{name} + defaults: { _controller: TestBundle:Session:welcome } + +session_logout: + pattern: /session_logout + defaults: { _controller: TestBundle:Session:logout} + +session_setflash: + pattern: /session_setflash/{message} + defaults: { _controller: TestBundle:Session:setFlash} + +session_showflash: + pattern: /session_showflash + defaults: { _controller: TestBundle:Session:showFlash} + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/TestBundle.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/TestBundle.php new file mode 100644 index 0000000..d17347c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/TestBundle.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\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class TestBundle extends Bundle +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SessionTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SessionTest.php new file mode 100644 index 0000000..3e90e9d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SessionTest.php @@ -0,0 +1,154 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Functional; + +/** + * @group functional + */ +class SessionTest extends WebTestCase +{ + /** + * Tests session attributes persist. + * + * @dataProvider getConfigs + */ + public function testWelcome($config, $insulate) + { + $client = $this->createClient(array('test_case' => 'Session', 'root_config' => $config)); + if ($insulate) { + $client->insulate(); + } + + // no session + $crawler = $client->request('GET', '/session'); + $this->assertContains('You are new here and gave no name.', $crawler->text()); + + // remember name + $crawler = $client->request('GET', '/session/drak'); + $this->assertContains('Hello drak, nice to meet you.', $crawler->text()); + + // prove remembered name + $crawler = $client->request('GET', '/session'); + $this->assertContains('Welcome back drak, nice to meet you.', $crawler->text()); + + // clear session + $crawler = $client->request('GET', '/session_logout'); + $this->assertContains('Session cleared.', $crawler->text()); + + // prove cleared session + $crawler = $client->request('GET', '/session'); + $this->assertContains('You are new here and gave no name.', $crawler->text()); + } + + /** + * Tests flash messages work in practice. + * + * @dataProvider getConfigs + */ + public function testFlash($config, $insulate) + { + $client = $this->createClient(array('test_case' => 'Session', 'root_config' => $config)); + if ($insulate) { + $client->insulate(); + } + + // set flash + $crawler = $client->request('GET', '/session_setflash/Hello%20world.'); + + // check flash displays on redirect + $this->assertContains('Hello world.', $client->followRedirect()->text()); + + // check flash is gone + $crawler = $client->request('GET', '/session_showflash'); + $this->assertContains('No flash was set.', $crawler->text()); + } + + /** + * See if two separate insulated clients can run without + * polluting eachother's session data. + * + * @dataProvider getConfigs + */ + public function testTwoClients($config, $insulate) + { + // start first client + $client1 = $this->createClient(array('test_case' => 'Session', 'root_config' => $config)); + if ($insulate) { + $client1->insulate(); + } + + // start second client + $client2 = $this->createClient(array('test_case' => 'Session', 'root_config' => $config)); + if ($insulate) { + $client2->insulate(); + } + + // new session, so no name set. + $crawler1 = $client1->request('GET', '/session'); + $this->assertContains('You are new here and gave no name.', $crawler1->text()); + + // set name of client1 + $crawler1 = $client1->request('GET', '/session/client1'); + $this->assertContains('Hello client1, nice to meet you.', $crawler1->text()); + + // no session for client2 + $crawler2 = $client2->request('GET', '/session'); + $this->assertContains('You are new here and gave no name.', $crawler2->text()); + + // remember name client2 + $crawler2 = $client2->request('GET', '/session/client2'); + $this->assertContains('Hello client2, nice to meet you.', $crawler2->text()); + + // prove remembered name of client1 + $crawler1 = $client1->request('GET', '/session'); + $this->assertContains('Welcome back client1, nice to meet you.', $crawler1->text()); + + // prove remembered name of client2 + $crawler2 = $client2->request('GET', '/session'); + $this->assertContains('Welcome back client2, nice to meet you.', $crawler2->text()); + + // clear client1 + $crawler1 = $client1->request('GET', '/session_logout'); + $this->assertContains('Session cleared.', $crawler1->text()); + + // prove client1 data is cleared + $crawler1 = $client1->request('GET', '/session'); + $this->assertContains('You are new here and gave no name.', $crawler1->text()); + + // prove remembered name of client2 remains untouched. + $crawler2 = $client2->request('GET', '/session'); + $this->assertContains('Welcome back client2, nice to meet you.', $crawler2->text()); + } + + public function getConfigs() + { + return array( + // configfile, insulate + array('config.yml', true), + array('config.yml', false), + ); + } + + protected function setUp() + { + parent::setUp(); + + $this->deleteTmpDir('SessionTest'); + } + + protected function tearDown() + { + parent::tearDown(); + + $this->deleteTmpDir('SessionTest'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/WebTestCase.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/WebTestCase.php new file mode 100644 index 0000000..e5bbe87 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/WebTestCase.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\Bundle\FrameworkBundle\Tests\Functional; + +use Symfony\Bundle\FrameworkBundle\Test\WebTestCase as BaseWebTestCase; +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\HttpKernel\Kernel; + +class WebTestCase extends BaseWebTestCase +{ + static public function assertRedirect($response, $location) + { + self::assertTrue($response->isRedirect(), 'Response is not a redirect, got status code: '.$response->getStatusCode()); + self::assertEquals('http://localhost'.$location, $response->headers->get('Location')); + } + + protected function setUp() + { + if (!class_exists('Twig_Environment')) { + $this->markTestSkipped('Twig is not available.'); + } + + parent::setUp(); + } + + protected function deleteTmpDir($testCase) + { + if (!file_exists($dir = sys_get_temp_dir().'/'.Kernel::VERSION.'/'.$testCase)) { + return; + } + + $fs = new Filesystem(); + $fs->remove($dir); + } + + static protected function getKernelClass() + { + require_once __DIR__.'/app/AppKernel.php'; + + return 'Symfony\Bundle\FrameworkBundle\Tests\Functional\AppKernel'; + } + + static protected function createKernel(array $options = array()) + { + $class = self::getKernelClass(); + + if (!isset($options['test_case'])) { + throw new \InvalidArgumentException('The option "test_case" must be set.'); + } + + return new $class( + $options['test_case'], + isset($options['root_config']) ? $options['root_config'] : 'config.yml', + isset($options['environment']) ? $options['environment'] : 'frameworkbundletest', + isset($options['debug']) ? $options['debug'] : true + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AppKernel.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AppKernel.php new file mode 100644 index 0000000..655c9c7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AppKernel.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\Bundle\FrameworkBundle\Tests\Functional; + +// get the autoload file +$dir = __DIR__; +$lastDir = null; +while ($dir !== $lastDir) { + $lastDir = $dir; + + if (file_exists($dir.'/autoload.php')) { + require_once $dir.'/autoload.php'; + break; + } + + if (file_exists($dir.'/autoload.php.dist')) { + require_once $dir.'/autoload.php.dist'; + break; + } + + $dir = dirname($dir); +} + +use Symfony\Component\Config\Loader\LoaderInterface; +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\HttpKernel\Kernel; + +/** + * App Test Kernel for functional tests. + * + * @author Johannes M. Schmitt + */ +class AppKernel extends Kernel +{ + private $testCase; + private $rootConfig; + + public function __construct($testCase, $rootConfig, $environment, $debug) + { + if (!is_dir(__DIR__.'/'.$testCase)) { + throw new \InvalidArgumentException(sprintf('The test case "%s" does not exist.', $testCase)); + } + $this->testCase = $testCase; + + $fs = new Filesystem(); + if (!$fs->isAbsolutePath($rootConfig) && !file_exists($rootConfig = __DIR__.'/'.$testCase.'/'.$rootConfig)) { + throw new \InvalidArgumentException(sprintf('The root config "%s" does not exist.', $rootConfig)); + } + $this->rootConfig = $rootConfig; + + parent::__construct($environment, $debug); + } + + public function registerBundles() + { + if (!file_exists($filename = $this->getRootDir().'/'.$this->testCase.'/bundles.php')) { + throw new \RuntimeException(sprintf('The bundles file "%s" does not exist.', $filename)); + } + + return include $filename; + } + + public function init() + { + } + + public function getRootDir() + { + return __DIR__; + } + + public function getCacheDir() + { + return sys_get_temp_dir().'/'.Kernel::VERSION.'/'.$this->testCase.'/cache/'.$this->environment; + } + + public function getLogDir() + { + return sys_get_temp_dir().'/'.Kernel::VERSION.'/'.$this->testCase.'/logs'; + } + + public function registerContainerConfiguration(LoaderInterface $loader) + { + $loader->load($this->rootConfig); + } + + public function serialize() + { + return serialize(array($this->testCase, $this->rootConfig, $this->getEnvironment(), $this->isDebug())); + } + + public function unserialize($str) + { + call_user_func_array(array($this, '__construct'), unserialize($str)); + } + + protected function getKernelParameters() + { + $parameters = parent::getKernelParameters(); + $parameters['kernel.test_case'] = $this->testCase; + + return $parameters; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Session/bundles.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Session/bundles.php new file mode 100644 index 0000000..351cf79 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Session/bundles.php @@ -0,0 +1,9 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests; + +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Bundle\FrameworkBundle\HttpKernel; +use Symfony\Component\EventDispatcher\EventDispatcher; + +class HttpKernelTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getProviderTypes + */ + public function testHandle($type) + { + $request = new Request(); + $expected = new Response(); + + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $container + ->expects($this->once()) + ->method('enterScope') + ->with($this->equalTo('request')) + ; + $container + ->expects($this->once()) + ->method('leaveScope') + ->with($this->equalTo('request')) + ; + $container + ->expects($this->once()) + ->method('set') + ->with($this->equalTo('request'), $this->equalTo($request), $this->equalTo('request')) + ; + + $dispatcher = new EventDispatcher(); + $resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface'); + $kernel = new HttpKernel($dispatcher, $container, $resolver); + + $controller = function() use($expected) { + return $expected; + }; + + $resolver->expects($this->once()) + ->method('getController') + ->with($request) + ->will($this->returnValue($controller)); + $resolver->expects($this->once()) + ->method('getArguments') + ->with($request, $controller) + ->will($this->returnValue(array())); + + $actual = $kernel->handle($request, $type); + + $this->assertSame($expected, $actual, '->handle() returns the response'); + } + + /** + * @dataProvider getProviderTypes + */ + public function testHandleRestoresThePreviousRequestOnException($type) + { + $request = new Request(); + $expected = new \Exception(); + + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $container + ->expects($this->once()) + ->method('enterScope') + ->with($this->equalTo('request')) + ; + $container + ->expects($this->once()) + ->method('leaveScope') + ->with($this->equalTo('request')) + ; + $container + ->expects($this->once()) + ->method('set') + ->with($this->equalTo('request'), $this->equalTo($request), $this->equalTo('request')) + ; + + $dispatcher = new EventDispatcher(); + $resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface'); + $kernel = new HttpKernel($dispatcher, $container, $resolver); + + $controller = function() use ($expected) { + throw $expected; + }; + + $resolver->expects($this->once()) + ->method('getController') + ->with($request) + ->will($this->returnValue($controller)); + $resolver->expects($this->once()) + ->method('getArguments') + ->with($request, $controller) + ->will($this->returnValue(array())); + + try { + $kernel->handle($request, $type); + $this->fail('->handle() suppresses the controller exception'); + } catch (\Exception $actual) { + $this->assertSame($expected, $actual, '->handle() throws the controller exception'); + } + } + + public function testGenerateInternalUriHandlesNullValues() + { + $request = new Request(); + + $router = $this->getMock('Symfony\\Component\\Routing\\RouterInterface'); + $container = $this->getMock('Symfony\\Component\\DependencyInjection\\ContainerInterface'); + $container + ->expects($this->at(0)) + ->method('get') + ->with($this->equalTo('router')) + ->will($this->returnValue($router)) + ; + $container + ->expects($this->at('1')) + ->method('get') + ->with($this->equalTo('request')) + ->will($this->returnValue($request)) + ; + + $controller = 'AController'; + $attributes = array('anAttribute' => null); + $query = array('aQueryParam' => null); + + $expectedPath = 'none'; + + $routeParameters = array('controller' => $controller, 'path' => $expectedPath, '_format' => 'html'); + $router + ->expects($this->once()) + ->method('generate') + ->with($this->equalTo('_internal'), $this->equalTo($routeParameters)) + ->will($this->returnValue('GENERATED_URI')) + ; + + $dispatcher = new EventDispatcher(); + $resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface'); + $kernel = new HttpKernel($dispatcher, $container, $resolver); + + $uri = $kernel->generateInternalUri($controller, $attributes, $query); + $this->assertEquals('GENERATED_URI', $uri); + } + + public function getProviderTypes() + { + return array( + array(HttpKernelInterface::MASTER_REQUEST), + array(HttpKernelInterface::SUB_REQUEST), + ); + } + + public function testExceptionInSubRequestsDoesNotMangleOutputBuffers() + { + $request = new Request(); + + $container = $this->getMock('Symfony\\Component\\DependencyInjection\\ContainerInterface'); + $container + ->expects($this->at(0)) + ->method('getParameter') + ->with($this->equalTo('kernel.debug')) + ->will($this->returnValue(false)) + ; + $container + ->expects($this->at(1)) + ->method('has') + ->with($this->equalTo('esi')) + ->will($this->returnValue(false)) + ; + $container + ->expects($this->at(2)) + ->method('get') + ->with($this->equalTo('request')) + ->will($this->returnValue($request)) + ; + + $dispatcher = new EventDispatcher(); + $resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface'); + $resolver->expects($this->once()) + ->method('getController') + ->will($this->returnValue(function () { + ob_start(); + echo 'bar'; + throw new \RuntimeException(); + })); + $resolver->expects($this->once()) + ->method('getArguments') + ->will($this->returnValue(array())); + + $kernel = new HttpKernel($dispatcher, $container, $resolver); + + // simulate a main request with output buffering + ob_start(); + echo 'Foo'; + + // simulate a sub-request with output buffering and an exception + $kernel->render('/'); + + $this->assertEquals('Foo', ob_get_clean()); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php new file mode 100644 index 0000000..fe8fc70 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.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\Bundle\FrameworkBundle\Tests\Routing; + +use Symfony\Component\Routing\Route; +use Symfony\Component\Routing\RouteCollection; +use Symfony\Bundle\FrameworkBundle\Routing\RedirectableUrlMatcher; +use Symfony\Component\Routing\RequestContext; + +class RedirectableUrlMatcherTest extends \PHPUnit_Framework_TestCase +{ + public function testRedirectWhenNoSlash() + { + $coll = new RouteCollection(); + $coll->add('foo', new Route('/foo/')); + + $matcher = new RedirectableUrlMatcher($coll, $context = new RequestContext()); + + $this->assertEquals(array( + '_controller' => 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction', + 'path' => '/foo/', + 'permanent' => true, + 'scheme' => null, + 'httpPort' => $context->getHttpPort(), + 'httpsPort' => $context->getHttpsPort(), + '_route' => null, + ), + $matcher->match('/foo') + ); + } + + public function testSchemeRedirect() + { + $coll = new RouteCollection(); + $coll->add('foo', new Route('/foo', array(), array('_scheme' => 'https'))); + + $matcher = new RedirectableUrlMatcher($coll, $context = new RequestContext()); + + $this->assertEquals(array( + '_controller' => 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction', + 'path' => '/foo', + 'permanent' => true, + 'scheme' => 'https', + 'httpPort' => $context->getHttpPort(), + 'httpsPort' => $context->getHttpsPort(), + '_route' => 'foo', + ), + $matcher->match('/foo') + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RouterTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RouterTest.php new file mode 100644 index 0000000..6c9f072 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RouterTest.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\Bundle\FrameworkBundle\Tests\Routing; + +use Symfony\Bundle\FrameworkBundle\Routing\Router; +use Symfony\Component\Routing\Route; +use Symfony\Component\Routing\RouteCollection; + +class RoutingTest extends \PHPUnit_Framework_TestCase +{ + public function testPlaceholders() + { + $routes = new RouteCollection(); + $routes->add('foo', new Route('/foo', array( + 'foo' => '%foo%', + 'bar' => '%bar%', + 'foobar' => 'foobar', + 'foo1' => '%foo', + 'foo2' => 'foo%', + 'foo3' => 'f%o%o', + ), array( + 'foo' => '%foo%', + 'bar' => '%bar%', + 'foobar' => 'foobar', + 'foo1' => '%foo', + 'foo2' => 'foo%', + 'foo3' => 'f%o%o', + ))); + + $sc = $this->getServiceContainer($routes); + $sc->expects($this->at(1))->method('hasParameter')->will($this->returnValue(false)); + $sc->expects($this->at(2))->method('hasParameter')->will($this->returnValue(true)); + $sc->expects($this->at(3))->method('getParameter')->will($this->returnValue('bar')); + $sc->expects($this->at(4))->method('hasParameter')->will($this->returnValue(false)); + $sc->expects($this->at(5))->method('hasParameter')->will($this->returnValue(true)); + $sc->expects($this->at(6))->method('getParameter')->will($this->returnValue('bar')); + + $router = new Router($sc, 'foo'); + $route = $router->getRouteCollection()->get('foo'); + + $this->assertEquals('%foo%', $route->getDefault('foo')); + $this->assertEquals('bar', $route->getDefault('bar')); + $this->assertEquals('foobar', $route->getDefault('foobar')); + $this->assertEquals('%foo', $route->getDefault('foo1')); + $this->assertEquals('foo%', $route->getDefault('foo2')); + $this->assertEquals('f%o%o', $route->getDefault('foo3')); + + $this->assertEquals('%foo%', $route->getRequirement('foo')); + $this->assertEquals('bar', $route->getRequirement('bar')); + $this->assertEquals('foobar', $route->getRequirement('foobar')); + $this->assertEquals('%foo', $route->getRequirement('foo1')); + $this->assertEquals('foo%', $route->getRequirement('foo2')); + $this->assertEquals('f%o%o', $route->getRequirement('foo3')); + } + + private function getServiceContainer(RouteCollection $routes) + { + $sc = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $sc + ->expects($this->once()) + ->method('get') + ->will($this->returnValue($this->getLoader($routes))) + ; + + return $sc; + } + + private function getLoader(RouteCollection $routes) + { + $loader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface'); + $loader + ->expects($this->any()) + ->method('load') + ->will($this->returnValue($routes)) + ; + + return $loader; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/CodeHelperTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/CodeHelperTest.php new file mode 100644 index 0000000..357170d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/CodeHelperTest.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\Bundle\FrameworkBundle\Tests\Templating\Helper; + +use Symfony\Bundle\FrameworkBundle\Templating\Helper\CodeHelper; + +class CodeHelperTest extends \PHPUnit_Framework_TestCase +{ + protected static $helper; + + static public function setUpBeforeClass() + { + self::$helper = new CodeHelper('txmt://open?url=file://%f&line=%l', '/root', 'UTF-8'); + } + + public function testFormatFile() + { + $expected = sprintf('%s at line 25', __FILE__, __FILE__); + $this->assertEquals($expected, self::$helper->formatFile(__FILE__, 25)); + } + + /** + * @dataProvider getClassNameProvider + */ + public function testGettingClassAbbreviation($class, $abbr) + { + $this->assertEquals(self::$helper->abbrClass($class), $abbr); + } + + /** + * @dataProvider getMethodNameProvider + */ + public function testGettingMethodAbbreviation($method, $abbr) + { + $this->assertEquals(self::$helper->abbrMethod($method), $abbr); + } + + public function getClassNameProvider() + { + return array( + array('F\Q\N\Foo', 'Foo'), + array('Bare', 'Bare'), + ); + } + + public function getMethodNameProvider() + { + return array( + array('F\Q\N\Foo::Method', 'Foo::Method()'), + array('Bare::Method', 'Bare::Method()'), + array('Closure', 'Closure'), + array('Method', 'Method()') + ); + } + + public function testGetName() + { + $this->assertEquals('code', self::$helper->getName()); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Fixtures/StubTemplateNameParser.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Fixtures/StubTemplateNameParser.php new file mode 100644 index 0000000..3a66454 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Fixtures/StubTemplateNameParser.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\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures; + +use Symfony\Component\Templating\TemplateNameParserInterface; +use Symfony\Component\Templating\TemplateReference; + +class StubTemplateNameParser implements TemplateNameParserInterface +{ + private $root; + + private $rootTheme; + + public function __construct($root, $rootTheme) + { + $this->root = $root; + $this->rootTheme = $rootTheme; + } + + public function parse($name) + { + list($bundle, $controller, $template) = explode(':', $name, 3); + + if ($template[0] == '_') { + $path = $this->rootTheme.'/Custom/'.$template; + } elseif ($bundle === 'TestBundle') { + $path = $this->rootTheme.'/'.$controller.'/'.$template; + } else { + $path = $this->root.'/'.$controller.'/'.$template; + } + + return new TemplateReference($path, 'php'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Fixtures/StubTranslator.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Fixtures/StubTranslator.php new file mode 100644 index 0000000..17d1fd4 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Fixtures/StubTranslator.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\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures; + +use Symfony\Component\Translation\TranslatorInterface; + +class StubTranslator implements TranslatorInterface +{ + public function trans($id, array $parameters = array(), $domain = null, $locale = null) + { + return '[trans]'.$id.'[/trans]'; + } + + public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null) + { + return '[trans]'.$id.'[/trans]'; + } + + public function setLocale($locale) + { + } + + public function getLocale() + { + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperDivLayoutTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperDivLayoutTest.php new file mode 100644 index 0000000..dbb6fa1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperDivLayoutTest.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\Bundle\FrameworkBundle\Tests\Templating\Helper; + +use Symfony\Bundle\FrameworkBundle\Templating\Helper\FormHelper; +use Symfony\Bundle\FrameworkBundle\Templating\Helper\TranslatorHelper; +use Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures\StubTemplateNameParser; +use Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures\StubTranslator; +use Symfony\Component\Form\FormView; +use Symfony\Component\Templating\PhpEngine; +use Symfony\Component\Templating\Loader\FilesystemLoader; +use Symfony\Component\Form\Tests\AbstractDivLayoutTest; + +class FormHelperDivLayoutTest extends AbstractDivLayoutTest +{ + protected $helper; + + protected function setUp() + { + parent::setUp(); + + $root = realpath(__DIR__.'/../../../Resources/views'); + $rootTheme = realpath(__DIR__.'/Resources'); + $templateNameParser = new StubTemplateNameParser($root, $rootTheme); + $loader = new FilesystemLoader(array()); + $engine = new PhpEngine($templateNameParser, $loader); + + $this->helper = new FormHelper($engine, $this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'), array('FrameworkBundle:Form')); + + $engine->setHelpers(array( + $this->helper, + new TranslatorHelper(new StubTranslator()), + )); + } + + protected function tearDown() + { + $this->helper = null; + } + + protected function renderEnctype(FormView $view) + { + return (string) $this->helper->enctype($view); + } + + protected function renderLabel(FormView $view, $label = null, array $vars = array()) + { + return (string) $this->helper->label($view, $label, $vars); + } + + protected function renderErrors(FormView $view) + { + return (string) $this->helper->errors($view); + } + + protected function renderWidget(FormView $view, array $vars = array()) + { + return (string) $this->helper->widget($view, $vars); + } + + protected function renderRow(FormView $view, array $vars = array()) + { + return (string) $this->helper->row($view, $vars); + } + + protected function renderRest(FormView $view, array $vars = array()) + { + return (string) $this->helper->rest($view, $vars); + } + + protected function setTheme(FormView $view, array $themes) + { + $this->helper->setTheme($view, $themes); + } + + static public function themeBlockInheritanceProvider() + { + return array( + array(array('TestBundle:Parent')) + ); + } + + static public function themeInheritanceProvider() + { + return array( + array(array('TestBundle:Parent'), array('TestBundle:Child')) + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperTableLayoutTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperTableLayoutTest.php new file mode 100644 index 0000000..22c1e19 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperTableLayoutTest.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\Bundle\FrameworkBundle\Tests\Templating\Helper; + +use Symfony\Bundle\FrameworkBundle\Templating\Helper\FormHelper; +use Symfony\Bundle\FrameworkBundle\Templating\Helper\TranslatorHelper; +use Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures\StubTemplateNameParser; +use Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures\StubTranslator; +use Symfony\Component\Form\FormView; +use Symfony\Component\Templating\PhpEngine; +use Symfony\Component\Templating\Loader\FilesystemLoader; +use Symfony\Component\Form\Tests\AbstractTableLayoutTest; + +class FormHelperTableLayoutTest extends AbstractTableLayoutTest +{ + protected $helper; + + protected function setUp() + { + parent::setUp(); + + $root = realpath(__DIR__.'/../../../Resources/views'); + $rootTheme = realpath(__DIR__.'/Resources'); + $templateNameParser = new StubTemplateNameParser($root, $rootTheme); + $loader = new FilesystemLoader(array()); + $engine = new PhpEngine($templateNameParser, $loader); + + $this->helper = new FormHelper($engine, $this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'), array( + 'FrameworkBundle:Form', + 'FrameworkBundle:FormTable' + )); + + $engine->setHelpers(array( + $this->helper, + new TranslatorHelper(new StubTranslator()), + )); + } + + protected function tearDown() + { + $this->helper = null; + } + + protected function renderEnctype(FormView $view) + { + return (string) $this->helper->enctype($view); + } + + protected function renderLabel(FormView $view, $label = null, array $vars = array()) + { + return (string) $this->helper->label($view, $label, $vars); + } + + protected function renderErrors(FormView $view) + { + return (string) $this->helper->errors($view); + } + + protected function renderWidget(FormView $view, array $vars = array()) + { + return (string) $this->helper->widget($view, $vars); + } + + protected function renderRow(FormView $view, array $vars = array()) + { + return (string) $this->helper->row($view, $vars); + } + + protected function renderRest(FormView $view, array $vars = array()) + { + return (string) $this->helper->rest($view, $vars); + } + + protected function setTheme(FormView $view, array $themes) + { + $this->helper->setTheme($view, $themes); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/RequestHelperTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/RequestHelperTest.php new file mode 100644 index 0000000..d3d4f22 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/RequestHelperTest.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\Bundle\FrameworkBundle\Tests\Templating\Helper; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Bundle\FrameworkBundle\Templating\Helper\RequestHelper; + +class RequestHelperTest extends \PHPUnit_Framework_TestCase +{ + protected $request; + + protected function setUp() + { + $this->request = new Request(); + $this->request->initialize(array('foobar' => 'bar')); + } + + protected function tearDown() + { + $this->request = null; + } + + public function testGetParameter() + { + $helper = new RequestHelper($this->request); + + $this->assertEquals('bar', $helper->getParameter('foobar')); + $this->assertEquals('foo', $helper->getParameter('bar', 'foo')); + + $this->assertNull($helper->getParameter('foo')); + } + + public function testGetLocale() + { + $helper = new RequestHelper($this->request); + + $this->assertEquals('en', $helper->getLocale()); + } + + public function testGetName() + { + $helper = new RequestHelper($this->request); + + $this->assertEquals('request', $helper->getName()); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Child/form_label.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Child/form_label.html.php new file mode 100644 index 0000000..3dec64b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Child/form_label.html.php @@ -0,0 +1 @@ + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Custom/_text_id_widget.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Custom/_text_id_widget.html.php new file mode 100644 index 0000000..078fe57 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Custom/_text_id_widget.html.php @@ -0,0 +1,3 @@ +
    + widget($form) ?> +
    diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/form_label.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/form_label.html.php new file mode 100644 index 0000000..068c5de --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/form_label.html.php @@ -0,0 +1 @@ + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/form_widget_simple.html.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/form_widget_simple.html.php new file mode 100644 index 0000000..6506f91 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/form_widget_simple.html.php @@ -0,0 +1,2 @@ + +renderBlock('widget_attributes') ?> value="" rel="theme" /> diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/SessionHelperTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/SessionHelperTest.php new file mode 100644 index 0000000..4bd043e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/SessionHelperTest.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\Bundle\FrameworkBundle\Tests\Templating\Helper; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Session\Session; +use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; +use Symfony\Bundle\FrameworkBundle\Templating\Helper\SessionHelper; + +class SessionHelperTest extends \PHPUnit_Framework_TestCase +{ + protected $request; + + protected function setUp() + { + $this->request = new Request(); + + $session = new Session(new MockArraySessionStorage()); + $session->set('foobar', 'bar'); + $session->getFlashBag()->set('notice', 'bar'); + + $this->request->setSession($session); + } + + protected function tearDown() + { + $this->request = null; + } + + public function testFlash() + { + $helper = new SessionHelper($this->request); + + $this->assertTrue($helper->hasFlash('notice')); + + $this->assertEquals(array('bar'), $helper->getFlash('notice')); + } + + public function testGetFlashes() + { + $helper = new SessionHelper($this->request); + $this->assertEquals(array('notice' => array('bar')), $helper->getFlashes()); + } + + public function testGet() + { + $helper = new SessionHelper($this->request); + + $this->assertEquals('bar', $helper->get('foobar')); + $this->assertEquals('foo', $helper->get('bar', 'foo')); + + $this->assertNull($helper->get('foo')); + } + + public function testGetName() + { + $helper = new SessionHelper($this->request); + + $this->assertEquals('session', $helper->getName()); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Loader/TemplateLocatorTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Loader/TemplateLocatorTest.php new file mode 100644 index 0000000..1b28ec4 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Loader/TemplateLocatorTest.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\Bundle\FrameworkBundle\Tests\Templating\Loader; + +use Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateLocator; +use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference; +use Symfony\Bundle\FrameworkBundle\Tests\TestCase; + +class TemplateLocatorTest extends TestCase +{ + public function testLocateATemplate() + { + $template = new TemplateReference('bundle', 'controller', 'name', 'format', 'engine'); + + $fileLocator = $this->getFileLocator(); + + $fileLocator + ->expects($this->once()) + ->method('locate') + ->with($template->getPath()) + ->will($this->returnValue('/path/to/template')) + ; + + $locator = new TemplateLocator($fileLocator); + + $this->assertEquals('/path/to/template', $locator->locate($template)); + } + + public function testThrowsExceptionWhenTemplateNotFound() + { + $template = new TemplateReference('bundle', 'controller', 'name', 'format', 'engine'); + + $fileLocator = $this->getFileLocator(); + + $errorMessage = 'FileLocator exception message'; + + $fileLocator + ->expects($this->once()) + ->method('locate') + ->will($this->throwException(new \InvalidArgumentException($errorMessage))) + ; + + $locator = new TemplateLocator($fileLocator); + + try { + $locator->locate($template); + $this->fail('->locate() should throw an exception when the file is not found.'); + } catch (\InvalidArgumentException $e) { + $this->assertContains( + $errorMessage, + $e->getMessage(), + 'TemplateLocator exception should propagate the FileLocator exception message' + ); + } + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testThrowsAnExceptionWhenTemplateIsNotATemplateReferenceInterface() + { + $locator = new TemplateLocator($this->getFileLocator()); + $locator->locate('template'); + } + + protected function getFileLocator() + { + return $this + ->getMockBuilder('Symfony\Component\Config\FileLocator') + ->setMethods(array('locate')) + ->setConstructorArgs(array('/path/to/fallback')) + ->getMock() + ; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/PhpEngineTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/PhpEngineTest.php new file mode 100644 index 0000000..476b398 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/PhpEngineTest.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\Bundle\FrameworkBundle\Tests\Templating; + +use Symfony\Bundle\FrameworkBundle\Templating\PhpEngine; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Session\Session; +use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; +use Symfony\Component\Templating\TemplateNameParser; +use Symfony\Bundle\FrameworkBundle\Templating\GlobalVariables; +use Symfony\Bundle\FrameworkBundle\Tests\TestCase; + +class PhpEngineTest extends TestCase +{ + public function testEvaluateAddsAppGlobal() + { + $container = $this->getContainer(); + $loader = $this->getMockForAbstractClass('Symfony\Component\Templating\Loader\Loader'); + $engine = new PhpEngine(new TemplateNameParser(), $container, $loader, $app = new GlobalVariables($container)); + $globals = $engine->getGlobals(); + $this->assertSame($app, $globals['app']); + } + + public function testEvaluateWithoutAvailableRequest() + { + $container = new Container(); + $loader = $this->getMockForAbstractClass('Symfony\Component\Templating\Loader\Loader'); + $engine = new PhpEngine(new TemplateNameParser(), $container, $loader, new GlobalVariables($container)); + + $container->set('request', null); + + $globals = $engine->getGlobals(); + $this->assertEmpty($globals['app']->getRequest()); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testGetInvalidHelper() + { + $container = $this->getContainer(); + $loader = $this->getMockForAbstractClass('Symfony\Component\Templating\Loader\Loader'); + $engine = new PhpEngine(new TemplateNameParser(), $container, $loader); + + $engine->get('non-existing-helper'); + } + + /** + * Creates a Container with a Session-containing Request service. + * + * @return Container + */ + protected function getContainer() + { + $container = new Container(); + $request = new Request(); + $session = new Session(new MockArraySessionStorage()); + + $request->setSession($session); + $container->set('request', $request); + + return $container; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateNameParserTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateNameParserTest.php new file mode 100644 index 0000000..4e86dc9 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateNameParserTest.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\Bundle\FrameworkBundle\Tests\Templating; + +use Symfony\Bundle\FrameworkBundle\Tests\TestCase; +use Symfony\Bundle\FrameworkBundle\Templating\TemplateNameParser; +use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference; + +class TemplateNameParserTest extends TestCase +{ + protected $parser; + + protected function setUp() + { + $kernel = $this->getMock('Symfony\Component\HttpKernel\KernelInterface'); + $kernel + ->expects($this->any()) + ->method('getBundle') + ->will($this->returnCallback(function ($bundle) { + if (in_array($bundle, array('SensioFooBundle', 'SensioCmsFooBundle', 'FooBundle'))) { + return true; + } + + throw new \InvalidArgumentException(); + })) + ; + $this->parser = new TemplateNameParser($kernel); + } + + protected function tearDown() + { + $this->parser = null; + } + + /** + * @dataProvider getLogicalNameToTemplateProvider + */ + public function testParse($name, $ref) + { + $template = $this->parser->parse($name); + + $this->assertEquals($template->getLogicalName(), $ref->getLogicalName()); + $this->assertEquals($template->getLogicalName(), $name); + } + + public function getLogicalNameToTemplateProvider() + { + return array( + array('FooBundle:Post:index.html.php', new TemplateReference('FooBundle', 'Post', 'index', 'html', 'php')), + array('FooBundle:Post:index.html.twig', new TemplateReference('FooBundle', 'Post', 'index', 'html', 'twig')), + array('FooBundle:Post:index.xml.php', new TemplateReference('FooBundle', 'Post', 'index', 'xml', 'php')), + array('SensioFooBundle:Post:index.html.php', new TemplateReference('SensioFooBundle', 'Post', 'index', 'html', 'php')), + array('SensioCmsFooBundle:Post:index.html.php', new TemplateReference('SensioCmsFooBundle', 'Post', 'index', 'html', 'php')), + array(':Post:index.html.php', new TemplateReference('', 'Post', 'index', 'html', 'php')), + array('::index.html.php', new TemplateReference('', '', 'index', 'html', 'php')), + array('FooBundle:Post:foo.bar.index.html.php', new TemplateReference('FooBundle', 'Post', 'foo.bar.index', 'html', 'php')), + ); + } + + /** + * @dataProvider getInvalidLogicalNameProvider + * @expectedException \InvalidArgumentException + */ + public function testParseInvalidName($name) + { + $this->parser->parse($name); + } + + public function getInvalidLogicalNameProvider() + { + return array( + array('BarBundle:Post:index.html.php'), + array('FooBundle:Post:index'), + array('FooBundle:Post'), + array('FooBundle:Post:foo:bar'), + ); + } + + /** + * @dataProvider getFilenameToTemplateProvider + */ + public function testParseFromFilename($file, $ref) + { + $template = $this->parser->parseFromFilename($file); + + if ($ref === false) { + $this->assertFalse($template); + } else { + $this->assertEquals($template->getLogicalName(), $ref->getLogicalName()); + } + } + + public function getFilenameToTemplateProvider() + { + return array( + array('/path/to/section/name.format.engine', new TemplateReference('', '/path/to/section', 'name', 'format', 'engine')), + array('\\path\\to\\section\\name.format.engine', new TemplateReference('', '/path/to/section', 'name', 'format', 'engine')), + array('name.format.engine', new TemplateReference('', '', 'name', 'format', 'engine')), + array('name.format', false), + array('name', false), + ); + } + +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateReferenceTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateReferenceTest.php new file mode 100644 index 0000000..5ee2a8e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateReferenceTest.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\Bundle\FrameworkBundle\Tests\Templating; + +use Symfony\Bundle\FrameworkBundle\Tests\TestCase; +use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference; + +class TemplateReferenceTest extends TestCase +{ + public function testGetPathWorksWithNamespacedControllers() + { + $reference = new TemplateReference('AcmeBlogBundle', 'Admin\Post', 'index', 'html', 'twig'); + + $this->assertSame( + '@AcmeBlogBundle/Resources/views/Admin/Post/index.html.twig', + $reference->getPath() + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateTest.php new file mode 100644 index 0000000..c49010b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateTest.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\Bundle\FrameworkBundle\Tests\Templating; + +use Symfony\Bundle\FrameworkBundle\Tests\TestCase; +use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference; + +class TemplateTest extends TestCase +{ + /** + * @dataProvider getTemplateToPathProvider + */ + public function testGetPathForTemplatesInABundle($template, $path) + { + if ($template->get('bundle')) { + $this->assertEquals($template->getPath(), $path); + } + } + + /** + * @dataProvider getTemplateToPathProvider + */ + public function testGetPathForTemplatesOutOfABundle($template, $path) + { + if (!$template->get('bundle')) { + $this->assertEquals($template->getPath(), $path); + } + } + + public function getTemplateToPathProvider() + { + return array( + array(new TemplateReference('FooBundle', 'Post', 'index', 'html', 'php'), '@FooBundle/Resources/views/Post/index.html.php'), + array(new TemplateReference('FooBundle', '', 'index', 'html', 'twig'), '@FooBundle/Resources/views/index.html.twig'), + array(new TemplateReference('', 'Post', 'index', 'html', 'php'), 'views/Post/index.html.php'), + array(new TemplateReference('', '', 'index', 'html', 'php'), 'views/index.html.php'), + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/TestCase.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/TestCase.php new file mode 100644 index 0000000..8e72430 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/TestCase.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\Bundle\FrameworkBundle\Tests; + +class TestCase extends \PHPUnit_Framework_TestCase +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/PhpExtractorTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/PhpExtractorTest.php new file mode 100644 index 0000000..4305f0e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/PhpExtractorTest.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\Bundle\FrameworkBundle\Tests\Translation; + +use Symfony\Bundle\FrameworkBundle\Tests\TestCase; +use Symfony\Bundle\FrameworkBundle\Translation\PhpExtractor; +use Symfony\Component\Translation\MessageCatalogue; + +class PhpExtractorTest extends TestCase +{ + public function testExtraction() + { + // Arrange + $extractor = new PhpExtractor(); + $extractor->setPrefix('prefix'); + $catalogue = new MessageCatalogue('en'); + + // Act + $extractor->extract(__DIR__.'/../Fixtures/Resources/views/', $catalogue); + + // Assert + $this->assertCount(1, $catalogue->all('messages'), '->extract() should find 1 translation'); + $this->assertTrue($catalogue->has('new key'), '->extract() should find at leat "new key" message'); + $this->assertEquals('prefixnew key', $catalogue->get('new key'), '->extract() should apply "prefix" as prefix'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php new file mode 100644 index 0000000..ad2462a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.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\Bundle\FrameworkBundle\Tests\Translation; + +use Symfony\Bundle\FrameworkBundle\Translation\Translator; +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\Translation\MessageSelector; + +class TranslatorTest extends \PHPUnit_Framework_TestCase +{ + protected $tmpDir; + + protected function setUp() + { + $this->tmpDir = sys_get_temp_dir().'/sf2_translation'; + $this->deleteTmpDir(); + } + + public function tearDown() + { + $this->deleteTmpDir(); + } + + protected function deleteTmpDir() + { + if (!file_exists($dir = $this->tmpDir)) { + return; + } + + $fs = new Filesystem(); + $fs->remove($dir); + } + + public function testTransWithoutCaching() + { + $translator = $this->getTranslator($this->getLoader()); + $translator->setLocale('fr'); + $translator->setFallbackLocale(array('en', 'es')); + + $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')); + } + + public function testTransWithCaching() + { + // prime the cache + $translator = $this->getTranslator($this->getLoader(), array('cache_dir' => $this->tmpDir)); + $translator->setLocale('fr'); + $translator->setFallbackLocale(array('en', 'es')); + + $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')); + + // do it another time as the cache is primed now + $loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface'); + $translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir)); + $translator->setLocale('fr'); + $translator->setFallbackLocale(array('en', 'es')); + + $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')); + } + + 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)', + )))) + ; + + return $loader; + } + + protected function getContainer($loader) + { + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $container + ->expects($this->any()) + ->method('get') + ->will($this->returnValue($loader)) + ; + + return $container; + } + + public function getTranslator($loader, $options = array()) + { + $translator = new Translator( + $this->getContainer($loader), + new MessageSelector(), + array('loader' => array('loader')), + $options + ); + + $translator->addResource('loader', 'foo', 'fr'); + $translator->addResource('loader', 'foo', 'en'); + $translator->addResource('loader', 'foo', 'es'); + + return $translator; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Validator/ConstraintValidatorFactoryTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Validator/ConstraintValidatorFactoryTest.php new file mode 100644 index 0000000..7dc3389 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Tests/Validator/ConstraintValidatorFactoryTest.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\Bundle\FrameworkBundle\Tests\Validator; + +use Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\Validator\Constraints\Blank as BlankConstraint; + +class ConstraintValidatorFactoryTest extends \PHPUnit_Framework_TestCase +{ + public function testGetInstanceCreatesValidator() + { + $class = get_class($this->getMockForAbstractClass('Symfony\\Component\\Validator\\ConstraintValidator')); + + $constraint = $this->getMock('Symfony\\Component\\Validator\\Constraint'); + $constraint + ->expects($this->once()) + ->method('validatedBy') + ->will($this->returnValue($class)); + + $factory = new ConstraintValidatorFactory(new Container()); + $this->assertInstanceOf($class, $factory->getInstance($constraint)); + } + + public function testGetInstanceReturnsExistingValidator() + { + $factory = new ConstraintValidatorFactory(new Container()); + $v1 = $factory->getInstance(new BlankConstraint()); + $v2 = $factory->getInstance(new BlankConstraint()); + $this->assertSame($v1, $v2); + } + + public function testGetInstanceReturnsService() + { + $service = 'validator_constraint_service'; + $alias = 'validator_constraint_alias'; + $validator = new \stdClass(); + + // mock ContainerBuilder b/c it implements TaggedContainerInterface + $container = $this->getMock('Symfony\\Component\\DependencyInjection\\ContainerBuilder'); + $container + ->expects($this->once()) + ->method('get') + ->with($service) + ->will($this->returnValue($validator)); + + $constraint = $this->getMock('Symfony\\Component\\Validator\\Constraint'); + $constraint + ->expects($this->once()) + ->method('validatedBy') + ->will($this->returnValue($alias)); + + $factory = new ConstraintValidatorFactory($container, array('validator_constraint_alias' => 'validator_constraint_service')); + $this->assertSame($validator, $factory->getInstance($constraint)); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php new file mode 100644 index 0000000..1eb3605 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.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\Bundle\FrameworkBundle\Translation; + +use Symfony\Component\Finder\Finder; +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Extractor\ExtractorInterface; + +/** + * PhpExtractor extracts translation messages from a php template. + * + * @author Michel Salib + */ +class PhpExtractor implements ExtractorInterface +{ + const MESSAGE_TOKEN = 300; + const IGNORE_TOKEN = 400; + + /** + * Prefix for new found message. + * + * @var string + */ + private $prefix = ''; + + /** + * The sequence that captures translation messages. + * + * @var array + */ + protected $sequences = array( + array( + '$view', + '[', + '\'translator\'', + ']', + '->', + 'trans', + '(', + self::MESSAGE_TOKEN, + ')', + ), + ); + + /** + * {@inheritDoc} + */ + public function extract($directory, MessageCatalogue $catalog) + { + // load any existing translation files + $finder = new Finder(); + $files = $finder->files()->name('*.php')->in($directory); + foreach ($files as $file) { + $this->parseTokens(token_get_all(file_get_contents($file)), $catalog); + } + } + + /** + * {@inheritDoc} + */ + public function setPrefix($prefix) + { + $this->prefix = $prefix; + } + + /** + * Normalizes a token. + * + * @param mixed $token + * @return string + */ + protected function normalizeToken($token) + { + if (is_array($token)) { + return $token[1]; + } + + return $token; + } + + /** + * Extracts trans message from php tokens. + * + * @param array $tokens + * @param MessageCatalogue $catalog + */ + protected function parseTokens($tokens, MessageCatalogue $catalog) + { + foreach ($tokens as $key => $token) { + foreach ($this->sequences as $sequence) { + $message = ''; + + foreach ($sequence as $id => $item) { + if ($this->normalizeToken($tokens[$key + $id]) == $item) { + continue; + } elseif (self::MESSAGE_TOKEN == $item) { + $message = $this->normalizeToken($tokens[$key + $id]); + } elseif (self::IGNORE_TOKEN == $item) { + continue; + } else { + break; + } + } + + $message = trim($message, '\''); + + if ($message) { + $catalog->set($message, $this->prefix.$message); + break; + } + } + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Translation/TranslationLoader.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Translation/TranslationLoader.php new file mode 100644 index 0000000..aea1ec4 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Translation/TranslationLoader.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\Bundle\FrameworkBundle\Translation; + +use Symfony\Component\Finder\Finder; +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Loader\LoaderInterface; + +/** + * TranslationLoader loads translation messages from translation files. + * + * @author Michel Salib + */ +class TranslationLoader +{ + /** + * Loaders used for import. + * + * @var array + */ + private $loaders = array(); + + /** + * Adds a loader to the translation extractor. + * @param string $format The format of the loader + * @param LoaderInterface $loader + */ + public function addLoader($format, LoaderInterface $loader) + { + $this->loaders[$format] = $loader; + } + + /** + * Loads translation messages from a directory to the catalogue. + * + * @param string $directory the directory to look into + * @param MessageCatalogue $catalogue the catalogue + */ + public function loadMessages($directory, MessageCatalogue $catalogue) + { + foreach ($this->loaders as $format => $loader) { + // load any existing translation files + $finder = new Finder(); + $extension = $catalogue->getLocale().'.'.$format; + $files = $finder->files()->name('*.'.$extension)->in($directory); + foreach ($files as $file) { + $domain = substr($file->getFileName(), 0, -1 * strlen($extension) - 1); + $catalogue->addCatalogue($loader->load($file->getPathname(), $catalogue->getLocale(), $domain)); + } + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php new file mode 100644 index 0000000..4477121 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.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\Bundle\FrameworkBundle\Translation; + +use Symfony\Component\Translation\Translator as BaseTranslator; +use Symfony\Component\Translation\MessageSelector; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\Config\ConfigCache; + +/** + * Translator. + * + * @author Fabien Potencier + */ +class Translator extends BaseTranslator +{ + protected $container; + protected $options; + protected $loaderIds; + + /** + * Constructor. + * + * Available options: + * + * * cache_dir: The cache directory (or null to disable caching) + * * debug: Whether to enable debugging or not (false by default) + * + * @param ContainerInterface $container A ContainerInterface instance + * @param MessageSelector $selector The message selector for pluralization + * @param array $loaderIds An array of loader Ids + * @param array $options An array of options + */ + public function __construct(ContainerInterface $container, MessageSelector $selector, $loaderIds = array(), array $options = array()) + { + $this->container = $container; + $this->loaderIds = $loaderIds; + + $this->options = array( + 'cache_dir' => null, + 'debug' => false, + ); + + // check option names + if ($diff = array_diff(array_keys($options), array_keys($this->options))) { + throw new \InvalidArgumentException(sprintf('The Translator does not support the following options: \'%s\'.', implode('\', \'', $diff))); + } + + $this->options = array_merge($this->options, $options); + + parent::__construct(null, $selector); + } + + /** + * {@inheritdoc} + */ + public function getLocale() + { + if (null === $this->locale && $this->container->has('request')) { + $this->locale = $this->container->get('request')->getLocale(); + } + + return $this->locale; + } + + /** + * {@inheritdoc} + */ + protected function loadCatalogue($locale) + { + if (isset($this->catalogues[$locale])) { + return; + } + + if (null === $this->options['cache_dir']) { + $this->initialize(); + + return parent::loadCatalogue($locale); + } + + $cache = new ConfigCache($this->options['cache_dir'].'/catalogue.'.$locale.'.php', $this->options['debug']); + if (!$cache->isFresh()) { + $this->initialize(); + + parent::loadCatalogue($locale); + + $fallbackContent = ''; + $current = ''; + foreach ($this->computeFallbackLocales($locale) as $fallback) { + $fallbackContent .= sprintf(<<addFallbackCatalogue(\$catalogue%s); + + +EOF + , + ucfirst($fallback), + $fallback, + var_export($this->catalogues[$fallback]->all(), true), + ucfirst($current), + ucfirst($fallback) + ); + $current = $fallback; + } + + $content = sprintf(<<catalogues[$locale]->all(), true), + $fallbackContent + ); + + $cache->write($content, $this->catalogues[$locale]->getResources()); + + return; + } + + $this->catalogues[$locale] = include $cache; + } + + protected function initialize() + { + foreach ($this->loaderIds as $id => $aliases) { + foreach ($aliases as $alias) { + $this->addLoader($alias, $this->container->get($id)); + } + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Validator/ConstraintValidatorFactory.php b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Validator/ConstraintValidatorFactory.php new file mode 100644 index 0000000..b42aca1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Validator/ConstraintValidatorFactory.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\Bundle\FrameworkBundle\Validator; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidatorFactoryInterface; + +/** + * Uses a service container to create constraint validators. + * + * A constraint validator should be tagged as "validator.constraint_validator" + * in the service container and include an "alias" attribute: + * + * + * + * + * + * + * A constraint may then return this alias in its validatedBy() method: + * + * public function validatedBy() + * { + * return 'some_alias'; + * } + * + * @author Kris Wallsmith + */ +class ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface +{ + protected $container; + protected $validators; + + /** + * Constructor. + * + * @param ContainerInterface $container The service container + * @param array $validators An array of validators + */ + public function __construct(ContainerInterface $container, array $validators = array()) + { + $this->container = $container; + $this->validators = $validators; + } + + /** + * Returns the validator for the supplied constraint. + * + * @param Constraint $constraint A constraint + * + * @return Symfony\Component\Validator\ConstraintValidator A validator for the supplied constraint + */ + public function getInstance(Constraint $constraint) + { + $name = $constraint->validatedBy(); + + if (!isset($this->validators[$name])) { + $this->validators[$name] = new $name(); + } elseif (is_string($this->validators[$name])) { + $this->validators[$name] = $this->container->get($this->validators[$name]); + } + + return $this->validators[$name]; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/composer.json b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/composer.json new file mode 100644 index 0000000..55c4366 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -0,0 +1,45 @@ +{ + "name": "symfony/framework-bundle", + "type": "symfony-bundle", + "description": "Symfony FrameworkBundle", + "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/dependency-injection" : "self.version", + "symfony/config" : "self.version", + "symfony/event-dispatcher": "self.version", + "symfony/http-kernel": "self.version", + "symfony/filesystem": "self.version", + "symfony/routing": "self.version", + "symfony/templating": "self.version", + "symfony/translation": "self.version", + "doctrine/common": ">=2.2,<2.4-dev" + }, + "suggest": { + "symfony/console": "self.version", + "symfony/finder": "self.version", + "symfony/form": "self.version", + "symfony/validator": "self.version" + }, + "autoload": { + "psr-0": { "Symfony\\Bundle\\FrameworkBundle": "" } + }, + "target-dir": "Symfony/Bundle/FrameworkBundle", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md new file mode 100644 index 0000000..39926ae --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md @@ -0,0 +1,77 @@ +CHANGELOG +========= + +2.1.0 +----- + + * [BC BREAK] The custom factories for the firewall configuration are now + registered during the build method of bundles instead of being registered + by the end-user (you need to remove the 'factories' keys in your security + configuration). + + * [BC BREAK] The Firewall listener is now registered after the Router one. This + means that specific Firewall URLs (like /login_check and /logout must now + have proper route defined in your routing configuration) + + * [BC BREAK] refactored the user provider configuration. The configuration + changed for the chain provider and the memory provider: + + Before: + + ``` yaml + security: + providers: + my_chain_provider: + providers: [my_memory_provider, my_doctrine_provider] + my_memory_provider: + users: + toto: { password: foobar, roles: [ROLE_USER] } + foo: { password: bar, roles: [ROLE_USER, ROLE_ADMIN] } + ``` + + After: + + ``` yaml + security: + providers: + my_chain_provider: + chain: + providers: [my_memory_provider, my_doctrine_provider] + my_memory_provider: + memory: + users: + toto: { password: foobar, roles: [ROLE_USER] } + foo: { password: bar, roles: [ROLE_USER, ROLE_ADMIN] } + ``` + + * [BC BREAK] Method `equals` was removed from `UserInterface` to its own new + `EquatableInterface`. The user class can now implement this interface to override + the default implementation of users equality test. + + * added a validator for the user password + * added 'erase_credentials' as a configuration key (true by default) + * added new events: `security.authentication.success` and `security.authentication.failure` + fired on authentication success/failure, regardless of authentication method, + events are defined in new event class: `Symfony\Component\Security\Core\AuthenticationEvents`. + + * Added optional CSRF protection to LogoutListener: + + ``` yaml + security: + firewalls: + default: + logout: + path: /logout_path + target: / + csrf_parameter: _csrf_token # Optional (defaults to "_csrf_token") + csrf_provider: form.csrf_provider # Required to enable protection + intention: logout # Optional (defaults to "logout") + ``` + + If the LogoutListener has CSRF protection enabled but cannot validate a token, + then a LogoutException will be thrown. + + * Added `logout_url` templating helper and Twig extension, which may be used to + generate logout URL's within templates. The security firewall's config key + must be specified. If a firewall's logout listener has CSRF protection + enabled, a token will be automatically added to the generated URL. diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Command/InitAclCommand.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Command/InitAclCommand.php new file mode 100644 index 0000000..eaa518f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Command/InitAclCommand.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\Bundle\SecurityBundle\Command; + +use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; +use Symfony\Component\Security\Acl\Dbal\Schema; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Doctrine\DBAL\Schema\SchemaException; + +/** + * Installs the tables required by the ACL system + * + * @author Johannes M. Schmitt + */ +class InitAclCommand extends ContainerAwareCommand +{ + /** + * @see Command + */ + protected function configure() + { + $this + ->setName('init:acl') + ->setDescription('Mounts ACL tables in the database') + ->setHelp(<<%command.name% command mounts ACL tables in the database. + +php %command.full_name% + +The name of the DBAL connection must be configured in your app/config/security.yml configuration file in the security.acl.connection variable. + +security: + acl: + connection: default +EOF + ) + ; + } + + /** + * @see Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $container = $this->getContainer(); + + $connection = $container->get('security.acl.dbal.connection'); + $schema = $container->get('security.acl.dbal.schema'); + + try { + $schema->addToSchema($connection->getSchemaManager()->createSchema()); + } catch (SchemaException $e) { + $output->writeln("Aborting: " . $e->getMessage()); + + return; + } + + foreach ($schema->toSql($connection->getDatabasePlatform()) as $sql) { + $connection->exec($sql); + } + + $output->writeln('ACL tables have been initialized successfully.'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php new file mode 100644 index 0000000..609f8db --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.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\Bundle\SecurityBundle\DataCollector; + +use Symfony\Component\Security\Core\SecurityContextInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\DataCollector\DataCollector; + +/** + * SecurityDataCollector. + * + * @author Fabien Potencier + */ +class SecurityDataCollector extends DataCollector +{ + private $context; + + public function __construct(SecurityContextInterface $context = null) + { + $this->context = $context; + } + + /** + * {@inheritdoc} + */ + public function collect(Request $request, Response $response, \Exception $exception = null) + { + if (null === $this->context) { + $this->data = array( + 'enabled' => false, + 'authenticated' => false, + 'user' => '', + 'roles' => array(), + ); + } elseif (null === $token = $this->context->getToken()) { + $this->data = array( + 'enabled' => true, + 'authenticated' => false, + 'user' => '', + 'roles' => array(), + ); + } else { + $this->data = array( + 'enabled' => true, + 'authenticated' => $token->isAuthenticated(), + 'user' => $token->getUsername(), + 'roles' => array_map(function ($role){ return $role->getRole();}, $token->getRoles()), + ); + } + } + + /** + * Checks if security is enabled. + * + * @return Boolean true if security is enabled, false otherwise + */ + public function isEnabled() + { + return $this->data['enabled']; + } + + /** + * Gets the user. + * + * @return string The user + */ + public function getUser() + { + return $this->data['user']; + } + + /** + * Gets the roles of the user. + * + * @return array The roles + */ + public function getRoles() + { + return $this->data['roles']; + } + + /** + * Checks if the user is authenticated or not. + * + * @return Boolean true if the user is authenticated, false otherwise + */ + public function isAuthenticated() + { + return $this->data['authenticated']; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'security'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddSecurityVotersPass.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddSecurityVotersPass.php new file mode 100644 index 0000000..cfc6173 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddSecurityVotersPass.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\Bundle\SecurityBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Adds all configured security voters to the access decision manager + * + * @author Johannes M. Schmitt + */ +class AddSecurityVotersPass implements CompilerPassInterface +{ + /** + * {@inheritDoc} + */ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('security.access.decision_manager')) { + return; + } + + $voters = new \SplPriorityQueue(); + foreach ($container->findTaggedServiceIds('security.voter') as $id => $attributes) { + $priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0; + $voters->insert(new Reference($id), $priority); + } + + $voters = iterator_to_array($voters); + ksort($voters); + + $container->getDefinition('security.access.decision_manager')->replaceArgument(0, array_values($voters)); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php new file mode 100644 index 0000000..c0e8736 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.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\Bundle\SecurityBundle\DependencyInjection; + +use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AbstractFactory; + +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\ConfigurationInterface; + +/** + * This class contains the configuration information for the following tags: + * + * * security.config + * * security.acl + * + * This information is solely responsible for how the different configuration + * sections are normalized, and merged. + * + * @author Johannes M. Schmitt + */ +class MainConfiguration implements ConfigurationInterface +{ + private $factories; + private $userProviderFactories; + + /** + * Constructor. + * + * @param array $factories + * @param array $userProviderFactories + */ + public function __construct(array $factories, array $userProviderFactories) + { + $this->factories = $factories; + $this->userProviderFactories = $userProviderFactories; + } + + /** + * Generates the configuration tree builder. + * + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder + */ + public function getConfigTreeBuilder() + { + $tb = new TreeBuilder(); + $rootNode = $tb->root('security'); + + $rootNode + ->children() + ->scalarNode('access_denied_url')->defaultNull()->example('/foo/error403')->end() + ->scalarNode('session_fixation_strategy')->cannotBeEmpty()->info('strategy can be: none, migrate, invalidate')->defaultValue('migrate')->end() + ->booleanNode('hide_user_not_found')->defaultTrue()->end() + ->booleanNode('always_authenticate_before_granting')->defaultFalse()->end() + ->booleanNode('erase_credentials')->defaultTrue()->end() + ->arrayNode('access_decision_manager') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('strategy')->defaultValue('affirmative')->end() + ->booleanNode('allow_if_all_abstain')->defaultFalse()->end() + ->booleanNode('allow_if_equal_granted_denied')->defaultTrue()->end() + ->end() + ->end() + ->end() + ; + + $this->addAclSection($rootNode); + $this->addEncodersSection($rootNode); + $this->addProvidersSection($rootNode); + $this->addFirewallsSection($rootNode, $this->factories); + $this->addAccessControlSection($rootNode); + $this->addRoleHierarchySection($rootNode); + + return $tb; + } + + private function addAclSection(ArrayNodeDefinition $rootNode) + { + $rootNode + ->children() + ->arrayNode('acl') + ->children() + ->scalarNode('connection') + ->defaultNull() + ->info('any name configured in doctrine.dbal section') + ->end() + ->arrayNode('cache') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('id')->end() + ->scalarNode('prefix')->defaultValue('sf2_acl_')->end() + ->end() + ->end() + ->scalarNode('provider')->end() + ->arrayNode('tables') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('class')->defaultValue('acl_classes')->end() + ->scalarNode('entry')->defaultValue('acl_entries')->end() + ->scalarNode('object_identity')->defaultValue('acl_object_identities')->end() + ->scalarNode('object_identity_ancestors')->defaultValue('acl_object_identity_ancestors')->end() + ->scalarNode('security_identity')->defaultValue('acl_security_identities')->end() + ->end() + ->end() + ->arrayNode('voter') + ->addDefaultsIfNotSet() + ->children() + ->booleanNode('allow_if_object_identity_unavailable')->defaultTrue()->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ; + } + + private function addRoleHierarchySection(ArrayNodeDefinition $rootNode) + { + $rootNode + ->fixXmlConfig('role', 'role_hierarchy') + ->children() + ->arrayNode('role_hierarchy') + ->useAttributeAsKey('id') + ->prototype('array') + ->performNoDeepMerging() + ->beforeNormalization()->ifString()->then(function($v) { return array('value' => $v); })->end() + ->beforeNormalization() + ->ifTrue(function($v) { return is_array($v) && isset($v['value']); }) + ->then(function($v) { return preg_split('/\s*,\s*/', $v['value']); }) + ->end() + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + ; + } + + private function addAccessControlSection(ArrayNodeDefinition $rootNode) + { + $rootNode + ->fixXmlConfig('rule', 'access_control') + ->children() + ->arrayNode('access_control') + ->cannotBeOverwritten() + ->prototype('array') + ->children() + ->scalarNode('requires_channel')->defaultNull()->end() + ->scalarNode('path') + ->defaultNull() + ->info('use the urldecoded format') + ->example('^/path to resource/') + ->end() + ->scalarNode('host')->defaultNull()->end() + ->scalarNode('ip')->defaultNull()->end() + ->arrayNode('methods') + ->beforeNormalization()->ifString()->then(function($v) { return preg_split('/\s*,\s*/', $v); })->end() + ->prototype('scalar')->end() + ->end() + ->end() + ->fixXmlConfig('role') + ->children() + ->arrayNode('roles') + ->beforeNormalization()->ifString()->then(function($v) { return preg_split('/\s*,\s*/', $v); })->end() + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ; + } + + private function addFirewallsSection(ArrayNodeDefinition $rootNode, array $factories) + { + $firewallNodeBuilder = $rootNode + ->fixXmlConfig('firewall') + ->children() + ->arrayNode('firewalls') + ->isRequired() + ->requiresAtLeastOneElement() + ->disallowNewKeysInSubsequentConfigs() + ->useAttributeAsKey('name') + ->prototype('array') + ->children() + ; + + $firewallNodeBuilder + ->scalarNode('pattern')->end() + ->booleanNode('security')->defaultTrue()->end() + ->scalarNode('request_matcher')->end() + ->scalarNode('access_denied_url')->end() + ->scalarNode('access_denied_handler')->end() + ->scalarNode('entry_point')->end() + ->scalarNode('provider')->end() + ->booleanNode('stateless')->defaultFalse()->end() + ->scalarNode('context')->cannotBeEmpty()->end() + ->arrayNode('logout') + ->treatTrueLike(array()) + ->canBeUnset() + ->children() + ->scalarNode('csrf_parameter')->defaultValue('_csrf_token')->end() + ->scalarNode('csrf_provider')->cannotBeEmpty()->end() + ->scalarNode('intention')->defaultValue('logout')->end() + ->scalarNode('path')->defaultValue('/logout')->end() + ->scalarNode('target')->defaultValue('/')->end() + ->scalarNode('success_handler')->end() + ->booleanNode('invalidate_session')->defaultTrue()->end() + ->end() + ->fixXmlConfig('delete_cookie') + ->children() + ->arrayNode('delete_cookies') + ->beforeNormalization() + ->ifTrue(function($v) { return is_array($v) && is_int(key($v)); }) + ->then(function($v) { return array_map(function($v) { return array('name' => $v); }, $v); }) + ->end() + ->useAttributeAsKey('name') + ->prototype('array') + ->children() + ->scalarNode('path')->defaultNull()->end() + ->scalarNode('domain')->defaultNull()->end() + ->end() + ->end() + ->end() + ->end() + ->fixXmlConfig('handler') + ->children() + ->arrayNode('handlers') + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + ->arrayNode('anonymous') + ->canBeUnset() + ->children() + ->scalarNode('key')->defaultValue(uniqid())->end() + ->end() + ->end() + ->arrayNode('switch_user') + ->canBeUnset() + ->children() + ->scalarNode('provider')->end() + ->scalarNode('parameter')->defaultValue('_switch_user')->end() + ->scalarNode('role')->defaultValue('ROLE_ALLOWED_TO_SWITCH')->end() + ->end() + ->end() + ; + + $abstractFactoryKeys = array(); + foreach ($factories as $factoriesAtPosition) { + foreach ($factoriesAtPosition as $factory) { + $name = str_replace('-', '_', $factory->getKey()); + $factoryNode = $firewallNodeBuilder->arrayNode($name) + ->canBeUnset() + ; + + if ($factory instanceof AbstractFactory) { + $abstractFactoryKeys[] = $name; + } + + $factory->addConfiguration($factoryNode); + } + } + + // check for unreachable check paths + $firewallNodeBuilder + ->end() + ->validate() + ->ifTrue(function($v) { + return true === $v['security'] && isset($v['pattern']) && !isset($v['request_matcher']); + }) + ->then(function($firewall) use($abstractFactoryKeys) { + foreach ($abstractFactoryKeys as $k) { + if (!isset($firewall[$k]['check_path'])) { + continue; + } + + if (false !== strpos('/', $firewall[$k]['check_path']) && !preg_match('#'.$firewall['pattern'].'#', $firewall[$k]['check_path'])) { + throw new \LogicException(sprintf('The check_path "%s" for login method "%s" is not matched by the firewall pattern "%s".', $firewall[$k]['check_path'], $k, $firewall['pattern'])); + } + } + + return $firewall; + }) + ->end() + ; + } + + private function addProvidersSection(ArrayNodeDefinition $rootNode) + { + $providerNodeBuilder = $rootNode + ->fixXmlConfig('provider') + ->children() + ->arrayNode('providers') + ->example(array( + 'memory' => array( + 'name' => 'memory', + 'users' => array( + 'foo' => array('password' => 'foo', 'roles' => 'ROLE_USER'), + 'bar' => array('password' => 'bar', 'roles' => '[ROLE_USER, ROLE_ADMIN]') + ) + ), + 'entity' => array('entity' => array('class' => 'SecurityBundle:User', 'property' => 'username')) + )) + ->disallowNewKeysInSubsequentConfigs() + ->isRequired() + ->requiresAtLeastOneElement() + ->useAttributeAsKey('name') + ->prototype('array') + ; + + $providerNodeBuilder + ->children() + ->scalarNode('id')->end() + ->arrayNode('chain') + ->fixXmlConfig('provider') + ->children() + ->arrayNode('providers') + ->beforeNormalization() + ->ifString() + ->then(function($v) { return preg_split('/\s*,\s*/', $v); }) + ->end() + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + ->end() + ; + + foreach ($this->userProviderFactories as $factory) { + $name = str_replace('-', '_', $factory->getKey()); + $factoryNode = $providerNodeBuilder->children()->arrayNode($name)->canBeUnset(); + + $factory->addConfiguration($factoryNode); + } + + $providerNodeBuilder + ->validate() + ->ifTrue(function($v){return count($v) > 1;}) + ->thenInvalid('You cannot set multiple provider types for the same provider') + ->end() + ->validate() + ->ifTrue(function($v){return count($v) === 0;}) + ->thenInvalid('You must set a provider definition for the provider.') + ->end() + ; + } + + private function addEncodersSection(ArrayNodeDefinition $rootNode) + { + $rootNode + ->fixXmlConfig('encoder') + ->children() + ->arrayNode('encoders') + ->example(array( + 'Acme\DemoBundle\Entity\User1' => 'sha512', + 'Acme\DemoBundle\Entity\User2' => array( + 'algorithm' => 'sha512', + 'encode_as_base64' => 'true', + 'iterations'=> 5000 + ) + )) + ->requiresAtLeastOneElement() + ->useAttributeAsKey('class') + ->prototype('array') + ->canBeUnset() + ->performNoDeepMerging() + ->beforeNormalization()->ifString()->then(function($v) { return array('algorithm' => $v); })->end() + ->children() + ->scalarNode('algorithm')->cannotBeEmpty()->end() + ->booleanNode('ignore_case')->defaultFalse()->end() + ->booleanNode('encode_as_base64')->defaultTrue()->end() + ->scalarNode('iterations')->defaultValue(5000)->end() + ->scalarNode('id')->end() + ->end() + ->end() + ->end() + ->end() + ; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.php new file mode 100644 index 0000000..611b028 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.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\Bundle\SecurityBundle\DependencyInjection\Security\Factory; + +use Symfony\Component\Config\Definition\Builder\NodeDefinition; + +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * AbstractFactory is the base class for all classes inheriting from + * AbstractAuthenticationListener + * + * @author Lukas Kahwe Smith + * @author Johannes M. Schmitt + */ +abstract class AbstractFactory implements SecurityFactoryInterface +{ + protected $options = array( + 'check_path' => '/login_check', + 'login_path' => '/login', + 'use_forward' => false, + 'always_use_default_target_path' => false, + 'default_target_path' => '/', + 'target_path_parameter' => '_target_path', + 'use_referer' => false, + 'failure_path' => null, + 'failure_forward' => false, + ); + + public function create(ContainerBuilder $container, $id, $config, $userProviderId, $defaultEntryPointId) + { + // authentication provider + $authProviderId = $this->createAuthProvider($container, $id, $config, $userProviderId); + + // authentication listener + $listenerId = $this->createListener($container, $id, $config, $userProviderId); + + // add remember-me aware tag if requested + if ($this->isRememberMeAware($config)) { + $container + ->getDefinition($listenerId) + ->addTag('security.remember_me_aware', array('id' => $id, 'provider' => $userProviderId)) + ; + } + + // create entry point if applicable (optional) + $entryPointId = $this->createEntryPoint($container, $id, $config, $defaultEntryPointId); + + return array($authProviderId, $listenerId, $entryPointId); + } + + public function addConfiguration(NodeDefinition $node) + { + $builder = $node->children(); + + $builder + ->scalarNode('provider')->end() + ->booleanNode('remember_me')->defaultTrue()->end() + ->scalarNode('success_handler')->end() + ->scalarNode('failure_handler')->end() + ; + + foreach ($this->options as $name => $default) { + if (is_bool($default)) { + $builder->booleanNode($name)->defaultValue($default); + } else { + $builder->scalarNode($name)->defaultValue($default); + } + } + } + + public final function addOption($name, $default = null) + { + $this->options[$name] = $default; + } + + /** + * Subclasses must return the id of a service which implements the + * AuthenticationProviderInterface. + * + * @param ContainerBuilder $container + * @param string $id The unique id of the firewall + * @param array $config The options array for this listener + * @param string $userProviderId The id of the user provider + * + * @return string never null, the id of the authentication provider + */ + abstract protected function createAuthProvider(ContainerBuilder $container, $id, $config, $userProviderId); + + /** + * Subclasses must return the id of the abstract listener template. + * + * Listener definitions should inherit from the AbstractAuthenticationListener + * like this: + * + * + * + * In the above case, this method would return "my.listener.id". + * + * @return string + */ + abstract protected function getListenerId(); + + /** + * Subclasses may create an entry point of their as they see fit. The + * default implementation does not change the default entry point. + * + * @param ContainerBuilder $container + * @param string $id + * @param array $config + * @param string $defaultEntryPointId + * + * @return string the entry point id + */ + protected function createEntryPoint($container, $id, $config, $defaultEntryPointId) + { + return $defaultEntryPointId; + } + + /** + * Subclasses may disable remember-me features for the listener, by + * always returning false from this method. + * + * @param array $config + * + * @return Boolean Whether a possibly configured RememberMeServices should be set for this listener + */ + protected function isRememberMeAware($config) + { + return $config['remember_me']; + } + + protected function createListener($container, $id, $config, $userProvider) + { + $listenerId = $this->getListenerId(); + $listener = new DefinitionDecorator($listenerId); + $listener->replaceArgument(4, $id); + $listener->replaceArgument(5, array_intersect_key($config, $this->options)); + + // success handler + if (isset($config['success_handler'])) { + $listener->replaceArgument(6, new Reference($config['success_handler'])); + } + + // failure handler + if (isset($config['failure_handler'])) { + $listener->replaceArgument(7, new Reference($config['failure_handler'])); + } + + $listenerId .= '.'.$id; + $container->setDefinition($listenerId, $listener); + + return $listenerId; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.php new file mode 100644 index 0000000..ce06bba --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.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\Bundle\SecurityBundle\DependencyInjection\Security\Factory; + +use Symfony\Component\Config\Definition\Builder\NodeDefinition; +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * FormLoginFactory creates services for form login authentication. + * + * @author Fabien Potencier + * @author Johannes M. Schmitt + */ +class FormLoginFactory extends AbstractFactory +{ + public function __construct() + { + $this->addOption('username_parameter', '_username'); + $this->addOption('password_parameter', '_password'); + $this->addOption('csrf_parameter', '_csrf_token'); + $this->addOption('intention', 'authenticate'); + $this->addOption('post_only', true); + } + + public function getPosition() + { + return 'form'; + } + + public function getKey() + { + return 'form-login'; + } + + public function addConfiguration(NodeDefinition $node) + { + parent::addConfiguration($node); + + $node + ->children() + ->scalarNode('csrf_provider')->cannotBeEmpty()->end() + ->end() + ; + } + + protected function getListenerId() + { + return 'security.authentication.listener.form'; + } + + protected function createAuthProvider(ContainerBuilder $container, $id, $config, $userProviderId) + { + $provider = 'security.authentication.provider.dao.'.$id; + $container + ->setDefinition($provider, new DefinitionDecorator('security.authentication.provider.dao')) + ->replaceArgument(0, new Reference($userProviderId)) + ->replaceArgument(2, $id) + ; + + return $provider; + } + + protected function createListener($container, $id, $config, $userProvider) + { + $listenerId = parent::createListener($container, $id, $config, $userProvider); + + if (isset($config['csrf_provider'])) { + $container + ->getDefinition($listenerId) + ->addArgument(new Reference($config['csrf_provider'])) + ; + } + + return $listenerId; + } + + protected function createEntryPoint($container, $id, $config, $defaultEntryPoint) + { + $entryPointId = 'security.authentication.form_entry_point.'.$id; + $container + ->setDefinition($entryPointId, new DefinitionDecorator('security.authentication.form_entry_point')) + ->addArgument(new Reference('security.http_utils')) + ->addArgument($config['login_path']) + ->addArgument($config['use_forward']) + ; + + return $entryPointId; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpBasicFactory.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpBasicFactory.php new file mode 100644 index 0000000..c87f68c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpBasicFactory.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\Bundle\SecurityBundle\DependencyInjection\Security\Factory; + +use Symfony\Component\Config\Definition\Builder\NodeDefinition; + +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * HttpBasicFactory creates services for HTTP basic authentication. + * + * @author Fabien Potencier + */ +class HttpBasicFactory implements SecurityFactoryInterface +{ + public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint) + { + $provider = 'security.authentication.provider.dao.'.$id; + $container + ->setDefinition($provider, new DefinitionDecorator('security.authentication.provider.dao')) + ->replaceArgument(0, new Reference($userProvider)) + ->replaceArgument(2, $id) + ; + + // entry point + $entryPointId = $this->createEntryPoint($container, $id, $config, $defaultEntryPoint); + + // listener + $listenerId = 'security.authentication.listener.basic.'.$id; + $listener = $container->setDefinition($listenerId, new DefinitionDecorator('security.authentication.listener.basic')); + $listener->replaceArgument(2, $id); + $listener->replaceArgument(3, new Reference($entryPointId)); + + return array($provider, $listenerId, $entryPointId); + } + + public function getPosition() + { + return 'http'; + } + + public function getKey() + { + return 'http-basic'; + } + + public function addConfiguration(NodeDefinition $node) + { + $node + ->children() + ->scalarNode('provider')->end() + ->scalarNode('realm')->defaultValue('Secured Area')->end() + ->end() + ; + } + + protected function createEntryPoint($container, $id, $config, $defaultEntryPoint) + { + if (null !== $defaultEntryPoint) { + return $defaultEntryPoint; + } + + $entryPointId = 'security.authentication.basic_entry_point.'.$id; + $container + ->setDefinition($entryPointId, new DefinitionDecorator('security.authentication.basic_entry_point')) + ->addArgument($config['realm']) + ; + + return $entryPointId; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpDigestFactory.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpDigestFactory.php new file mode 100644 index 0000000..3a49b5d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpDigestFactory.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory; + +use Symfony\Component\Config\Definition\Builder\NodeDefinition; + +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * HttpDigestFactory creates services for HTTP digest authentication. + * + * @author Fabien Potencier + */ +class HttpDigestFactory implements SecurityFactoryInterface +{ + public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint) + { + $provider = 'security.authentication.provider.dao.'.$id; + $container + ->setDefinition($provider, new DefinitionDecorator('security.authentication.provider.dao')) + ->replaceArgument(0, new Reference($userProvider)) + ->replaceArgument(2, $id) + ; + + // entry point + $entryPointId = $this->createEntryPoint($container, $id, $config, $defaultEntryPoint); + + // listener + $listenerId = 'security.authentication.listener.digest.'.$id; + $listener = $container->setDefinition($listenerId, new DefinitionDecorator('security.authentication.listener.digest')); + $listener->replaceArgument(1, new Reference($userProvider)); + $listener->replaceArgument(2, $id); + $listener->replaceArgument(3, new Reference($entryPointId)); + + return array($provider, $listenerId, $entryPointId); + } + + public function getPosition() + { + return 'http'; + } + + public function getKey() + { + return 'http-digest'; + } + + public function addConfiguration(NodeDefinition $node) + { + $node + ->children() + ->scalarNode('provider')->end() + ->scalarNode('realm')->defaultValue('Secured Area')->end() + ->scalarNode('key')->isRequired()->cannotBeEmpty()->end() + ->end() + ; + } + + protected function createEntryPoint($container, $id, $config, $defaultEntryPoint) + { + if (null !== $defaultEntryPoint) { + return $defaultEntryPoint; + } + + $entryPointId = 'security.authentication.digest_entry_point.'.$id; + $container + ->setDefinition($entryPointId, new DefinitionDecorator('security.authentication.digest_entry_point')) + ->addArgument($config['realm']) + ->addArgument($config['key']) + ; + + return $entryPointId; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php new file mode 100644 index 0000000..08c4a33 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.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\Bundle\SecurityBundle\DependencyInjection\Security\Factory; + +use Symfony\Component\Config\Definition\Builder\NodeDefinition; +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +class RememberMeFactory implements SecurityFactoryInterface +{ + protected $options = array( + 'name' => 'REMEMBERME', + 'lifetime' => 31536000, + 'path' => '/', + 'domain' => null, + 'secure' => false, + 'httponly' => true, + 'always_remember_me' => false, + 'remember_me_parameter' => '_remember_me', + ); + + public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint) + { + // authentication provider + $authProviderId = 'security.authentication.provider.rememberme.'.$id; + $container + ->setDefinition($authProviderId, new DefinitionDecorator('security.authentication.provider.rememberme')) + ->addArgument($config['key']) + ->addArgument($id) + ; + + // remember me services + if (isset($config['token_provider'])) { + $templateId = 'security.authentication.rememberme.services.persistent'; + $rememberMeServicesId = $templateId.'.'.$id; + } else { + $templateId = 'security.authentication.rememberme.services.simplehash'; + $rememberMeServicesId = $templateId.'.'.$id; + } + + if ($container->hasDefinition('security.logout_listener.'.$id)) { + $container + ->getDefinition('security.logout_listener.'.$id) + ->addMethodCall('addHandler', array(new Reference($rememberMeServicesId))) + ; + } + + $rememberMeServices = $container->setDefinition($rememberMeServicesId, new DefinitionDecorator($templateId)); + $rememberMeServices->replaceArgument(1, $config['key']); + $rememberMeServices->replaceArgument(2, $id); + + if (isset($config['token_provider'])) { + $rememberMeServices->addMethodCall('setTokenProvider', array( + new Reference($config['token_provider']) + )); + } + + // remember-me options + $rememberMeServices->replaceArgument(3, array_intersect_key($config, $this->options)); + + // attach to remember-me aware listeners + $userProviders = array(); + foreach ($container->findTaggedServiceIds('security.remember_me_aware') as $serviceId => $attributes) { + foreach ($attributes as $attribute) { + if (!isset($attribute['id']) || $attribute['id'] !== $id) { + continue; + } + + if (!isset($attribute['provider'])) { + throw new \RuntimeException('Each "security.remember_me_aware" tag must have a provider attribute.'); + } + + $userProviders[] = new Reference($attribute['provider']); + $container + ->getDefinition($serviceId) + ->addMethodCall('setRememberMeServices', array(new Reference($rememberMeServicesId))) + ; + } + } + if ($config['user_providers']) { + $userProviders = array(); + foreach ($config['user_providers'] as $providerName) { + $userProviders[] = new Reference('security.user.provider.concrete.'.$providerName); + } + } + if (count($userProviders) === 0) { + throw new \RuntimeException('You must configure at least one remember-me aware listener (such as form-login) for each firewall that has remember-me enabled.'); + } + $rememberMeServices->replaceArgument(0, $userProviders); + + // remember-me listener + $listenerId = 'security.authentication.listener.rememberme.'.$id; + $listener = $container->setDefinition($listenerId, new DefinitionDecorator('security.authentication.listener.rememberme')); + $listener->replaceArgument(1, new Reference($rememberMeServicesId)); + + return array($authProviderId, $listenerId, $defaultEntryPoint); + } + + public function getPosition() + { + return 'remember_me'; + } + + public function getKey() + { + return 'remember-me'; + } + + public function addConfiguration(NodeDefinition $node) + { + $node->fixXmlConfig('user_provider'); + $builder = $node->children(); + + $builder + ->scalarNode('key')->isRequired()->cannotBeEmpty()->end() + ->scalarNode('token_provider')->end() + ->arrayNode('user_providers') + ->beforeNormalization() + ->ifString()->then(function($v) { return array($v); }) + ->end() + ->prototype('scalar')->end() + ->end() + ; + + foreach ($this->options as $name => $value) { + if (is_bool($value)) { + $builder->booleanNode($name)->defaultValue($value); + } else { + $builder->scalarNode($name)->defaultValue($value); + } + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php new file mode 100644 index 0000000..5ef4c00 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.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\Bundle\SecurityBundle\DependencyInjection\Security\Factory; + +use Symfony\Component\Config\Definition\Builder\NodeDefinition; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * SecurityFactoryInterface is the interface for all security authentication listener. + * + * @author Fabien Potencier + */ +interface SecurityFactoryInterface +{ + function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint); + + function getPosition(); + + function getKey(); + + function addConfiguration(NodeDefinition $builder); +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/X509Factory.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/X509Factory.php new file mode 100644 index 0000000..d24942b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/X509Factory.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\Bundle\SecurityBundle\DependencyInjection\Security\Factory; + +use Symfony\Component\Config\Definition\Builder\NodeDefinition; + +use Symfony\Component\DependencyInjection\DefinitionDecorator; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * X509Factory creates services for X509 certificate authentication. + * + * @author Fabien Potencier + */ +class X509Factory implements SecurityFactoryInterface +{ + public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint) + { + $provider = 'security.authentication.provider.pre_authenticated.'.$id; + $container + ->setDefinition($provider, new DefinitionDecorator('security.authentication.provider.pre_authenticated')) + ->replaceArgument(0, new Reference($userProvider)) + ->addArgument($id) + ; + + // listener + $listenerId = 'security.authentication.listener.x509.'.$id; + $listener = $container->setDefinition($listenerId, new DefinitionDecorator('security.authentication.listener.x509')); + $listener->replaceArgument(2, $id); + $listener->replaceArgument(3, $config['user']); + $listener->replaceArgument(4, $config['credentials']); + + return array($provider, $listenerId, $defaultEntryPoint); + } + + public function getPosition() + { + return 'pre_auth'; + } + + public function getKey() + { + return 'x509'; + } + + public function addConfiguration(NodeDefinition $node) + { + $node + ->children() + ->scalarNode('provider')->end() + ->scalarNode('user')->defaultValue('SSL_CLIENT_S_DN_Email')->end() + ->scalarNode('credentials')->defaultValue('SSL_CLIENT_S_DN')->end() + ->end() + ; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/InMemoryFactory.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/InMemoryFactory.php new file mode 100644 index 0000000..bab1bb4 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/InMemoryFactory.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\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider; + +use Symfony\Component\Config\Definition\Builder\NodeDefinition; + +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * InMemoryFactory creates services for the memory provider. + * + * @author Fabien Potencier + * @author Christophe Coevoet + */ +class InMemoryFactory implements UserProviderFactoryInterface +{ + public function create(ContainerBuilder $container, $id, $config) + { + $definition = $container->setDefinition($id, new DefinitionDecorator('security.user.provider.in_memory')); + + foreach ($config['users'] as $username => $user) { + $userId = $id.'_'.$username; + + $container + ->setDefinition($userId, new DefinitionDecorator('security.user.provider.in_memory.user')) + ->setArguments(array($username, (string) $user['password'], $user['roles'])) + ; + + $definition->addMethodCall('createUser', array(new Reference($userId))); + } + } + + public function getKey() + { + return 'memory'; + } + + public function addConfiguration(NodeDefinition $node) + { + $node + ->fixXmlConfig('user') + ->children() + ->arrayNode('users') + ->useAttributeAsKey('name') + ->prototype('array') + ->children() + ->scalarNode('password')->defaultValue(uniqid())->end() + ->arrayNode('roles') + ->beforeNormalization()->ifString()->then(function($v) { return preg_split('/\s*,\s*/', $v); })->end() + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/UserProviderFactoryInterface.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/UserProviderFactoryInterface.php new file mode 100644 index 0000000..9f7eaf6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/UserProviderFactoryInterface.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\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider; + +use Symfony\Component\Config\Definition\Builder\NodeDefinition; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * UserProviderFactoryInterface is the interface for all user provider factories. + * + * @author Fabien Potencier + * @author Christophe Coevoet + */ +interface UserProviderFactoryInterface +{ + function create(ContainerBuilder $container, $id, $config); + + function getKey(); + + function addConfiguration(NodeDefinition $builder); +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php new file mode 100644 index 0000000..71d8d36 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -0,0 +1,635 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\SecurityBundle\DependencyInjection; + +use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface; +use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\UserProviderFactoryInterface; +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\Config\FileLocator; + +/** + * SecurityExtension. + * + * @author Fabien Potencier + * @author Johannes M. Schmitt + */ +class SecurityExtension extends Extension +{ + private $requestMatchers = array(); + private $contextListeners = array(); + private $listenerPositions = array('pre_auth', 'form', 'http', 'remember_me'); + private $factories = array(); + private $userProviderFactories = array(); + + public function __construct() + { + foreach ($this->listenerPositions as $position) { + $this->factories[$position] = array(); + } + } + + public function load(array $configs, ContainerBuilder $container) + { + if (!array_filter($configs)) { + return; + } + + $mainConfig = $this->getConfiguration($configs, $container); + + $config = $this->processConfiguration($mainConfig, $configs); + + // load services + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('security.xml'); + $loader->load('security_listeners.xml'); + $loader->load('security_rememberme.xml'); + $loader->load('templating_php.xml'); + $loader->load('templating_twig.xml'); + $loader->load('collectors.xml'); + + // set some global scalars + $container->setParameter('security.access.denied_url', $config['access_denied_url']); + $container->setParameter('security.authentication.manager.erase_credentials', $config['erase_credentials']); + $container->setParameter('security.authentication.session_strategy.strategy', $config['session_fixation_strategy']); + $container + ->getDefinition('security.access.decision_manager') + ->addArgument($config['access_decision_manager']['strategy']) + ->addArgument($config['access_decision_manager']['allow_if_all_abstain']) + ->addArgument($config['access_decision_manager']['allow_if_equal_granted_denied']) + ; + $container->setParameter('security.access.always_authenticate_before_granting', $config['always_authenticate_before_granting']); + $container->setParameter('security.authentication.hide_user_not_found', $config['hide_user_not_found']); + + $this->createFirewalls($config, $container); + $this->createAuthorization($config, $container); + $this->createRoleHierarchy($config, $container); + + if ($config['encoders']) { + $this->createEncoders($config['encoders'], $container); + } + + // load ACL + if (isset($config['acl'])) { + $this->aclLoad($config['acl'], $container); + } + + // add some required classes for compilation + $this->addClassesToCompile(array( + 'Symfony\\Component\\Security\\Http\\Firewall', + 'Symfony\\Component\\Security\\Http\\FirewallMapInterface', + 'Symfony\\Component\\Security\\Core\\SecurityContext', + 'Symfony\\Component\\Security\\Core\\SecurityContextInterface', + 'Symfony\\Component\\Security\\Core\\User\\UserProviderInterface', + 'Symfony\\Component\\Security\\Core\\Authentication\\AuthenticationProviderManager', + 'Symfony\\Component\\Security\\Core\\Authentication\\AuthenticationManagerInterface', + 'Symfony\\Component\\Security\\Core\\Authorization\\AccessDecisionManager', + 'Symfony\\Component\\Security\\Core\\Authorization\\AccessDecisionManagerInterface', + 'Symfony\\Component\\Security\\Core\\Authorization\\Voter\\VoterInterface', + + 'Symfony\\Bundle\\SecurityBundle\\Security\\FirewallMap', + 'Symfony\\Bundle\\SecurityBundle\\Security\\FirewallContext', + + 'Symfony\\Component\\HttpFoundation\\RequestMatcher', + 'Symfony\\Component\\HttpFoundation\\RequestMatcherInterface', + )); + } + + private function aclLoad($config, ContainerBuilder $container) + { + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('security_acl.xml'); + + if (isset($config['cache']['id'])) { + $container->setAlias('security.acl.cache', $config['cache']['id']); + } + $container->getDefinition('security.acl.voter.basic_permissions')->addArgument($config['voter']['allow_if_object_identity_unavailable']); + + // custom ACL provider + if (isset($config['provider'])) { + $container->setAlias('security.acl.provider', $config['provider']); + + return; + } + + $this->configureDbalAclProvider($config, $container, $loader); + } + + private function configureDbalAclProvider(array $config, ContainerBuilder $container, $loader) + { + $loader->load('security_acl_dbal.xml'); + + if (null !== $config['connection']) { + $container->setAlias('security.acl.dbal.connection', sprintf('doctrine.dbal.%s_connection', $config['connection'])); + } + + $container + ->getDefinition('security.acl.dbal.schema_listener') + ->addTag('doctrine.event_listener', array( + 'connection' => $config['connection'], + 'event' => 'postGenerateSchema', + 'lazy' => true + )) + ; + + $container->getDefinition('security.acl.cache.doctrine')->addArgument($config['cache']['prefix']); + + $container->setParameter('security.acl.dbal.class_table_name', $config['tables']['class']); + $container->setParameter('security.acl.dbal.entry_table_name', $config['tables']['entry']); + $container->setParameter('security.acl.dbal.oid_table_name', $config['tables']['object_identity']); + $container->setParameter('security.acl.dbal.oid_ancestors_table_name', $config['tables']['object_identity_ancestors']); + $container->setParameter('security.acl.dbal.sid_table_name', $config['tables']['security_identity']); + } + + /** + * Loads the web configuration. + * + * @param array $config An array of configuration settings + * @param ContainerBuilder $container A ContainerBuilder instance + */ + + private function createRoleHierarchy($config, ContainerBuilder $container) + { + if (!isset($config['role_hierarchy'])) { + $container->removeDefinition('security.access.role_hierarchy_voter'); + + return; + } + + $container->setParameter('security.role_hierarchy.roles', $config['role_hierarchy']); + $container->removeDefinition('security.access.simple_role_voter'); + } + + private function createAuthorization($config, ContainerBuilder $container) + { + if (!$config['access_control']) { + return; + } + + $this->addClassesToCompile(array( + 'Symfony\\Component\\Security\\Http\\AccessMapInterface', + 'Symfony\\Component\\Security\\Http\\AccessMap', + )); + + foreach ($config['access_control'] as $access) { + $matcher = $this->createRequestMatcher( + $container, + $access['path'], + $access['host'], + count($access['methods']) === 0 ? null : $access['methods'], + $access['ip'] + ); + + $container->getDefinition('security.access_map') + ->addMethodCall('add', array($matcher, $access['roles'], $access['requires_channel'])); + } + } + + private function createFirewalls($config, ContainerBuilder $container) + { + if (!isset($config['firewalls'])) { + return; + } + + $firewalls = $config['firewalls']; + $providerIds = $this->createUserProviders($config, $container); + + // make the ContextListener aware of the configured user providers + $definition = $container->getDefinition('security.context_listener'); + $arguments = $definition->getArguments(); + $userProviders = array(); + foreach ($providerIds as $userProviderId) { + $userProviders[] = new Reference($userProviderId); + } + $arguments[1] = $userProviders; + $definition->setArguments($arguments); + + // load firewall map + $mapDef = $container->getDefinition('security.firewall.map'); + $map = $authenticationProviders = array(); + foreach ($firewalls as $name => $firewall) { + list($matcher, $listeners, $exceptionListener) = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds); + + $contextId = 'security.firewall.map.context.'.$name; + $context = $container->setDefinition($contextId, new DefinitionDecorator('security.firewall.context')); + $context + ->replaceArgument(0, $listeners) + ->replaceArgument(1, $exceptionListener) + ; + $map[$contextId] = $matcher; + } + $mapDef->replaceArgument(1, $map); + + // add authentication providers to authentication manager + $authenticationProviders = array_map(function($id) { + return new Reference($id); + }, array_values(array_unique($authenticationProviders))); + $container + ->getDefinition('security.authentication.manager') + ->replaceArgument(0, $authenticationProviders) + ; + } + + private function createFirewall(ContainerBuilder $container, $id, $firewall, &$authenticationProviders, $providerIds) + { + // Matcher + $i = 0; + $matcher = null; + if (isset($firewall['request_matcher'])) { + $matcher = new Reference($firewall['request_matcher']); + } elseif (isset($firewall['pattern'])) { + $matcher = $this->createRequestMatcher($container, $firewall['pattern']); + } + + // Security disabled? + if (false === $firewall['security']) { + return array($matcher, array(), null); + } + + // Provider id (take the first registered provider if none defined) + if (isset($firewall['provider'])) { + $defaultProvider = $this->getUserProviderId($firewall['provider']); + } else { + $defaultProvider = reset($providerIds); + } + + // Register listeners + $listeners = array(); + + // Channel listener + $listeners[] = new Reference('security.channel_listener'); + + // Context serializer listener + if (false === $firewall['stateless']) { + $contextKey = $id; + if (isset($firewall['context'])) { + $contextKey = $firewall['context']; + } + + $listeners[] = new Reference($this->createContextListener($container, $contextKey)); + } + + // Logout listener + if (isset($firewall['logout'])) { + $listenerId = 'security.logout_listener.'.$id; + $listener = $container->setDefinition($listenerId, new DefinitionDecorator('security.logout_listener')); + $listener->replaceArgument(2, array( + 'csrf_parameter' => $firewall['logout']['csrf_parameter'], + 'intention' => $firewall['logout']['intention'], + 'logout_path' => $firewall['logout']['path'], + 'target_url' => $firewall['logout']['target'], + )); + $listeners[] = new Reference($listenerId); + + // add logout success handler + if (isset($firewall['logout']['success_handler'])) { + $listener->replaceArgument(3, new Reference($firewall['logout']['success_handler'])); + } + + // add CSRF provider + if (isset($firewall['logout']['csrf_provider'])) { + $listener->addArgument(new Reference($firewall['logout']['csrf_provider'])); + } + + // add session logout handler + if (true === $firewall['logout']['invalidate_session'] && false === $firewall['stateless']) { + $listener->addMethodCall('addHandler', array(new Reference('security.logout.handler.session'))); + } + + // add cookie logout handler + if (count($firewall['logout']['delete_cookies']) > 0) { + $cookieHandlerId = 'security.logout.handler.cookie_clearing.'.$id; + $cookieHandler = $container->setDefinition($cookieHandlerId, new DefinitionDecorator('security.logout.handler.cookie_clearing')); + $cookieHandler->addArgument($firewall['logout']['delete_cookies']); + + $listener->addMethodCall('addHandler', array(new Reference($cookieHandlerId))); + } + + // add custom handlers + foreach ($firewall['logout']['handlers'] as $handlerId) { + $listener->addMethodCall('addHandler', array(new Reference($handlerId))); + } + + // register with LogoutUrlHelper + $container + ->getDefinition('templating.helper.logout_url') + ->addMethodCall('registerListener', array( + $id, + $firewall['logout']['path'], + $firewall['logout']['intention'], + $firewall['logout']['csrf_parameter'], + isset($firewall['logout']['csrf_provider']) ? new Reference($firewall['logout']['csrf_provider']) : null, + )) + ; + } + + // Authentication listeners + list($authListeners, $defaultEntryPoint) = $this->createAuthenticationListeners($container, $id, $firewall, $authenticationProviders, $defaultProvider); + + $listeners = array_merge($listeners, $authListeners); + + // Access listener + $listeners[] = new Reference('security.access_listener'); + + // Switch user listener + if (isset($firewall['switch_user'])) { + $listeners[] = new Reference($this->createSwitchUserListener($container, $id, $firewall['switch_user'], $defaultProvider)); + } + + // Determine default entry point + if (isset($firewall['entry_point'])) { + $defaultEntryPoint = $firewall['entry_point']; + } + + // Exception listener + $exceptionListener = new Reference($this->createExceptionListener($container, $firewall, $id, $defaultEntryPoint)); + + return array($matcher, $listeners, $exceptionListener); + } + + private function createContextListener($container, $contextKey) + { + if (isset($this->contextListeners[$contextKey])) { + return $this->contextListeners[$contextKey]; + } + + $listenerId = 'security.context_listener.'.count($this->contextListeners); + $listener = $container->setDefinition($listenerId, new DefinitionDecorator('security.context_listener')); + $listener->replaceArgument(2, $contextKey); + + return $this->contextListeners[$contextKey] = $listenerId; + } + + private function createAuthenticationListeners($container, $id, $firewall, &$authenticationProviders, $defaultProvider) + { + $listeners = array(); + $hasListeners = false; + $defaultEntryPoint = null; + + foreach ($this->listenerPositions as $position) { + foreach ($this->factories[$position] as $factory) { + $key = str_replace('-', '_', $factory->getKey()); + + if (isset($firewall[$key])) { + $userProvider = isset($firewall[$key]['provider']) ? $this->getUserProviderId($firewall[$key]['provider']) : $defaultProvider; + + list($provider, $listenerId, $defaultEntryPoint) = $factory->create($container, $id, $firewall[$key], $userProvider, $defaultEntryPoint); + + $listeners[] = new Reference($listenerId); + $authenticationProviders[] = $provider; + $hasListeners = true; + } + } + } + + // Anonymous + if (isset($firewall['anonymous'])) { + $listenerId = 'security.authentication.listener.anonymous.'.$id; + $container + ->setDefinition($listenerId, new DefinitionDecorator('security.authentication.listener.anonymous')) + ->replaceArgument(1, $firewall['anonymous']['key']) + ; + + $listeners[] = new Reference($listenerId); + + $providerId = 'security.authentication.provider.anonymous.'.$id; + $container + ->setDefinition($providerId, new DefinitionDecorator('security.authentication.provider.anonymous')) + ->replaceArgument(0, $firewall['anonymous']['key']) + ; + + $authenticationProviders[] = $providerId; + $hasListeners = true; + } + + if (false === $hasListeners) { + throw new \LogicException(sprintf('No authentication listener registered for firewall "%s".', $id)); + } + + return array($listeners, $defaultEntryPoint); + } + + private function createEncoders($encoders, ContainerBuilder $container) + { + $encoderMap = array(); + foreach ($encoders as $class => $encoder) { + $encoderMap[$class] = $this->createEncoder($encoder, $container); + } + + $container + ->getDefinition('security.encoder_factory.generic') + ->setArguments(array($encoderMap)) + ; + } + + private function createEncoder($config, ContainerBuilder $container) + { + // a custom encoder service + if (isset($config['id'])) { + return new Reference($config['id']); + } + + // plaintext encoder + if ('plaintext' === $config['algorithm']) { + $arguments = array($config['ignore_case']); + + return array( + 'class' => new Parameter('security.encoder.plain.class'), + 'arguments' => $arguments, + ); + } + + // message digest encoder + $arguments = array( + $config['algorithm'], + $config['encode_as_base64'], + $config['iterations'], + ); + + return array( + 'class' => new Parameter('security.encoder.digest.class'), + 'arguments' => $arguments, + ); + } + + // Parses user providers and returns an array of their ids + private function createUserProviders($config, ContainerBuilder $container) + { + $providerIds = array(); + foreach ($config['providers'] as $name => $provider) { + $id = $this->createUserDaoProvider($name, $provider, $container); + $providerIds[] = $id; + } + + return $providerIds; + } + + // Parses a tag and returns the id for the related user provider service + private function createUserDaoProvider($name, $provider, ContainerBuilder $container, $master = true) + { + $name = $this->getUserProviderId(strtolower($name)); + + foreach ($this->userProviderFactories as $factory) { + $key = str_replace('-', '_', $factory->getKey()); + + if (!empty($provider[$key])) { + $factory->create($container, $name, $provider[$key]); + + return $name; + } + } + + // Existing DAO service provider + if (isset($provider['id'])) { + $container->setAlias($name, new Alias($provider['id'], false)); + + return $provider['id']; + } + + // Chain provider + if (isset($provider['chain'])) { + $providers = array(); + foreach ($provider['chain']['providers'] as $providerName) { + $providers[] = new Reference($this->getUserProviderId(strtolower($providerName))); + } + + $container + ->setDefinition($name, new DefinitionDecorator('security.user.provider.chain')) + ->addArgument($providers) + ; + + return $name; + } + + // Doctrine Entity DAO provider + if (isset($provider['entity'])) { + $container + ->setDefinition($name, new DefinitionDecorator('security.user.provider.entity')) + ->addArgument($provider['entity']['class']) + ->addArgument($provider['entity']['property']) + ; + + return $name; + } + + // In-memory DAO provider + $definition = $container->setDefinition($name, new DefinitionDecorator('security.user.provider.in_memory')); + foreach ($provider['users'] as $username => $user) { + $userId = $name.'_'.$username; + + $container + ->setDefinition($userId, new DefinitionDecorator('security.user.provider.in_memory.user')) + ->setArguments(array($username, (string) $user['password'], $user['roles'])) + ; + + $definition->addMethodCall('createUser', array(new Reference($userId))); + } + + return $name; + } + + private function getUserProviderId($name) + { + return 'security.user.provider.concrete.'.$name; + } + + private function createExceptionListener($container, $config, $id, $defaultEntryPoint) + { + $exceptionListenerId = 'security.exception_listener.'.$id; + $listener = $container->setDefinition($exceptionListenerId, new DefinitionDecorator('security.exception_listener')); + $listener->replaceArgument(3, null === $defaultEntryPoint ? null : new Reference($defaultEntryPoint)); + + // access denied handler setup + if (isset($config['access_denied_handler'])) { + $listener->replaceArgument(5, new Reference($config['access_denied_handler'])); + } elseif (isset($config['access_denied_url'])) { + $listener->replaceArgument(4, $config['access_denied_url']); + } + + return $exceptionListenerId; + } + + private function createSwitchUserListener($container, $id, $config, $defaultProvider) + { + $userProvider = isset($config['provider']) ? $this->getUserProviderId($config['provider']) : $defaultProvider; + + $switchUserListenerId = 'security.authentication.switchuser_listener.'.$id; + $listener = $container->setDefinition($switchUserListenerId, new DefinitionDecorator('security.authentication.switchuser_listener')); + $listener->replaceArgument(1, new Reference($userProvider)); + $listener->replaceArgument(3, $id); + $listener->replaceArgument(6, $config['parameter']); + $listener->replaceArgument(7, $config['role']); + + return $switchUserListenerId; + } + + private function createRequestMatcher($container, $path = null, $host = null, $methods = null, $ip = null, array $attributes = array()) + { + $serialized = serialize(array($path, $host, $methods, $ip, $attributes)); + $id = 'security.request_matcher.'.md5($serialized).sha1($serialized); + + if (isset($this->requestMatchers[$id])) { + return $this->requestMatchers[$id]; + } + + // only add arguments that are necessary + $arguments = array($path, $host, $methods, $ip, $attributes); + while (count($arguments) > 0 && !end($arguments)) { + array_pop($arguments); + } + + $container + ->register($id, '%security.matcher.class%') + ->setPublic(false) + ->setArguments($arguments) + ; + + return $this->requestMatchers[$id] = new Reference($id); + } + + public function addSecurityListenerFactory(SecurityFactoryInterface $factory) + { + $this->factories[$factory->getPosition()][] = $factory; + } + + public function addUserProviderFactory(UserProviderFactoryInterface $factory) + { + $this->userProviderFactories[] = $factory; + } + + /** + * Returns the base path for the XSD files. + * + * @return string The XSD base path + */ + public function getXsdValidationBasePath() + { + return __DIR__.'/../Resources/config/schema'; + } + + public function getNamespace() + { + return 'http://symfony.com/schema/dic/security'; + } + + public function getConfiguration(array $config, ContainerBuilder $container) + { + // first assemble the factories + return new MainConfiguration($this->factories, $this->userProviderFactories); + } +} + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/EventListener/AclSchemaListener.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/EventListener/AclSchemaListener.php new file mode 100644 index 0000000..53758ab --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/EventListener/AclSchemaListener.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\Bundle\SecurityBundle\EventListener; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs; + +/** + * Merges ACL schema into the given schema. + * + * @author Johannes M. Schmitt + */ +class AclSchemaListener +{ + private $container; + + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + public function postGenerateSchema(GenerateSchemaEventArgs $args) + { + $schema = $args->getSchema(); + $this->container->get('security.acl.dbal.schema')->addToSchema($schema); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/EventListener/ResponseListener.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/EventListener/ResponseListener.php new file mode 100644 index 0000000..62d53dc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/EventListener/ResponseListener.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\Bundle\SecurityBundle\EventListener; + +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface; + +/** + * Adds remember-me cookies to the Response. + * + * @author Johannes M. Schmitt + */ +class ResponseListener +{ + public function onKernelResponse(FilterResponseEvent $event) + { + $request = $event->getRequest(); + $response = $event->getResponse(); + + if ($request->attributes->has(RememberMeServicesInterface::COOKIE_ATTR_NAME)) { + $response->headers->setCookie($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/LICENSE b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/LICENSE new file mode 100644 index 0000000..cdffe7a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 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/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/collectors.xml b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/collectors.xml new file mode 100644 index 0000000..f6106f7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/collectors.xml @@ -0,0 +1,17 @@ + + + + + + Symfony\Bundle\SecurityBundle\DataCollector\SecurityDataCollector + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml new file mode 100644 index 0000000..bb47fde --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml @@ -0,0 +1,140 @@ + + + + + + Symfony\Component\Security\Core\SecurityContext + + Symfony\Component\Security\Core\User\UserChecker + + Symfony\Component\Security\Core\Encoder\EncoderFactory + Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder + Symfony\Component\Security\Core\Encoder\PlaintextPasswordEncoder + + Symfony\Component\Security\Core\User\InMemoryUserProvider + Symfony\Component\Security\Core\User\User + Symfony\Component\Security\Core\User\ChainUserProvider + + Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver + Symfony\Component\Security\Core\Authentication\Token\AnonymousToken + Symfony\Component\Security\Core\Authentication\Token\RememberMeToken + + Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager + + Symfony\Component\Security\Http\Session\SessionAuthenticationStrategy + + Symfony\Component\Security\Core\Authorization\AccessDecisionManager + + Symfony\Component\Security\Core\Authorization\Voter\RoleVoter + Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter + Symfony\Component\Security\Core\Authorization\Voter\RoleHierarchyVoter + + Symfony\Component\Security\Http\Firewall + Symfony\Bundle\SecurityBundle\Security\FirewallMap + Symfony\Bundle\SecurityBundle\Security\FirewallContext + Symfony\Component\HttpFoundation\RequestMatcher + + Symfony\Component\Security\Core\Role\RoleHierarchy + + Symfony\Component\Security\Http\HttpUtils + + Symfony\Component\Security\Core\Validator\Constraint\UserPasswordValidator + + + + + + + %security.access.always_authenticate_before_granting% + + + + + + %security.authentication.manager.erase_credentials% + + + + + + + %security.authentication.trust_resolver.anonymous_class% + %security.authentication.trust_resolver.rememberme_class% + + + + %security.authentication.session_strategy.strategy% + + + + + + + + + + + + + + + + + + %security.role_hierarchy.roles% + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl.xml b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl.xml new file mode 100644 index 0000000..624b6b1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl.xml @@ -0,0 +1,47 @@ + + + + + + Symfony\Component\Security\Acl\Domain\PermissionGrantingStrategy + + Symfony\Component\Security\Acl\Voter\AclVoter + Symfony\Component\Security\Acl\Permission\BasicPermissionMap + + Symfony\Component\Security\Acl\Domain\ObjectIdentityRetrievalStrategy + Symfony\Component\Security\Acl\Domain\SecurityIdentityRetrievalStrategy + + Symfony\Component\Security\Acl\Domain\DoctrineAclCache + + Symfony\Component\Security\Acl\Domain\AclCollectionCache + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl_dbal.xml b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl_dbal.xml new file mode 100644 index 0000000..aac84a3 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl_dbal.xml @@ -0,0 +1,54 @@ + + + + + + Symfony\Component\Security\Acl\Dbal\MutableAclProvider + Symfony\Component\Security\Acl\Dbal\Schema + Symfony\Bundle\SecurityBundle\EventListener\AclSchemaListener + + + + + + + + + + %security.acl.dbal.class_table_name% + %security.acl.dbal.entry_table_name% + %security.acl.dbal.oid_table_name% + %security.acl.dbal.oid_ancestors_table_name% + %security.acl.dbal.sid_table_name% + + + + + + + %security.acl.dbal.class_table_name% + %security.acl.dbal.entry_table_name% + %security.acl.dbal.oid_table_name% + %security.acl.dbal.oid_ancestors_table_name% + %security.acl.dbal.sid_table_name% + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml new file mode 100644 index 0000000..b35e3a2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml @@ -0,0 +1,189 @@ + + + + + + Symfony\Component\Security\Http\EntryPoint\RetryAuthenticationEntryPoint + + Symfony\Component\Security\Http\Firewall\ChannelListener + + Symfony\Component\Security\Http\EntryPoint\FormAuthenticationEntryPoint + Symfony\Component\Security\Http\Firewall\UsernamePasswordFormAuthenticationListener + + Symfony\Component\Security\Http\Firewall\BasicAuthenticationListener + Symfony\Component\Security\Http\EntryPoint\BasicAuthenticationEntryPoint + + Symfony\Component\Security\Http\Firewall\DigestAuthenticationListener + Symfony\Component\Security\Http\EntryPoint\DigestAuthenticationEntryPoint + + Symfony\Component\Security\Http\Firewall\X509AuthenticationListener + + Symfony\Component\Security\Http\Firewall\AnonymousAuthenticationListener + + Symfony\Component\Security\Http\Firewall\SwitchUserListener + + Symfony\Component\Security\Http\Firewall\LogoutListener + Symfony\Component\Security\Http\Logout\SessionLogoutHandler + Symfony\Component\Security\Http\Logout\CookieClearingLogoutHandler + + Symfony\Component\Security\Http\Firewall\AccessListener + Symfony\Component\Security\Http\AccessMap + Symfony\Component\Security\Http\Firewall\ExceptionListener + Symfony\Component\Security\Http\Firewall\ContextListener + + Symfony\Component\Security\Core\Authentication\Provider\DaoAuthenticationProvider + Symfony\Component\Security\Core\Authentication\Provider\PreAuthenticatedAuthenticationProvider + + Symfony\Component\Security\Core\Authentication\Provider\AnonymousAuthenticationProvider + + + + + + + + + + + + + + + + %request_listener.http_port% + %request_listener.https_port% + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %security.authentication.hide_user_not_found% + + + + + + + + + + + + + + %security.access.denied_url% + + + + + + + + + + + + + _switch_user + ROLE_ALLOWED_TO_SWITCH + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/security_rememberme.xml b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/security_rememberme.xml new file mode 100644 index 0000000..983ef57 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/security_rememberme.xml @@ -0,0 +1,61 @@ + + + + + + Symfony\Component\Security\Core\Authentication\Provider\RememberMeAuthenticationProvider + + Symfony\Component\Security\Http\Firewall\RememberMeListener + Symfony\Component\Security\Core\Authentication\RememberMe\InMemoryTokenProvider + + Symfony\Component\Security\Http\RememberMe\PersistentTokenBasedRememberMeServices + Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices + + Symfony\Bundle\SecurityBundle\EventListener\ResponseListener + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/templating_php.xml b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/templating_php.xml new file mode 100644 index 0000000..c91bf79 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/templating_php.xml @@ -0,0 +1,24 @@ + + + + + + Symfony\Bundle\SecurityBundle\Templating\Helper\LogoutUrlHelper + Symfony\Bundle\SecurityBundle\Templating\Helper\SecurityHelper + + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/templating_twig.xml b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/templating_twig.xml new file mode 100644 index 0000000..d457cf1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/config/templating_twig.xml @@ -0,0 +1,23 @@ + + + + + + Symfony\Bundle\SecurityBundle\Twig\Extension\LogoutUrlExtension + Symfony\Bridge\Twig\Extension\SecurityExtension + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig new file mode 100644 index 0000000..d0838de --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig @@ -0,0 +1,74 @@ +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} + +{% block toolbar %} + {% if collector.user %} + {% set color_code = (collector.enabled and collector.authenticated) ? 'green' : 'yellow' %} + {% set authentication_color_code = (collector.enabled and collector.authenticated) ? 'green' : 'red' %} + {% set authentication_color_text = (collector.enabled and collector.authenticated) ? 'Yes' : 'No' %} + {% else %} + {% set color_code = collector.enabled ? 'red' : 'black' %} + {% endif %} + {% set text %} + {% if collector.user %} +
    + Logged in as + {{ collector.user }} +
    +
    + Authenticated + {{ authentication_color_text }} +
    + {% elseif collector.enabled %} + You are not authenticated. + {% else %} + The security is disabled. + {% endif %} + {% endset %} + {% set icon %} + Security + + {% if collector.user %}
    {{ collector.user }}
    {% endif %} + {% endset %} + {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %} +{% endblock %} + +{% block menu %} + + + Security + +{% endblock %} + +{% block panel %} +

    Security

    + {% if collector.user %} + + + + + + + + + + + + + +
    Username{{ collector.user }}
    Authenticated? + {% if collector.authenticated %} + yes + {% else %} + no {% if not collector.roles|length %}(probably because the user has no roles){% endif %} + {% endif %} +
    Roles{{ collector.roles|yaml_encode }}
    + {% elseif collector.enabled %} +

    + No token +

    + {% else %} +

    + The security component is disabled +

    + {% endif %} +{% endblock %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php new file mode 100644 index 0000000..13d096d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.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\Bundle\SecurityBundle\Security; + +use Symfony\Component\Security\Http\Firewall\ExceptionListener; + +/** + * This is a wrapper around the actual firewall configuration which allows us + * to lazy load the context for one specific firewall only when we need it. + * + * @author Johannes M. Schmitt + */ +class FirewallContext +{ + private $listeners; + private $exceptionListener; + + public function __construct(array $listeners, ExceptionListener $exceptionListener = null) + { + $this->listeners = $listeners; + $this->exceptionListener = $exceptionListener; + } + + public function getContext() + { + return array($this->listeners, $this->exceptionListener); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Security/FirewallMap.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Security/FirewallMap.php new file mode 100644 index 0000000..b06234b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Security/FirewallMap.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\Bundle\SecurityBundle\Security; + +use Symfony\Component\Security\Http\FirewallMapInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * This is a lazy-loading firewall map implementation + * + * Listeners will only be initialized if we really need them. + * + * @author Johannes M. Schmitt + */ +class FirewallMap implements FirewallMapInterface +{ + protected $container; + protected $map; + + public function __construct(ContainerInterface $container, array $map) + { + $this->container = $container; + $this->map = $map; + } + + public function getListeners(Request $request) + { + foreach ($this->map as $contextId => $requestMatcher) { + if (null === $requestMatcher || $requestMatcher->matches($request)) { + return $this->container->get($contextId)->getContext(); + } + } + + return array(array(), null); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/SecurityBundle.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/SecurityBundle.php new file mode 100644 index 0000000..7d810fd --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/SecurityBundle.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\Bundle\SecurityBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\AddSecurityVotersPass; +use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\FormLoginFactory; +use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\HttpBasicFactory; +use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\HttpDigestFactory; +use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\RememberMeFactory; +use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\X509Factory; +use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\InMemoryFactory; + +/** + * Bundle. + * + * @author Fabien Potencier + */ +class SecurityBundle extends Bundle +{ + public function build(ContainerBuilder $container) + { + parent::build($container); + + $extension = $container->getExtension('security'); + $extension->addSecurityListenerFactory(new FormLoginFactory()); + $extension->addSecurityListenerFactory(new HttpBasicFactory()); + $extension->addSecurityListenerFactory(new HttpDigestFactory()); + $extension->addSecurityListenerFactory(new RememberMeFactory()); + $extension->addSecurityListenerFactory(new X509Factory()); + + $extension->addUserProviderFactory(new InMemoryFactory()); + $container->addCompilerPass(new AddSecurityVotersPass()); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Templating/Helper/LogoutUrlHelper.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Templating/Helper/LogoutUrlHelper.php new file mode 100644 index 0000000..b24988e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Templating/Helper/LogoutUrlHelper.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\Bundle\SecurityBundle\Templating\Helper; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use Symfony\Component\Templating\Helper\Helper; + +/** + * LogoutUrlHelper provides generator functions for the logout URL. + * + * @author Jeremy Mikola + */ +class LogoutUrlHelper extends Helper +{ + private $container; + private $listeners; + private $router; + + /** + * Constructor. + * + * @param ContainerInterface $container A ContainerInterface instance + * @param UrlGeneratorInterface $router A Router instance + */ + public function __construct(ContainerInterface $container, UrlGeneratorInterface $router) + { + $this->container = $container; + $this->router = $router; + $this->listeners = array(); + } + + /** + * Registers a firewall's LogoutListener, allowing its URL to be generated. + * + * @param string $key The firewall key + * @param string $logoutPath The path that starts the logout process + * @param string $intention The intention for CSRF token generation + * @param string $csrfParameter The CSRF token parameter name + * @param CsrfProviderInterface $csrfProvider A CsrfProviderInterface instance + */ + public function registerListener($key, $logoutPath, $intention, $csrfParameter, CsrfProviderInterface $csrfProvider = null) + { + $this->listeners[$key] = array($logoutPath, $intention, $csrfParameter, $csrfProvider); + } + + /** + * Generate the relative logout URL for the firewall. + * + * @param string $key The firewall key + * @return string The relative logout URL + */ + public function getLogoutPath($key) + { + return $this->generateLogoutUrl($key, false); + } + + /** + * Generate the absolute logout URL for the firewall. + * + * @param string $key The firewall key + * @return string The absolute logout URL + */ + public function getLogoutUrl($key) + { + return $this->generateLogoutUrl($key, true); + } + + /** + * Generate the logout URL for the firewall. + * + * @param string $key The firewall key + * @param Boolean $absolute Whether to generate an absolute URL + * @return string The logout URL + * @throws InvalidArgumentException if no LogoutListener is registered for the key + */ + private function generateLogoutUrl($key, $absolute) + { + if (!array_key_exists($key, $this->listeners)) { + throw new \InvalidArgumentException(sprintf('No LogoutListener found for firewall key "%s".', $key)); + } + + list($logoutPath, $intention, $csrfParameter, $csrfProvider) = $this->listeners[$key]; + + $parameters = null !== $csrfProvider ? array($csrfParameter => $csrfProvider->generateCsrfToken($intention)) : array(); + + if ('/' === $logoutPath[0]) { + $request = $this->container->get('request'); + + $url = ($absolute ? $request->getUriForPath($logoutPath) : $request->getBasePath() . $logoutPath); + + if (!empty($parameters)) { + $url .= '?' . http_build_query($parameters); + } + } else { + $url = $this->router->generate($logoutPath, $parameters, $absolute); + } + + return $url; + } + + /** + * Returns the canonical name of this helper. + * + * @return string The canonical name + */ + public function getName() + { + return 'logout_url'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Templating/Helper/SecurityHelper.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Templating/Helper/SecurityHelper.php new file mode 100644 index 0000000..7ca0e7b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Templating/Helper/SecurityHelper.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\Bundle\SecurityBundle\Templating\Helper; + +use Symfony\Component\Security\Acl\Voter\FieldVote; +use Symfony\Component\Templating\Helper\Helper; +use Symfony\Component\Security\Core\SecurityContextInterface; + +/** + * SecurityHelper provides read-only access to the security context. + * + * @author Fabien Potencier + */ +class SecurityHelper extends Helper +{ + private $context; + + /** + * Constructor. + * + * @param SecurityContextInterface $context A SecurityContext instance + */ + public function __construct(SecurityContextInterface $context = null) + { + $this->context = $context; + } + + public function isGranted($role, $object = null, $field = null) + { + if (null === $this->context) { + return false; + } + + if (null !== $field) { + $object = new FieldVote($object, $field); + } + + return $this->context->isGranted($role, $object); + } + + /** + * Returns the canonical name of this helper. + * + * @return string The canonical name + */ + public function getName() + { + return 'security'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/ConfigurationTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/ConfigurationTest.php new file mode 100644 index 0000000..c859cff --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/ConfigurationTest.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\Bundle\SecurityBundle\Tests\DependencyInjection; + +use Symfony\Bundle\SecurityBundle\DependencyInjection\MainConfiguration; +use Symfony\Component\Config\Definition\Processor; + +class ConfigurationTest extends \PHPUnit_Framework_TestCase +{ + /** + * The minimal, required config needed to not have any required validation + * issues. + * + * @var array + */ + protected static $minimalConfig = array( + 'providers' => array( + 'stub' => array( + 'id' => 'foo', + ), + ), + 'firewalls' => array( + 'stub' => array(), + ), + ); + + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + */ + public function testNoConfigForProvider() + { + $config = array( + 'providers' => array( + 'stub' => array(), + ), + ); + + $processor = new Processor(); + $configuration = new MainConfiguration(array(), array()); + $config = $processor->processConfiguration($configuration, array($config)); + } + + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + */ + public function testManyConfigForProvider() + { + $config = array( + 'providers' => array( + 'stub' => array( + 'id' => 'foo', + 'chain' => array(), + ), + ), + ); + + $processor = new Processor(); + $configuration = new MainConfiguration(array(), array()); + $config = $processor->processConfiguration($configuration, array($config)); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/container1.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/container1.php new file mode 100644 index 0000000..8652333 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/container1.php @@ -0,0 +1,75 @@ +loadFromExtension('security', array( + 'acl' => array(), + 'encoders' => array( + 'JMS\FooBundle\Entity\User1' => 'plaintext', + 'JMS\FooBundle\Entity\User2' => array( + 'algorithm' => 'sha1', + 'encode_as_base64' => false, + 'iterations' => 5, + ), + 'JMS\FooBundle\Entity\User3' => array( + 'algorithm' => 'md5', + ), + 'JMS\FooBundle\Entity\User4' => array( + 'id' => 'security.encoder.foo', + ), + ), + 'providers' => array( + 'default' => array( + 'memory' => array( + 'users' => array( + 'foo' => array('password' => 'foo', 'roles' => 'ROLE_USER'), + ), + ), + ), + 'digest' => array( + 'memory' => array( + 'users' => array( + 'foo' => array('password' => 'foo', 'roles' => 'ROLE_USER, ROLE_ADMIN'), + ), + ), + ), + 'basic' => array( + 'memory' => array( + 'users' => array( + 'foo' => array('password' => '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33', 'roles' => 'ROLE_SUPER_ADMIN'), + 'bar' => array('password' => '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33', 'roles' => array('ROLE_USER', 'ROLE_ADMIN')), + ), + ), + ), + 'service' => array( + 'id' => 'user.manager', + ), + 'chain' => array( + 'chain' => array( + 'providers' => array('service', 'basic'), + ), + ), + ), + + 'firewalls' => array( + 'simple' => array('pattern' => '/login', 'security' => false), + 'secure' => array('stateless' => true, + 'http_basic' => true, + 'http_digest' => array('key' => 'TheKey'), + 'form_login' => true, + 'anonymous' => true, + 'switch_user' => true, + 'x509' => true, + 'logout' => true, + ), + ), + + 'access_control' => array( + array('path' => '/blog/524', 'role' => 'ROLE_USER', 'requires_channel' => 'https'), + array('path' => '/blog/.*', 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY'), + ), + + 'role_hierarchy' => array( + 'ROLE_ADMIN' => 'ROLE_USER', + 'ROLE_SUPER_ADMIN' => array('ROLE_USER', 'ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH'), + 'ROLE_REMOTE' => 'ROLE_USER,ROLE_ADMIN', + ), +)); diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/custom_acl_provider.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/custom_acl_provider.php new file mode 100644 index 0000000..4acf6cc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/custom_acl_provider.php @@ -0,0 +1,9 @@ +load('container1.php', $container); + +$container->loadFromExtension('security', array( + 'acl' => array( + 'provider' => 'foo', + ) +)); diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/merge.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/merge.php new file mode 100644 index 0000000..82966dc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/merge.php @@ -0,0 +1,20 @@ +load('merge_import.php', $container); + +$container->loadFromExtension('security', array( + 'providers' => array( + 'default' => array('id' => 'foo'), + ), + + 'firewalls' => array( + 'main' => array( + 'form_login' => false, + 'http_basic' => null, + ), + ), + + 'role_hierarchy' => array( + 'FOO' => array('MOO'), + ) +)); diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/merge_import.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/merge_import.php new file mode 100644 index 0000000..1e29d40 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/merge_import.php @@ -0,0 +1,15 @@ +loadFromExtension('security', array( + 'firewalls' => array( + 'main' => array( + 'form_login' => array( + 'login_path' => '/login', + ) + ) + ), + 'role_hierarchy' => array( + 'FOO' => 'BAR', + 'ADMIN' => 'USER', + ), +)); diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/container1.xml b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/container1.xml new file mode 100644 index 0000000..20c3760 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/container1.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ROLE_USER + ROLE_USER,ROLE_ADMIN,ROLE_ALLOWED_TO_SWITCH + ROLE_USER,ROLE_ADMIN + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/custom_acl_provider.xml b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/custom_acl_provider.xml new file mode 100644 index 0000000..6addc81 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/custom_acl_provider.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/merge.xml b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/merge.xml new file mode 100644 index 0000000..8a17f6d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/merge.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/merge_import.xml b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/merge_import.xml new file mode 100644 index 0000000..81b8cff --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/merge_import.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/container1.yml b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/container1.yml new file mode 100644 index 0000000..ade174f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/container1.yml @@ -0,0 +1,57 @@ +security: + acl: ~ + encoders: + JMS\FooBundle\Entity\User1: plaintext + JMS\FooBundle\Entity\User2: + algorithm: sha1 + encode_as_base64: false + iterations: 5 + JMS\FooBundle\Entity\User3: + algorithm: md5 + JMS\FooBundle\Entity\User4: + id: security.encoder.foo + + providers: + default: + memory: + users: + foo: { password: foo, roles: ROLE_USER } + digest: + memory: + users: + foo: { password: foo, roles: 'ROLE_USER, ROLE_ADMIN' } + basic: + memory: + users: + foo: { password: 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33, roles: ROLE_SUPER_ADMIN } + bar: { password: 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33, roles: [ROLE_USER, ROLE_ADMIN] } + service: + id: user.manager + chain: + chain: + providers: [service, basic] + + + firewalls: + simple: { pattern: /login, security: false } + secure: + stateless: true + http_basic: true + http_digest: + key: TheKey + form_login: true + anonymous: true + switch_user: true + x509: true + logout: true + + role_hierarchy: + ROLE_ADMIN: ROLE_USER + ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH] + ROLE_REMOTE: ROLE_USER,ROLE_ADMIN + + access_control: + - { path: /blog/524, role: ROLE_USER, requires_channel: https } + - + path: /blog/.* + role: IS_AUTHENTICATED_ANONYMOUSLY diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/custom_acl_provider.yml b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/custom_acl_provider.yml new file mode 100644 index 0000000..633eed0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/custom_acl_provider.yml @@ -0,0 +1,6 @@ +imports: + - { resource: container1.yml } + +security: + acl: + provider: foo diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/merge.yml b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/merge.yml new file mode 100644 index 0000000..60c0bbe --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/merge.yml @@ -0,0 +1,14 @@ +imports: + - { resource: merge_import.yml } + +security: + providers: + default: { id: foo } + + firewalls: + main: + form_login: false + http_basic: ~ + + role_hierarchy: + FOO: [MOO] diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/merge_import.yml b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/merge_import.yml new file mode 100644 index 0000000..4f8db0a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/merge_import.yml @@ -0,0 +1,9 @@ +security: + firewalls: + main: + form_login: + login_path: /login + + role_hierarchy: + FOO: BAR + ADMIN: USER diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/PhpSecurityExtensionTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/PhpSecurityExtensionTest.php new file mode 100644 index 0000000..fc54797 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/PhpSecurityExtensionTest.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\Bundle\SecurityBundle\Tests\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use Symfony\Component\Config\FileLocator; + +class PhpSecurityExtensionTest extends SecurityExtensionTest +{ + protected function loadFromFile(ContainerBuilder $container, $file) + { + $loadXml = new PhpFileLoader($container, new FileLocator(__DIR__.'/Fixtures/php')); + $loadXml->load($file.'.php'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php new file mode 100644 index 0000000..cc070db --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.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\Bundle\SecurityBundle\Tests\DependencyInjection\Security\Factory; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +class AbstractFactoryTest extends \PHPUnit_Framework_TestCase +{ + public function testCreate() + { + $factory = $this->getFactory(); + + $factory + ->expects($this->once()) + ->method('createAuthProvider') + ->will($this->returnValue('auth_provider')) + ; + $factory + ->expects($this->atLeastOnce()) + ->method('getListenerId') + ->will($this->returnValue('abstract_listener')) + ; + + $container = new ContainerBuilder(); + $container->register('auth_provider'); + + list($authProviderId, + $listenerId, + $entryPointId + ) = $factory->create($container, 'foo', array('use_forward' => true, 'failure_path' => '/foo', 'success_handler' => 'foo', 'remember_me' => true), 'user_provider', 'entry_point'); + + // auth provider + $this->assertEquals('auth_provider', $authProviderId); + + // listener + $this->assertEquals('abstract_listener.foo', $listenerId); + $this->assertTrue($container->hasDefinition('abstract_listener.foo')); + $definition = $container->getDefinition('abstract_listener.foo'); + $this->assertEquals(array( + 'index_4' => 'foo', + 'index_5' => array( + 'use_forward' => true, + 'failure_path' => '/foo', + ), + 'index_6' => new Reference('foo'), + ), $definition->getArguments()); + + // entry point + $this->assertEquals('entry_point', $entryPointId, '->create() does not change the default entry point.'); + } + + protected function getFactory() + { + return $this->getMockForAbstractClass('Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AbstractFactory', array()); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php new file mode 100644 index 0000000..60e1778 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php @@ -0,0 +1,183 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\SecurityBundle\Tests\DependencyInjection; + +use Symfony\Component\DependencyInjection\Reference; + +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Bundle\SecurityBundle\SecurityBundle; +use Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +abstract class SecurityExtensionTest extends \PHPUnit_Framework_TestCase +{ + abstract protected function loadFromFile(ContainerBuilder $container, $file); + + public function testRolesHierarchy() + { + $container = $this->getContainer('container1'); + $this->assertEquals(array( + 'ROLE_ADMIN' => array('ROLE_USER'), + 'ROLE_SUPER_ADMIN' => array('ROLE_USER', 'ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH'), + 'ROLE_REMOTE' => array('ROLE_USER', 'ROLE_ADMIN'), + ), $container->getParameter('security.role_hierarchy.roles')); + } + + public function testUserProviders() + { + $container = $this->getContainer('container1'); + + $providers = array_values(array_filter($container->getServiceIds(), function ($key) { return 0 === strpos($key, 'security.user.provider.concrete'); })); + + $expectedProviders = array( + 'security.user.provider.concrete.default', + 'security.user.provider.concrete.default_foo', + 'security.user.provider.concrete.digest', + 'security.user.provider.concrete.digest_foo', + 'security.user.provider.concrete.basic', + 'security.user.provider.concrete.basic_foo', + 'security.user.provider.concrete.basic_bar', + 'security.user.provider.concrete.service', + 'security.user.provider.concrete.chain', + ); + + $this->assertEquals(array(), array_diff($expectedProviders, $providers)); + $this->assertEquals(array(), array_diff($providers, $expectedProviders)); + + // chain provider + $this->assertEquals(array(array( + new Reference('security.user.provider.concrete.service'), + new Reference('security.user.provider.concrete.basic'), + )), $container->getDefinition('security.user.provider.concrete.chain')->getArguments()); + } + + public function testFirewalls() + { + $container = $this->getContainer('container1'); + + $arguments = $container->getDefinition('security.firewall.map')->getArguments(); + $listeners = array(); + foreach (array_keys($arguments[1]) as $contextId) { + $contextDef = $container->getDefinition($contextId); + $arguments = $contextDef->getArguments(); + $listeners[] = array_map(function ($ref) { return (string) $ref; }, $arguments['index_0']); + } + + $this->assertEquals(array( + array(), + array( + 'security.channel_listener', + 'security.logout_listener.secure', + 'security.authentication.listener.x509.secure', + 'security.authentication.listener.form.secure', + 'security.authentication.listener.basic.secure', + 'security.authentication.listener.digest.secure', + 'security.authentication.listener.anonymous.secure', + 'security.access_listener', + 'security.authentication.switchuser_listener.secure', + ), + ), $listeners); + } + + public function testAccess() + { + $container = $this->getContainer('container1'); + + $rules = array(); + foreach ($container->getDefinition('security.access_map')->getMethodCalls() as $call) { + if ($call[0] == 'add') { + $rules[] = array((string) $call[1][0], $call[1][1], $call[1][2]); + } + } + + $matcherIds = array(); + foreach ($rules as $rule) { + list($matcherId, $roles, $channel) = $rule; + + $this->assertFalse(isset($matcherIds[$matcherId])); + $matcherIds[$matcherId] = true; + + $i = count($matcherIds); + if (1 === $i) { + $this->assertEquals(array('ROLE_USER'), $roles); + $this->assertEquals('https', $channel); + } elseif (2 === $i) { + $this->assertEquals(array('IS_AUTHENTICATED_ANONYMOUSLY'), $roles); + $this->assertNull($channel); + } + } + } + + public function testMerge() + { + $container = $this->getContainer('merge'); + + $this->assertEquals(array( + 'FOO' => array('MOO'), + 'ADMIN' => array('USER'), + ), $container->getParameter('security.role_hierarchy.roles')); + } + + public function testEncoders() + { + $container = $this->getContainer('container1'); + + $this->assertEquals(array(array( + 'JMS\FooBundle\Entity\User1' => array( + 'class' => new Parameter('security.encoder.plain.class'), + 'arguments' => array(false), + ), + 'JMS\FooBundle\Entity\User2' => array( + 'class' => new Parameter('security.encoder.digest.class'), + 'arguments' => array('sha1', false, 5), + ), + 'JMS\FooBundle\Entity\User3' => array( + 'class' => new Parameter('security.encoder.digest.class'), + 'arguments' => array('md5', true, 5000), + ), + 'JMS\FooBundle\Entity\User4' => new Reference('security.encoder.foo'), + )), $container->getDefinition('security.encoder_factory.generic')->getArguments()); + } + + public function testAcl() + { + $container = $this->getContainer('container1'); + + $this->assertTrue($container->hasDefinition('security.acl.dbal.provider')); + $this->assertEquals('security.acl.dbal.provider', (string) $container->getAlias('security.acl.provider')); + } + + public function testCustomAclProvider() + { + $container = $this->getContainer('custom_acl_provider'); + + $this->assertFalse($container->hasDefinition('security.acl.dbal.provider')); + $this->assertEquals('foo', (string) $container->getAlias('security.acl.provider')); + } + + protected function getContainer($file) + { + $container = new ContainerBuilder(); + $security = new SecurityExtension(); + $container->registerExtension($security); + + $bundle = new SecurityBundle(); + $bundle->build($container); // Attach all default factories + $this->loadFromFile($container, $file); + + $container->getCompilerPassConfig()->setOptimizationPasses(array()); + $container->getCompilerPassConfig()->setRemovingPasses(array()); + $container->compile(); + + return $container; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/XmlSecurityExtensionTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/XmlSecurityExtensionTest.php new file mode 100644 index 0000000..6ce0489 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/XmlSecurityExtensionTest.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\Bundle\SecurityBundle\Tests\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\Config\FileLocator; + +class XmlSecurityExtensionTest extends SecurityExtensionTest +{ + protected function loadFromFile(ContainerBuilder $container, $file) + { + $loadXml = new XmlFileLoader($container, new FileLocator(__DIR__.'/Fixtures/xml')); + $loadXml->load($file.'.xml'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/YamlSecurityExtensionTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/YamlSecurityExtensionTest.php new file mode 100644 index 0000000..f5fabe0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/YamlSecurityExtensionTest.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\Bundle\SecurityBundle\Tests\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\Config\FileLocator; + +class YamlSecurityExtensionTest extends SecurityExtensionTest +{ + protected function loadFromFile(ContainerBuilder $container, $file) + { + $loadXml = new YamlFileLoader($container, new FileLocator(__DIR__.'/Fixtures/yml')); + $loadXml->load($file.'.yml'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticationCommencingTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticationCommencingTest.php new file mode 100644 index 0000000..e94a21e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticationCommencingTest.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\Bundle\SecurityBundle\Tests\Functional; + +class AuthenticationCommencingTest extends WebTestCase +{ + public function testAuthenticationIsCommencingIfAccessDeniedExceptionIsWrapped() + { + $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => 'config.yml')); + $client->insulate(); + + $client->request('GET', '/secure-but-not-covered-by-access-control'); + $this->assertRedirect($client->getResponse(), '/login'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Controller/LoginController.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Controller/LoginController.php new file mode 100644 index 0000000..3442459 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Controller/LoginController.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\Bundle\SecurityBundle\Tests\Functional\Bundle\CsrfFormLoginBundle\Controller; + +use Symfony\Component\DependencyInjection\ContainerAware; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Security\Core\Exception\AccessDeniedException; + +class LoginController extends ContainerAware +{ + public function loginAction() + { + $form = $this->container->get('form.factory')->create('user_login'); + + return $this->container->get('templating')->renderResponse('CsrfFormLoginBundle:Login:login.html.twig', array( + 'form' => $form->createView(), + )); + } + + public function afterLoginAction() + { + return $this->container->get('templating')->renderResponse('CsrfFormLoginBundle:Login:after_login.html.twig'); + } + + public function loginCheckAction() + { + return new Response('', 400); + } + + public function secureAction() + { + throw new \Exception('Wrapper', 0, new \Exception('Another Wrapper', 0, new AccessDeniedException())); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/CsrfFormLoginBundle.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/CsrfFormLoginBundle.php new file mode 100644 index 0000000..41309d9 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/CsrfFormLoginBundle.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\Bundle\SecurityBundle\Tests\Functional\Bundle\CsrfFormLoginBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class CsrfFormLoginBundle extends Bundle +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Form/UserLoginFormType.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Form/UserLoginFormType.php new file mode 100644 index 0000000..21389ef --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Form/UserLoginFormType.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\Bundle\SecurityBundle\Tests\Functional\Bundle\CsrfFormLoginBundle\Form; + +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\Form\FormError; +use Symfony\Component\Form\FormEvents; +use Symfony\Component\Form\FormEvent; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Security\Core\SecurityContextInterface; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; + +/** + * Form type for use with the Security component's form-based authentication + * listener. + * + * @author Henrik Bjornskov + * @author Jeremy Mikola + */ +class UserLoginFormType extends AbstractType +{ + private $request; + + /** + * @param Request $request A request instance + */ + public function __construct(Request $request) + { + $this->request = $request; + } + + /** + * @see Symfony\Component\Form\AbstractType::buildForm() + */ + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder + ->add('username', 'text') + ->add('password', 'password') + ->add('_target_path', 'hidden') + ; + + $request = $this->request; + + /* Note: since the Security component's form login listener intercepts + * the POST request, this form will never really be bound to the + * request; however, we can match the expected behavior by checking the + * session for an authentication error and last username. + */ + $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($request) { + if ($request->attributes->has(SecurityContextInterface::AUTHENTICATION_ERROR)) { + $error = $request->attributes->get(SecurityContextInterface::AUTHENTICATION_ERROR); + } else { + $error = $request->getSession()->get(SecurityContextInterface::AUTHENTICATION_ERROR); + } + + if ($error) { + $event->getForm()->addError(new FormError($error->getMessage())); + } + + $event->setData(array_replace((array) $event->getData(), array( + 'username' => $request->getSession()->get(SecurityContextInterface::LAST_USERNAME), + ))); + }); + } + + /** + * @see Symfony\Component\Form\AbstractType::setDefaultOptions() + */ + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + /* Note: the form's intention must correspond to that for the form login + * listener in order for the CSRF token to validate successfully. + */ + + $resolver->setDefaults(array( + 'intention' => 'authenticate', + )); + } + + /** + * @see Symfony\Component\Form\FormTypeInterface::getName() + */ + public function getName() + { + return 'user_login'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Resources/config/routing.yml b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Resources/config/routing.yml new file mode 100644 index 0000000..0c9842b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Resources/config/routing.yml @@ -0,0 +1,30 @@ +form_login: + pattern: /login + defaults: { _controller: CsrfFormLoginBundle:Login:login } + +form_login_check: + pattern: /login_check + defaults: { _controller: CsrfFormLoginBundle:Login:loginCheck } + +form_login_homepage: + pattern: / + defaults: { _controller: CsrfFormLoginBundle:Login:afterLogin } + +form_login_custom_target_path: + pattern: /foo + defaults: { _controller: CsrfFormLoginBundle:Login:afterLogin } + +form_login_default_target_path: + pattern: /profile + defaults: { _controller: CsrfFormLoginBundle:Login:afterLogin } + +form_login_redirect_to_protected_resource_after_login: + pattern: /protected-resource + defaults: { _controller: CsrfFormLoginBundle:Login:afterLogin } + +form_logout: + pattern: /logout_path + +form_secure_action: + pattern: /secure-but-not-covered-by-access-control + defaults: { _controller: CsrfFormLoginBundle:Login:secure } diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Resources/views/Login/after_login.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Resources/views/Login/after_login.html.twig new file mode 100644 index 0000000..b56c186 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Resources/views/Login/after_login.html.twig @@ -0,0 +1,8 @@ +{% extends "::base.html.twig" %} + +{% block body %} + Hello {{ app.user.username }}!

    + You're browsing to path "{{ app.request.pathInfo }}".

    + Log out. + Log out. +{% endblock %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Resources/views/Login/login.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Resources/views/Login/login.html.twig new file mode 100644 index 0000000..36ae015 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Resources/views/Login/login.html.twig @@ -0,0 +1,12 @@ +{% extends "::base.html.twig" %} + +{% block body %} + + + {{ form_widget(form) }} + + {# Note: ensure the submit name does not conflict with the form's name or it may clobber field data #} + + + +{% endblock %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Controller/LocalizedController.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Controller/LocalizedController.php new file mode 100644 index 0000000..381b13d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Controller/LocalizedController.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\Bundle\SecurityBundle\Tests\Functional\Bundle\FormLoginBundle\Controller; + +use Symfony\Component\Security\Core\SecurityContext; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\DependencyInjection\ContainerAware; + +class LocalizedController extends ContainerAware +{ + public function loginAction() + { + // get the login error if there is one + if ($this->container->get('request')->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) { + $error = $this->container->get('request')->attributes->get(SecurityContext::AUTHENTICATION_ERROR); + } else { + $error = $this->container->get('request')->getSession()->get(SecurityContext::AUTHENTICATION_ERROR); + } + + return $this->container->get('templating')->renderResponse('FormLoginBundle:Localized:login.html.twig', array( + // last username entered by the user + 'last_username' => $this->container->get('request')->getSession()->get(SecurityContext::LAST_USERNAME), + 'error' => $error, + )); + } + + public function loginCheckAction() + { + throw new \RuntimeException('loginCheckAction() should never be called.'); + } + + public function logoutAction() + { + throw new \RuntimeException('logoutAction() should never be called.'); + } + + public function secureAction() + { + throw new \RuntimeException('secureAction() should never be called.'); + } + + public function profileAction() + { + return new Response('Profile'); + } + + public function homepageAction() + { + return new Response('Homepage'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Controller/LoginController.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Controller/LoginController.php new file mode 100644 index 0000000..cec298c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Controller/LoginController.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\Bundle\SecurityBundle\Tests\Functional\Bundle\FormLoginBundle\Controller; + +use Symfony\Component\Security\Core\Exception\AccessDeniedException; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Security\Core\SecurityContext; +use Symfony\Component\DependencyInjection\ContainerAware; + +class LoginController extends ContainerAware +{ + public function loginAction() + { + // get the login error if there is one + if ($this->container->get('request')->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) { + $error = $this->container->get('request')->attributes->get(SecurityContext::AUTHENTICATION_ERROR); + } else { + $error = $this->container->get('request')->getSession()->get(SecurityContext::AUTHENTICATION_ERROR); + } + + return $this->container->get('templating')->renderResponse('FormLoginBundle:Login:login.html.twig', array( + // last username entered by the user + 'last_username' => $this->container->get('request')->getSession()->get(SecurityContext::LAST_USERNAME), + 'error' => $error, + )); + } + + public function afterLoginAction() + { + return $this->container->get('templating')->renderResponse('FormLoginBundle:Login:after_login.html.twig'); + } + + public function loginCheckAction() + { + return new Response('', 400); + } + + public function secureAction() + { + throw new \Exception('Wrapper', 0, new \Exception('Another Wrapper', 0, new AccessDeniedException())); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/DependencyInjection/FormLoginExtension.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/DependencyInjection/FormLoginExtension.php new file mode 100644 index 0000000..016bf5a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/DependencyInjection/FormLoginExtension.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\Bundle\SecurityBundle\Tests\Functional\Bundle\FormLoginBundle\DependencyInjection; + +use Symfony\Component\DependencyInjection\Reference; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\HttpKernel\DependencyInjection\Extension; + +class FormLoginExtension extends Extension +{ + public function load(array $configs, ContainerBuilder $container) + { + $container + ->register('localized_form_failure_handler', 'Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\FormLoginBundle\Security\LocalizedFormFailureHandler') + ->addArgument(new Reference('router')) + ; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/FormLoginBundle.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/FormLoginBundle.php new file mode 100644 index 0000000..eab1913 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/FormLoginBundle.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\Bundle\SecurityBundle\Tests\Functional\Bundle\FormLoginBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class FormLoginBundle extends Bundle +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/config/localized_routing.yml b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/config/localized_routing.yml new file mode 100644 index 0000000..a10bf9e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/config/localized_routing.yml @@ -0,0 +1,29 @@ +localized_login_path: + pattern: /{_locale}/login + defaults: { _controller: FormLoginBundle:Localized:login } + requirements: { _locale: "^[a-z]{2}$" } + +localized_check_path: + pattern: /{_locale}/login_check + defaults: { _controller: FormLoginBundle:Localized:loginCheck } + requirements: { _locale: "^[a-z]{2}$" } + +localized_default_target_path: + pattern: /{_locale}/profile + defaults: { _controller: FormLoginBundle:Localized:profile } + requirements: { _locale: "^[a-z]{2}$" } + +localized_logout_path: + pattern: /{_locale}/logout + defaults: { _controller: FormLoginBundle:Localized:logout } + requirements: { _locale: "^[a-z]{2}$" } + +localized_logout_target_path: + pattern: /{_locale}/ + defaults: { _controller: FormLoginBundle:Localized:homepage } + requirements: { _locale: "^[a-z]{2}$" } + +localized_secure_path: + pattern: /{_locale}/secure/ + defaults: { _controller: FormLoginBundle:Localized:secure } + requirements: { _locale: "^[a-z]{2}$" } diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/config/routing.yml b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/config/routing.yml new file mode 100644 index 0000000..c9684ce --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/config/routing.yml @@ -0,0 +1,33 @@ +form_login: + pattern: /login + defaults: { _controller: FormLoginBundle:Login:login } + +form_login_check: + pattern: /login_check + defaults: { _controller: FormLoginBundle:Login:loginCheck } + +form_login_homepage: + pattern: / + defaults: { _controller: FormLoginBundle:Login:afterLogin } + +form_login_custom_target_path: + pattern: /foo + defaults: { _controller: FormLoginBundle:Login:afterLogin } + +form_login_default_target_path: + pattern: /profile + defaults: { _controller: FormLoginBundle:Login:afterLogin } + +form_login_redirect_to_protected_resource_after_login: + pattern: /protected_resource + defaults: { _controller: FormLoginBundle:Login:afterLogin } + +highly_protected_resource: + pattern: /highly_protected_resource + +form_logout: + pattern: /logout_path + +form_secure_action: + pattern: /secure-but-not-covered-by-access-control + defaults: { _controller: FormLoginBundle:Login:secure } diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/views/Localized/login.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/views/Localized/login.html.twig new file mode 100644 index 0000000..60dd2f1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/views/Localized/login.html.twig @@ -0,0 +1,21 @@ +{% extends "::base.html.twig" %} + +{% block body %} + + {% if error %} +
    {{ error.message }}
    + {% endif %} + +
    + + + + + + + + + +
    + +{% endblock %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/views/Login/after_login.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/views/Login/after_login.html.twig new file mode 100644 index 0000000..9972b48 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/views/Login/after_login.html.twig @@ -0,0 +1,6 @@ +{% extends "::base.html.twig" %} + +{% block body %} + Hello {{ app.user.username }}!

    + You're browsing to path "{{ app.request.pathInfo }}". +{% endblock %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/views/Login/login.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/views/Login/login.html.twig new file mode 100644 index 0000000..6c1a224 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/views/Login/login.html.twig @@ -0,0 +1,21 @@ +{% extends "::base.html.twig" %} + +{% block body %} + + {% if error %} +
    {{ error.message }}
    + {% endif %} + +
    + + + + + + + + + +
    + +{% endblock %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Security/LocalizedFormFailureHandler.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Security/LocalizedFormFailureHandler.php new file mode 100644 index 0000000..fda394d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Security/LocalizedFormFailureHandler.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\Bundle\SecurityBundle\Tests\Functional\Bundle\FormLoginBundle\Security; + +use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\Routing\RouterInterface; +use Symfony\Component\Security\Core\Exception\AuthenticationException; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface; + +class LocalizedFormFailureHandler implements AuthenticationFailureHandlerInterface +{ + private $router; + + public function __construct(RouterInterface $router) + { + $this->router = $router; + } + + public function onAuthenticationFailure(Request $request, AuthenticationException $exception) + { + return new RedirectResponse($this->router->generate('localized_login_path', array(), true)); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/CsrfFormLoginTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/CsrfFormLoginTest.php new file mode 100644 index 0000000..4c4c1ac --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/CsrfFormLoginTest.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\Bundle\SecurityBundle\Tests\Functional; + +/** + * @group functional + */ +class CsrfFormLoginTest extends WebTestCase +{ + /** + * @dataProvider getConfigs + */ + public function testFormLoginAndLogoutWithCsrfTokens($config) + { + $client = $this->createClient(array('test_case' => 'CsrfFormLogin', 'root_config' => $config)); + $client->insulate(); + + $form = $client->request('GET', '/login')->selectButton('login')->form(); + $form['user_login[username]'] = 'johannes'; + $form['user_login[password]'] = 'test'; + $client->submit($form); + + $this->assertRedirect($client->getResponse(), '/profile'); + + $crawler = $client->followRedirect(); + + $text = $crawler->text(); + $this->assertContains('Hello johannes!', $text); + $this->assertContains('You\'re browsing to path "/profile".', $text); + + $logoutLinks = $crawler->selectLink('Log out')->links(); + $this->assertCount(2, $logoutLinks); + $this->assertContains('_csrf_token=', $logoutLinks[0]->getUri()); + $this->assertSame($logoutLinks[0]->getUri(), $logoutLinks[1]->getUri()); + + $client->click($logoutLinks[0]); + + $this->assertRedirect($client->getResponse(), '/'); + } + + /** + * @dataProvider getConfigs + */ + public function testFormLoginWithInvalidCsrfToken($config) + { + $client = $this->createClient(array('test_case' => 'CsrfFormLogin', 'root_config' => $config)); + $client->insulate(); + + $form = $client->request('GET', '/login')->selectButton('login')->form(); + $form['user_login[_token]'] = ''; + $client->submit($form); + + $this->assertRedirect($client->getResponse(), '/login'); + + $text = $client->followRedirect()->text(); + $this->assertContains('Invalid CSRF token.', $text); + } + + /** + * @dataProvider getConfigs + */ + public function testFormLoginWithCustomTargetPath($config) + { + $client = $this->createClient(array('test_case' => 'CsrfFormLogin', 'root_config' => $config)); + $client->insulate(); + + $form = $client->request('GET', '/login')->selectButton('login')->form(); + $form['user_login[username]'] = 'johannes'; + $form['user_login[password]'] = 'test'; + $form['user_login[_target_path]'] = '/foo'; + $client->submit($form); + + $this->assertRedirect($client->getResponse(), '/foo'); + + $text = $client->followRedirect()->text(); + $this->assertContains('Hello johannes!', $text); + $this->assertContains('You\'re browsing to path "/foo".', $text); + } + + /** + * @dataProvider getConfigs + */ + public function testFormLoginRedirectsToProtectedResourceAfterLogin($config) + { + $client = $this->createClient(array('test_case' => 'CsrfFormLogin', 'root_config' => $config)); + $client->insulate(); + + $client->request('GET', '/protected-resource'); + $this->assertRedirect($client->getResponse(), '/login'); + + $form = $client->followRedirect()->selectButton('login')->form(); + $form['user_login[username]'] = 'johannes'; + $form['user_login[password]'] = 'test'; + $client->submit($form); + $this->assertRedirect($client->getResponse(), '/protected-resource'); + + $text = $client->followRedirect()->text(); + $this->assertContains('Hello johannes!', $text); + $this->assertContains('You\'re browsing to path "/protected-resource".', $text); + } + + public function getConfigs() + { + return array( + array('config.yml'), + array('routes_as_path.yml'), + ); + } + + protected function setUp() + { + parent::setUp(); + + $this->deleteTmpDir('CsrfFormLogin'); + } + + protected function tearDown() + { + parent::tearDown(); + + $this->deleteTmpDir('CsrfFormLogin'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/FormLoginTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/FormLoginTest.php new file mode 100644 index 0000000..0dc038e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/FormLoginTest.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\Bundle\SecurityBundle\Tests\Functional; + +/** + * @group functional + */ +class FormLoginTest extends WebTestCase +{ + /** + * @dataProvider getConfigs + */ + public function testFormLogin($config) + { + $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config)); + $client->insulate(); + + $form = $client->request('GET', '/login')->selectButton('login')->form(); + $form['_username'] = 'johannes'; + $form['_password'] = 'test'; + $client->submit($form); + + $this->assertRedirect($client->getResponse(), '/profile'); + + $text = $client->followRedirect()->text(); + $this->assertContains('Hello johannes!', $text); + $this->assertContains('You\'re browsing to path "/profile".', $text); + } + + /** + * @dataProvider getConfigs + */ + public function testFormLoginWithCustomTargetPath($config) + { + $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config)); + $client->insulate(); + + $form = $client->request('GET', '/login')->selectButton('login')->form(); + $form['_username'] = 'johannes'; + $form['_password'] = 'test'; + $form['_target_path'] = '/foo'; + $client->submit($form); + + $this->assertRedirect($client->getResponse(), '/foo'); + + $text = $client->followRedirect()->text(); + $this->assertContains('Hello johannes!', $text); + $this->assertContains('You\'re browsing to path "/foo".', $text); + } + + /** + * @dataProvider getConfigs + */ + public function testFormLoginRedirectsToProtectedResourceAfterLogin($config) + { + $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config)); + $client->insulate(); + + $client->request('GET', '/protected_resource'); + $this->assertRedirect($client->getResponse(), '/login'); + + $form = $client->followRedirect()->selectButton('login')->form(); + $form['_username'] = 'johannes'; + $form['_password'] = 'test'; + $client->submit($form); + $this->assertRedirect($client->getResponse(), '/protected_resource'); + + $text = $client->followRedirect()->text(); + $this->assertContains('Hello johannes!', $text); + $this->assertContains('You\'re browsing to path "/protected_resource".', $text); + } + + public function getConfigs() + { + return array( + array('config.yml'), + array('routes_as_path.yml'), + ); + } + + protected function setUp() + { + parent::setUp(); + + $this->deleteTmpDir('StandardFormLogin'); + } + + protected function tearDown() + { + parent::tearDown(); + + $this->deleteTmpDir('StandardFormLogin'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LocalizedRoutesAsPathTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LocalizedRoutesAsPathTest.php new file mode 100644 index 0000000..84c7905 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LocalizedRoutesAsPathTest.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\Bundle\SecurityBundle\Tests\Functional; + +class LocalizedRoutesAsPathTest extends WebTestCase +{ + /** + * @dataProvider getLocales + */ + public function testLoginLogoutProcedure($locale) + { + $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => 'localized_routes.yml')); + $client->insulate(); + + $crawler = $client->request('GET', '/'.$locale.'/login'); + $form = $crawler->selectButton('login')->form(); + $form['_username'] = 'johannes'; + $form['_password'] = 'test'; + $client->submit($form); + + $this->assertRedirect($client->getResponse(), '/'.$locale.'/profile'); + $this->assertEquals('Profile', $client->followRedirect()->text()); + + $client->request('GET', '/'.$locale.'/logout'); + $this->assertRedirect($client->getResponse(), '/'.$locale.'/'); + $this->assertEquals('Homepage', $client->followRedirect()->text()); + } + + /** + * @dataProvider getLocales + */ + public function testLoginFailureWithLocalizedFailurePath($locale) + { + $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => 'localized_form_failure_handler.yml')); + $client->insulate(); + + $crawler = $client->request('GET', '/'.$locale.'/login'); + $form = $crawler->selectButton('login')->form(); + $form['_username'] = 'johannes'; + $form['_password'] = 'foobar'; + $client->submit($form); + + $this->assertRedirect($client->getResponse(), '/'.$locale.'/login'); + } + + /** + * @dataProvider getLocales + */ + public function testAccessRestrictedResource($locale) + { + $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => 'localized_routes.yml')); + $client->insulate(); + + $client->request('GET', '/'.$locale.'/secure/'); + $this->assertRedirect($client->getResponse(), '/'.$locale.'/login'); + } + + /** + * @dataProvider getLocales + */ + public function testAccessRestrictedResourceWithForward($locale) + { + $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => 'localized_routes_with_forward.yml')); + $client->insulate(); + + $crawler = $client->request('GET', '/'.$locale.'/secure/'); + $this->assertCount(1, $crawler->selectButton('login'), (string) $client->getResponse()); + } + + public function getLocales() + { + return array(array('en'), array('de')); + } + + protected function setUp() + { + parent::setUp(); + + $this->deleteTmpDir('StandardFormLogin'); + } + + protected function tearDown() + { + parent::tearDown(); + + $this->deleteTmpDir('StandardFormLogin'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityRoutingIntegrationTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityRoutingIntegrationTest.php new file mode 100644 index 0000000..3ae81bc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityRoutingIntegrationTest.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\Bundle\SecurityBundle\Tests\Functional; + +class SecurityRoutingIntegrationTest extends WebTestCase +{ + /** + * @dataProvider getConfigs + */ + public function testRoutingErrorIsNotExposedForProtectedResourceWhenAnonymous($config) + { + $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config)); + $client->insulate(); + $client->request('GET', '/protected_resource'); + + $this->assertRedirect($client->getResponse(), '/login'); + } + + /** + * @dataProvider getConfigs + */ + public function testRoutingErrorIsExposedWhenNotProtected($config) + { + if (strpos(PHP_OS, "WIN") === 0 && version_compare(phpversion(), "5.3.9", "<")) { + $this->markTestSkipped('Test hangs on Windows & PHP due to https://bugs.php.net/bug.php?id=60120 fixed in http://svn.php.net/viewvc?view=revision&revision=318366'); + } + + $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config)); + $client->insulate(); + $client->request('GET', '/unprotected_resource'); + + $this->assertEquals(404, $client->getResponse()->getStatusCode(), (string) $client->getResponse()); + } + + /** + * @dataProvider getConfigs + */ + public function testRoutingErrorIsNotExposedForProtectedResourceWhenLoggedInWithInsufficientRights($config) + { + if (strpos(PHP_OS, "WIN") === 0 && version_compare(phpversion(), "5.3.9", "<")) { + $this->markTestSkipped('Test hangs on Windows & PHP due to https://bugs.php.net/bug.php?id=60120 fixed in http://svn.php.net/viewvc?view=revision&revision=318366'); + } + + $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config)); + $client->insulate(); + + $form = $client->request('GET', '/login')->selectButton('login')->form(); + $form['_username'] = 'johannes'; + $form['_password'] = 'test'; + $client->submit($form); + + $client->request('GET', '/highly_protected_resource'); + + $this->assertNotEquals(404, $client->getResponse()->getStatusCode()); + } + + public function getConfigs() + { + return array(array('config.yml'), array('routes_as_path.yml')); + } + + protected function setUp() + { + parent::setUp(); + + $this->deleteTmpDir('StandardFormLogin'); + } + + protected function tearDown() + { + parent::tearDown(); + + $this->deleteTmpDir('StandardFormLogin'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SwitchUserTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SwitchUserTest.php new file mode 100644 index 0000000..217e27b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SwitchUserTest.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\Bundle\SecurityBundle\Tests\Functional; + +/** + * @group functional + */ +class SwitchUserTest extends WebTestCase +{ + /** + * @dataProvider getTestParameters + */ + public function testSwitchUser($originalUser, $targetUser, $expectedUser, $expectedStatus) + { + $client = $this->createAuthenticatedClient($originalUser); + + $client->request('GET', '/profile?_switch_user=' . $targetUser); + + $this->assertEquals($expectedStatus, $client->getResponse()->getStatusCode()); + $this->assertEquals($expectedUser, $client->getProfile()->getCollector('security')->getUser()); + } + + public function testSwitchedUserCannotSwitchToOther() + { + $client = $this->createAuthenticatedClient('user_can_switch'); + + $client->request('GET', '/profile?_switch_user=user_cannot_switch_1'); + $client->request('GET', '/profile?_switch_user=user_cannot_switch_2'); + + $this->assertEquals(500, $client->getResponse()->getStatusCode()); + $this->assertEquals('user_cannot_switch_1', $client->getProfile()->getCollector('security')->getUser()); + } + + public function testSwitchedUserExit() + { + $client = $this->createAuthenticatedClient('user_can_switch'); + + $client->request('GET', '/profile?_switch_user=user_cannot_switch_1'); + $client->request('GET', '/profile?_switch_user=_exit'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + $this->assertEquals('user_can_switch', $client->getProfile()->getCollector('security')->getUser()); + } + + public function getTestParameters() + { + return array( + 'unauthorized_user_cannot_switch' => array('user_cannot_switch_1', 'user_cannot_switch_1', 'user_cannot_switch_1', 403), + 'authorized_user_can_switch' => array('user_can_switch', 'user_cannot_switch_1', 'user_cannot_switch_1', 200), + 'authorized_user_cannot_switch_to_non_existent' => array('user_can_switch', 'user_does_not_exist', 'user_can_switch', 500), + 'authorized_user_can_switch_to_himself' => array('user_can_switch', 'user_can_switch', 'user_can_switch', 200), + ); + } + + protected function createAuthenticatedClient($username) + { + $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => 'switchuser.yml')); + $client->followRedirects(true); + $client->insulate(); + + $form = $client->request('GET', '/login')->selectButton('login')->form(); + $form['_username'] = $username; + $form['_password'] = 'test'; + $client->submit($form); + + return $client; + } + + protected function setUp() + { + parent::setUp(); + + $this->deleteTmpDir('StandardFormLogin'); + } + + protected function tearDown() + { + parent::tearDown(); + + $this->deleteTmpDir('StandardFormLogin'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/WebTestCase.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/WebTestCase.php new file mode 100644 index 0000000..4440a3e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/WebTestCase.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\Bundle\SecurityBundle\Tests\Functional; + +use Symfony\Bundle\FrameworkBundle\Test\WebTestCase as BaseWebTestCase; +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\HttpKernel\Kernel; + +class WebTestCase extends BaseWebTestCase +{ + static public function assertRedirect($response, $location) + { + self::assertTrue($response->isRedirect(), 'Response is not a redirect, got status code: '.substr($response, 0, 2000)); + self::assertEquals('http://localhost'.$location, $response->headers->get('Location')); + } + + protected function setUp() + { + if (!class_exists('Twig_Environment')) { + $this->markTestSkipped('Twig is not available.'); + } + + parent::setUp(); + } + + protected function deleteTmpDir($testCase) + { + if (!file_exists($dir = sys_get_temp_dir().'/'.Kernel::VERSION.'/'.$testCase)) { + return; + } + + $fs = new Filesystem(); + $fs->remove($dir); + } + + static protected function getKernelClass() + { + require_once __DIR__.'/app/AppKernel.php'; + + return 'Symfony\Bundle\SecurityBundle\Tests\Functional\AppKernel'; + } + + static protected function createKernel(array $options = array()) + { + $class = self::getKernelClass(); + + if (!isset($options['test_case'])) { + throw new \InvalidArgumentException('The option "test_case" must be set.'); + } + + return new $class( + $options['test_case'], + isset($options['root_config']) ? $options['root_config'] : 'config.yml', + isset($options['environment']) ? $options['environment'] : 'securitybundletest' . strtolower($options['test_case']), + isset($options['debug']) ? $options['debug'] : true + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AppKernel.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AppKernel.php new file mode 100644 index 0000000..dbe618f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AppKernel.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\Bundle\SecurityBundle\Tests\Functional; + +// get the autoload file +$dir = __DIR__; +$lastDir = null; +while ($dir !== $lastDir) { + $lastDir = $dir; + + if (is_file($dir.'/autoload.php')) { + require_once $dir.'/autoload.php'; + break; + } + + if (is_file($dir.'/autoload.php.dist')) { + require_once $dir.'/autoload.php.dist'; + break; + } + + $dir = dirname($dir); +} + +use Symfony\Component\Config\Loader\LoaderInterface; +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\HttpKernel\Kernel; + +/** + * App Test Kernel for functional tests. + * + * @author Johannes M. Schmitt + */ +class AppKernel extends Kernel +{ + private $testCase; + private $rootConfig; + + public function __construct($testCase, $rootConfig, $environment, $debug) + { + if (!is_dir(__DIR__.'/'.$testCase)) { + throw new \InvalidArgumentException(sprintf('The test case "%s" does not exist.', $testCase)); + } + $this->testCase = $testCase; + + $fs = new Filesystem(); + if (!$fs->isAbsolutePath($rootConfig) && !is_file($rootConfig = __DIR__.'/'.$testCase.'/'.$rootConfig)) { + throw new \InvalidArgumentException(sprintf('The root config "%s" does not exist.', $rootConfig)); + } + $this->rootConfig = $rootConfig; + + parent::__construct($environment, $debug); + } + + public function registerBundles() + { + if (!is_file($filename = $this->getRootDir().'/'.$this->testCase.'/bundles.php')) { + throw new \RuntimeException(sprintf('The bundles file "%s" does not exist.', $filename)); + } + + return include $filename; + } + + public function init() + { + } + + public function getRootDir() + { + return __DIR__; + } + + public function getCacheDir() + { + return sys_get_temp_dir().'/'.Kernel::VERSION.'/'.$this->testCase.'/cache/'.$this->environment; + } + + public function getLogDir() + { + return sys_get_temp_dir().'/'.Kernel::VERSION.'/'.$this->testCase.'/logs'; + } + + public function registerContainerConfiguration(LoaderInterface $loader) + { + $loader->load($this->rootConfig); + } + + public function serialize() + { + return serialize(array($this->testCase, $this->rootConfig, $this->getEnvironment(), $this->isDebug())); + } + + public function unserialize($str) + { + call_user_func_array(array($this, '__construct'), unserialize($str)); + } + + protected function getKernelParameters() + { + $parameters = parent::getKernelParameters(); + $parameters['kernel.test_case'] = $this->testCase; + + return $parameters; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/bundles.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/bundles.php new file mode 100644 index 0000000..cee883f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/bundles.php @@ -0,0 +1,8 @@ + + + + + {% block title %}Welcome!{% endblock %} + {% block stylesheets %}{% endblock %} + + + + {% block body %}{% endblock %} + {% block javascripts %}{% endblock %} + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/bundles.php b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/bundles.php new file mode 100644 index 0000000..e4bbc08 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/bundles.php @@ -0,0 +1,13 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\SecurityBundle\Twig\Extension; + +use Symfony\Bundle\SecurityBundle\Templating\Helper\LogoutUrlHelper; + +/** + * LogoutUrlHelper provides generator functions for the logout URL to Twig. + * + * @author Jeremy Mikola + */ +class LogoutUrlExtension extends \Twig_Extension +{ + private $helper; + + /** + * Constructor. + * + * @param LogoutUrlHelper $helper + */ + public function __construct(LogoutUrlHelper $helper) + { + $this->helper = $helper; + } + + /** + * @see Twig_Extension::getFunctions() + */ + public function getFunctions() + { + return array( + 'logout_url' => new \Twig_Function_Method($this, 'getLogoutUrl'), + 'logout_path' => new \Twig_Function_Method($this, 'getLogoutPath'), + ); + } + + /** + * Generate the relative logout URL for the firewall. + * + * @param string $key The firewall key + * @return string The relative logout URL + */ + public function getLogoutPath($key) + { + return $this->helper->getLogoutPath($key); + } + + /** + * Generate the absolute logout URL for the firewall. + * + * @param string $key The firewall key + * @return string The absolute logout URL + */ + public function getLogoutUrl($key) + { + return $this->helper->getLogoutUrl($key); + } + + /** + * @see Twig_ExtensionInterface::getName() + */ + public function getName() + { + return 'logout_url'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/composer.json b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/composer.json new file mode 100644 index 0000000..3530d67 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/composer.json @@ -0,0 +1,31 @@ +{ + "name": "symfony/security-bundle", + "type": "symfony-bundle", + "description": "Symfony SecurityBundle", + "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/security": "self.version" + }, + "autoload": { + "psr-0": { "Symfony\\Bundle\\SecurityBundle": "" } + }, + "target-dir": "Symfony/Bundle/SecurityBundle", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/CHANGELOG.md b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/CHANGELOG.md new file mode 100644 index 0000000..0da6ea2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/CHANGELOG.md @@ -0,0 +1,10 @@ +CHANGELOG +========= + +2.1.0 +----- + + * added contextual escaping based on the template file name (disabled if you explicitly pass an autoescape option) + * added a command that extracts translation messages from templates + * added the real template name when an error occurs in a Twig template + * added the twig:lint command that will validate a Twig template syntax. diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/CacheWarmer/TemplateCacheCacheWarmer.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/CacheWarmer/TemplateCacheCacheWarmer.php new file mode 100644 index 0000000..47225fb --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/CacheWarmer/TemplateCacheCacheWarmer.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\Bundle\TwigBundle\CacheWarmer; + +use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Bundle\FrameworkBundle\CacheWarmer\TemplateFinderInterface; + +/** + * Generates the Twig cache for all templates. + * + * This warmer must be registered after TemplatePathsCacheWarmer, + * as the Twig loader will need the cache generated by it. + * + * @author Fabien Potencier + */ +class TemplateCacheCacheWarmer implements CacheWarmerInterface +{ + protected $container; + protected $warmer; + + /** + * Constructor. + * + * @param ContainerInterface $container The dependency injection container + * @param TemplateFinderInterface $finder The template paths cache warmer + */ + public function __construct(ContainerInterface $container, TemplateFinderInterface $finder) + { + // We don't inject the Twig environment directly as it depends on the + // template locator (via the loader) which might be a cached one. + // The cached template locator is available once the TemplatePathsCacheWarmer + // has been warmed up + $this->container = $container; + $this->finder = $finder; + } + + /** + * Warms up the cache. + * + * @param string $cacheDir The cache directory + */ + public function warmUp($cacheDir) + { + $twig = $this->container->get('twig'); + + foreach ($this->finder->findAllTemplates() as $template) { + if ('twig' !== $template->get('engine')) { + continue; + } + + try { + $twig->loadTemplate($template); + } catch (\Twig_Error $e) { + // problem during compilation, give up + } + } + } + + /** + * Checks whether this warmer is optional or not. + * + * @return Boolean always true + */ + public function isOptional() + { + return true; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Command/LintCommand.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Command/LintCommand.php new file mode 100644 index 0000000..d898f54 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Command/LintCommand.php @@ -0,0 +1,139 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\TwigBundle\Command; + +use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Finder\Finder; + +/** + * Command that will validate your template syntax and output encountered errors. + * + * @author Marc Weistroff + */ +class LintCommand extends ContainerAwareCommand +{ + protected function configure() + { + $this + ->setName('twig:lint') + ->setDescription('Lints a template and outputs eventual errors') + ->addArgument('filename') + ->setHelp(<<%command.name% command lints a template and outputs to stdout +the first encountered syntax error. + +php %command.full_name% filename + +The command gets the contents of filename and validates its syntax. + +php %command.full_name% dirname + +The command finds all twig templates in dirname and validates the syntax +of each Twig template. + +php %command.full_name% @AcmeMyBundle + +The command finds all twig templates in the AcmeMyBundle bundle and validates +the syntax of each Twig template. + +cat filename | php %command.full_name% + +The command gets the template contents from stdin and validates its syntax. +EOF + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $twig = $this->getContainer()->get('twig'); + $template = null; + $filename = $input->getArgument('filename'); + + if (!$filename) { + if (0 !== ftell(STDIN)) { + throw new \RuntimeException("Please provide a filename or pipe template content to stdin."); + } + + while (!feof(STDIN)) { + $template .= fread(STDIN, 1024); + } + + return $twig->parse($twig->tokenize($template)); + } + + if (0 !== strpos($filename, '@') && !is_readable($filename)) { + throw new \RuntimeException("File or directory '%s' is not readable"); + } + + $files = array(); + if (is_file($filename)) { + $files = array($filename); + } elseif (is_dir($filename)) { + $files = Finder::create()->files()->in($filename)->name('*.twig'); + } else { + $dir = $this->getApplication()->getKernel()->locateResource($filename); + $files = Finder::create()->files()->in($dir)->name('*.twig'); + } + + $error = false; + foreach ($files as $file) { + try { + $twig->parse($twig->tokenize(file_get_contents($file), (string) $file)); + $output->writeln(sprintf("OK in %s", $file)); + } catch (\Twig_Error $e) { + $this->renderException($output, $file, $e); + $error = true; + } + } + + return $error ? 1 : 0; + } + + protected function renderException(OutputInterface $output, $file, \Twig_Error $exception) + { + $line = $exception->getTemplateLine(); + $lines = $this->getContext($file, $line); + + $output->writeln(sprintf("KO in %s (line %s)", $file, $line)); + foreach ($lines as $no => $code) { + $output->writeln(sprintf( + "%s %-6s %s", + $no == $line ? '>>' : ' ', + $no, + $code + )); + if ($no == $line) { + $output->writeln(sprintf('>> %s ', $exception->getRawMessage())); + } + } + } + + protected function getContext($file, $line, $context = 3) + { + $fileContent = file_get_contents($file); + $lines = explode("\n", $fileContent); + + $position = max(0, $line - $context); + $max = min(count($lines), $line - 1 + $context); + + $result = array(); + while ($position < $max) { + $result[$position + 1] = $lines[$position]; + $position++; + } + + return $result; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Controller/ExceptionController.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Controller/ExceptionController.php new file mode 100644 index 0000000..7601be9 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Controller/ExceptionController.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\Bundle\TwigBundle\Controller; + +use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface; +use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference; +use Symfony\Component\DependencyInjection\ContainerAware; +use Symfony\Component\HttpKernel\Exception\FlattenException; +use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; +use Symfony\Component\HttpFoundation\Response; + +/** + * ExceptionController. + * + * @author Fabien Potencier + */ +class ExceptionController extends ContainerAware +{ + /** + * Converts an Exception to a Response. + * + * @param FlattenException $exception A FlattenException instance + * @param DebugLoggerInterface $logger A DebugLoggerInterface instance + * @param string $format The format to use for rendering (html, xml, ...) + * + * @return Response + * + * @throws \InvalidArgumentException When the exception template does not exist + */ + public function showAction(FlattenException $exception, DebugLoggerInterface $logger = null, $format = 'html') + { + $this->container->get('request')->setRequestFormat($format); + + $currentContent = $this->getAndCleanOutputBuffering(); + + $templating = $this->container->get('templating'); + $code = $exception->getStatusCode(); + + $response = $templating->renderResponse( + $this->findTemplate($templating, $format, $code, $this->container->get('kernel')->isDebug()), + array( + 'status_code' => $code, + 'status_text' => isset(Response::$statusTexts[$code]) ? Response::$statusTexts[$code] : '', + 'exception' => $exception, + 'logger' => $logger, + 'currentContent' => $currentContent, + ) + ); + + $response->setStatusCode($code); + $response->headers->replace($exception->getHeaders()); + + return $response; + } + + /** + * @return string + */ + protected function getAndCleanOutputBuffering() + { + // ob_get_level() never returns 0 on some Windows configurations, so if + // the level is the same two times in a row, the loop should be stopped. + $previousObLevel = null; + $startObLevel = $this->container->get('request')->headers->get('X-Php-Ob-Level', -1); + + $currentContent = ''; + + while (($obLevel = ob_get_level()) > $startObLevel && $obLevel !== $previousObLevel) { + $previousObLevel = $obLevel; + $currentContent .= ob_get_clean(); + } + + return $currentContent; + } + + /** + * @param EngineInterface $templating + * @param string $format + * @param integer $code An HTTP response status code + * @param Boolean $debug + * + * @return TemplateReference + */ + protected function findTemplate($templating, $format, $code, $debug) + { + $name = $debug ? 'exception' : 'error'; + if ($debug && 'html' == $format) { + $name = 'exception_full'; + } + + // when not in debug, try to find a template for the specific HTTP status code and format + if (!$debug) { + $template = new TemplateReference('TwigBundle', 'Exception', $name.$code, $format, 'twig'); + if ($templating->exists($template)) { + return $template; + } + } + + // try to find a template for the given format + $template = new TemplateReference('TwigBundle', 'Exception', $name, $format, 'twig'); + if ($templating->exists($template)) { + return $template; + } + + // default to a generic HTML exception + $this->container->get('request')->setRequestFormat('html'); + + return new TemplateReference('TwigBundle', 'Exception', $name, 'html', 'twig'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Debug/TimedTwigEngine.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Debug/TimedTwigEngine.php new file mode 100644 index 0000000..e428401 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Debug/TimedTwigEngine.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\Bundle\TwigBundle\Debug; + +use Symfony\Bundle\TwigBundle\TwigEngine; +use Symfony\Bundle\FrameworkBundle\Templating\GlobalVariables; +use Symfony\Component\Templating\TemplateNameParserInterface; +use Symfony\Component\HttpKernel\Debug\Stopwatch; +use Symfony\Component\Config\FileLocatorInterface; + +/** + * Times the time spent to render a template. + * + * @author Fabien Potencier + */ +class TimedTwigEngine extends TwigEngine +{ + protected $stopwatch; + + /** + * Constructor. + * + * @param \Twig_Environment $environment A \Twig_Environment instance + * @param TemplateNameParserInterface $parser A TemplateNameParserInterface instance + * @param FileLocatorInterface $locator A FileLocatorInterface instance + * @param Stopwatch $stopwatch A Stopwatch instance + * @param GlobalVariables $globals A GlobalVariables instance + */ + public function __construct(\Twig_Environment $environment, TemplateNameParserInterface $parser, FileLocatorInterface $locator, Stopwatch $stopwatch, GlobalVariables $globals = null) + { + parent::__construct($environment, $parser, $locator, $globals); + + $this->stopwatch = $stopwatch; + } + + /** + * {@inheritdoc} + */ + public function render($name, array $parameters = array()) + { + $e = $this->stopwatch->start(sprintf('template.twig (%s)', $name), 'template'); + + $ret = parent::render($name, $parameters); + + $e->stop(); + + return $ret; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExceptionListenerPass.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExceptionListenerPass.php new file mode 100644 index 0000000..18d98b3 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExceptionListenerPass.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\Bundle\TwigBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Registers the Twig exception listener if Twig is registered as a templating engine. + * + * @author Fabien Potencier + */ +class ExceptionListenerPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (false === $container->hasDefinition('twig')) { + return; + } + + // register the exception controller only if Twig is enabled + $engines = $container->getParameter('templating.engines'); + if (!in_array('twig', $engines)) { + $container->removeDefinition('twig.exception_listener'); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TwigEnvironmentPass.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TwigEnvironmentPass.php new file mode 100644 index 0000000..785c597 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TwigEnvironmentPass.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\Bundle\TwigBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Adds tagged twig.extension services to twig service + * + * @author Fabien Potencier + */ +class TwigEnvironmentPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (false === $container->hasDefinition('twig')) { + return; + } + + $definition = $container->getDefinition('twig'); + + // Extensions must always be registered before everything else. + // For instance, global variable definitions must be registered + // afterward. If not, the globals from the extensions will never + // be registered. + $calls = $definition->getMethodCalls(); + $definition->setMethodCalls(array()); + foreach ($container->findTaggedServiceIds('twig.extension') as $id => $attributes) { + $definition->addMethodCall('addExtension', array(new Reference($id))); + } + $definition->setMethodCalls(array_merge($definition->getMethodCalls(), $calls)); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php new file mode 100644 index 0000000..ff2a9ef --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.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\Bundle\TwigBundle\DependencyInjection; + +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; + +/** + * TwigExtension configuration structure. + * + * @author Jeremy Mikola + */ +class Configuration implements ConfigurationInterface +{ + /** + * Generates the configuration tree builder. + * + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder + */ + public function getConfigTreeBuilder() + { + $treeBuilder = new TreeBuilder(); + $rootNode = $treeBuilder->root('twig'); + + $rootNode + ->children() + ->scalarNode('exception_controller')->defaultValue('Symfony\\Bundle\\TwigBundle\\Controller\\ExceptionController::showAction')->end() + ->end() + ; + + $this->addFormSection($rootNode); + $this->addGlobalsSection($rootNode); + $this->addTwigOptions($rootNode); + + return $treeBuilder; + } + + private function addFormSection(ArrayNodeDefinition $rootNode) + { + $rootNode + ->children() + ->arrayNode('form') + ->addDefaultsIfNotSet() + ->fixXmlConfig('resource') + ->children() + ->arrayNode('resources') + ->addDefaultChildrenIfNoneSet() + ->prototype('scalar')->defaultValue('form_div_layout.html.twig')->end() + ->example(array('MyBundle::form.html.twig')) + ->validate() + ->ifTrue(function($v) { return !in_array('form_div_layout.html.twig', $v); }) + ->then(function($v){ + return array_merge(array('form_div_layout.html.twig'), $v); + }) + ->end() + ->end() + ->end() + ->end() + ->end() + ; + } + + private function addGlobalsSection(ArrayNodeDefinition $rootNode) + { + $rootNode + ->fixXmlConfig('global') + ->children() + ->arrayNode('globals') + ->useAttributeAsKey('key') + ->example(array('foo' => '"@bar"', 'pi' => 3.14)) + ->prototype('array') + ->beforeNormalization() + ->ifTrue(function($v){ return is_string($v) && 0 === strpos($v, '@'); }) + ->then(function($v){ return array('id' => substr($v, 1), 'type' => 'service'); }) + ->end() + ->beforeNormalization() + ->ifTrue(function($v){ + if (is_array($v)) { + $keys = array_keys($v); + sort($keys); + + return $keys !== array('id', 'type') && $keys !== array('value'); + } + + return true; + }) + ->then(function($v){ return array('value' => $v); }) + ->end() + ->children() + ->scalarNode('id')->end() + ->scalarNode('type') + ->validate() + ->ifNotInArray(array('service')) + ->thenInvalid('The %s type is not supported') + ->end() + ->end() + ->variableNode('value')->end() + ->end() + ->end() + ->end() + ->end() + ; + } + + private function addTwigOptions(ArrayNodeDefinition $rootNode) + { + $rootNode + ->children() + ->scalarNode('autoescape')->end() + ->scalarNode('base_template_class')->example('Twig_Template')->end() + ->scalarNode('cache')->defaultValue('%kernel.cache_dir%/twig')->end() + ->scalarNode('charset')->defaultValue('%kernel.charset%')->end() + ->scalarNode('debug')->defaultValue('%kernel.debug%')->end() + ->scalarNode('strict_variables')->end() + ->scalarNode('auto_reload')->end() + ->scalarNode('optimizations')->end() + ->end() + ; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php new file mode 100644 index 0000000..f9a7617 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.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\Bundle\TwigBundle\DependencyInjection; + +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\HttpKernel\DependencyInjection\Extension; + +/** + * TwigExtension. + * + * @author Fabien Potencier + * @author Jeremy Mikola + */ +class TwigExtension extends Extension +{ + /** + * Responds to the twig configuration parameter. + * + * @param array $configs + * @param ContainerBuilder $container + */ + public function load(array $configs, ContainerBuilder $container) + { + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('twig.xml'); + + foreach ($configs as &$config) { + if (isset($config['globals'])) { + foreach ($config['globals'] as $name => $value) { + if (is_array($value) && isset($value['key'])) { + $config['globals'][$name] = array( + 'key' => $name, + 'value' => $config['globals'][$name] + ); + } + } + } + } + + $configuration = $this->getConfiguration($configs, $container); + + $config = $this->processConfiguration($configuration, $configs); + + $container->setParameter('twig.exception_listener.controller', $config['exception_controller']); + + $container->setParameter('twig.form.resources', $config['form']['resources']); + + $reflClass = new \ReflectionClass('Symfony\Bridge\Twig\Extension\FormExtension'); + $container->getDefinition('twig.loader')->addMethodCall('addPath', array(dirname(dirname($reflClass->getFileName())).'/Resources/views/Form')); + + if (!empty($config['globals'])) { + $def = $container->getDefinition('twig'); + foreach ($config['globals'] as $key => $global) { + if (isset($global['type']) && 'service' === $global['type']) { + $def->addMethodCall('addGlobal', array($key, new Reference($global['id']))); + } else { + $def->addMethodCall('addGlobal', array($key, $global['value'])); + } + } + } + + unset( + $config['form'], + $config['globals'], + $config['extensions'] + ); + + $container->setParameter('twig.options', $config); + + if ($container->getParameter('kernel.debug')) { + $loader->load('debug.xml'); + + $container->setDefinition('templating.engine.twig', $container->findDefinition('debug.templating.engine.twig')); + $container->setAlias('debug.templating.engine.twig', 'templating.engine.twig'); + } + + if (!isset($config['autoescape'])) { + $container->findDefinition('templating.engine.twig')->addMethodCall('setDefaultEscapingStrategy', array(array(new Reference('templating.engine.twig'), 'guessDefaultEscapingStrategy'))); + } + + $this->addClassesToCompile(array( + 'Twig_Environment', + 'Twig_ExtensionInterface', + 'Twig_Extension', + 'Twig_Extension_Core', + 'Twig_Extension_Escaper', + 'Twig_Extension_Optimizer', + 'Twig_LoaderInterface', + 'Twig_Markup', + 'Twig_TemplateInterface', + 'Twig_Template', + )); + } + + /** + * Returns the base path for the XSD files. + * + * @return string The XSD base path + */ + public function getXsdValidationBasePath() + { + return __DIR__.'/../Resources/config/schema'; + } + + public function getNamespace() + { + return 'http://symfony.com/schema/dic/twig'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Extension/ActionsExtension.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Extension/ActionsExtension.php new file mode 100644 index 0000000..017bfb4 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Extension/ActionsExtension.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\Bundle\TwigBundle\Extension; + +use Symfony\Bundle\TwigBundle\TokenParser\RenderTokenParser; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Twig extension for Symfony actions helper + * + * @author Fabien Potencier + */ +class ActionsExtension extends \Twig_Extension +{ + private $container; + + /** + * Constructor. + * + * @param ContainerInterface $container The service container + */ + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + /** + * Returns the Response content for a given controller or URI. + * + * @param string $controller A controller name to execute (a string like BlogBundle:Post:index), or a relative URI + * @param array $attributes An array of request attributes + * @param array $options An array of options + * + * @see Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver::render() + */ + public function renderAction($controller, array $attributes = array(), array $options = array()) + { + return $this->container->get('templating.helper.actions')->render($controller, $attributes, $options); + } + + /** + * Returns the token parser instance to add to the existing list. + * + * @return array An array of Twig_TokenParser instances + */ + public function getTokenParsers() + { + return array( + // {% render 'BlogBundle:Post:list' with { 'limit': 2 }, { 'alt': 'BlogBundle:Post:error' } %} + new RenderTokenParser(), + ); + } + + public function getName() + { + return 'actions'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Extension/AssetsExtension.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Extension/AssetsExtension.php new file mode 100644 index 0000000..29bb2ec --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Extension/AssetsExtension.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\Bundle\TwigBundle\Extension; + +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Twig extension for Symfony assets helper + * + * @author Fabien Potencier + */ +class AssetsExtension extends \Twig_Extension +{ + private $container; + + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + /** + * Returns a list of functions to add to the existing list. + * + * @return array An array of functions + */ + public function getFunctions() + { + return array( + 'asset' => new \Twig_Function_Method($this, 'getAssetUrl'), + 'assets_version' => new \Twig_Function_Method($this, 'getAssetsVersion'), + ); + } + + /** + * Returns the public path of an asset. + * + * Absolute paths (i.e. http://...) are returned unmodified. + * + * @param string $path A public path + * @param string $packageName The name of the asset package to use + * + * @return string A public path which takes into account the base path and URL path + */ + public function getAssetUrl($path, $packageName = null) + { + return $this->container->get('templating.helper.assets')->getUrl($path, $packageName); + } + + /** + * Returns the version of the assets in a package. + * + * @param string $packageName + * + * @return int + */ + public function getAssetsVersion($packageName = null) + { + return $this->container->get('templating.helper.assets')->getVersion($packageName); + } + + /** + * Returns the name of the extension. + * + * @return string The extension name + */ + public function getName() + { + return 'assets'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Extension/CodeExtension.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Extension/CodeExtension.php new file mode 100644 index 0000000..d3f16ae --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Extension/CodeExtension.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\Bundle\TwigBundle\Extension; + +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Twig extension for Symfony code helper + * + * + * @author Fabien Potencier + */ +class CodeExtension extends \Twig_Extension +{ + private $container; + + /** + * Constructor of Twig Extension to provide functions for code formatting + * + * @param ContainerInterface $container A ContainerInterface instance + */ + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + /** + * {@inheritdoc} + */ + public function getFilters() + { + return array( + 'abbr_class' => new \Twig_Filter_Method($this, 'abbrClass', array('is_safe' => array('html'))), + 'abbr_method' => new \Twig_Filter_Method($this, 'abbrMethod', array('is_safe' => array('html'))), + 'format_args' => new \Twig_Filter_Method($this, 'formatArgs', array('is_safe' => array('html'))), + 'format_args_as_text' => new \Twig_Filter_Method($this, 'formatArgsAsText'), + 'file_excerpt' => new \Twig_Filter_Method($this, 'fileExcerpt', array('is_safe' => array('html'))), + 'format_file' => new \Twig_Filter_Method($this, 'formatFile', array('is_safe' => array('html'))), + 'format_file_from_text' => new \Twig_Filter_Method($this, 'formatFileFromText', array('is_safe' => array('html'))), + 'file_link' => new \Twig_Filter_Method($this, 'getFileLink', array('is_safe' => array('html'))), + ); + } + + public function abbrClass($class) + { + return $this->container->get('templating.helper.code')->abbrClass($class); + } + + public function abbrMethod($method) + { + return $this->container->get('templating.helper.code')->abbrMethod($method); + } + + public function formatArgs($args) + { + return $this->container->get('templating.helper.code')->formatArgs($args); + } + + public function formatArgsAsText($args) + { + return $this->container->get('templating.helper.code')->formatArgsAsText($args); + } + + public function fileExcerpt($file, $line) + { + return $this->container->get('templating.helper.code')->fileExcerpt($file, $line); + } + + public function formatFile($file, $line, $text = null) + { + return $this->container->get('templating.helper.code')->formatFile($file, $line, $text); + } + + public function getFileLink($file, $line) + { + return $this->container->get('templating.helper.code')->getFileLink($file, $line); + } + + public function formatFileFromText($text) + { + return $this->container->get('templating.helper.code')->formatFileFromText($text); + } + + public function getName() + { + return 'code'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/LICENSE b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/LICENSE new file mode 100644 index 0000000..cdffe7a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 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/symfony/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php new file mode 100644 index 0000000..a79d35c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.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\Bundle\TwigBundle\Loader; + +use Symfony\Component\Templating\TemplateNameParserInterface; +use Symfony\Component\Config\FileLocatorInterface; + +/** + * FilesystemLoader extends the default Twig filesystem loader + * to work with the Symfony2 paths. + * + * @author Fabien Potencier + */ +class FilesystemLoader extends \Twig_Loader_Filesystem +{ + protected $locator; + protected $parser; + + /** + * Constructor. + * + * @param FileLocatorInterface $locator A FileLocatorInterface instance + * @param TemplateNameParserInterface $parser A TemplateNameParserInterface instance + */ + public function __construct(FileLocatorInterface $locator, TemplateNameParserInterface $parser) + { + parent::__construct(array()); + + $this->locator = $locator; + $this->parser = $parser; + $this->cache = array(); + } + + /** + * Returns the path to the template file. + * + * The file locator is used to locate the template when the naming convention + * is the symfony one (i.e. the name can be parsed). + * Otherwise the template is located using the locator from the twig library. + * + * @param string|TemplateReferenceInterface $template The template + * + * @return string The path to the template file + * + * @throws \Twig_Error_Loader if the template could not be found + */ + protected function findTemplate($template) + { + $logicalName = (string) $template; + + if (isset($this->cache[$logicalName])) { + return $this->cache[$logicalName]; + } + + $file = null; + $previous = null; + try { + $template = $this->parser->parse($template); + try { + $file = $this->locator->locate($template); + } catch (\InvalidArgumentException $e) { + $previous = $e; + } + } catch (\Exception $e) { + try { + $file = parent::findTemplate($template); + } catch (\Twig_Error_Loader $e) { + $previous = $e; + } + } + + if (false === $file || null === $file) { + throw new \Twig_Error_Loader(sprintf('Unable to find template "%s".', $logicalName), -1, null, $previous); + } + + return $this->cache[$logicalName] = $file; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Node/RenderNode.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Node/RenderNode.php new file mode 100644 index 0000000..3c40f3c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Node/RenderNode.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\Bundle\TwigBundle\Node; + +/** + * Represents a render node. + * + * @author Fabien Potencier + */ +class RenderNode extends \Twig_Node +{ + public function __construct(\Twig_Node_Expression $expr, \Twig_Node_Expression $attributes, \Twig_Node_Expression $options, $lineno, $tag = null) + { + parent::__construct(array('expr' => $expr, 'attributes' => $attributes, 'options' => $options), array(), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param \Twig_Compiler $compiler A Twig_Compiler instance + */ + public function compile(\Twig_Compiler $compiler) + { + $compiler + ->addDebugInfo($this) + ->write("echo \$this->env->getExtension('actions')->renderAction(") + ->subcompile($this->getNode('expr')) + ->raw(', ') + ->subcompile($this->getNode('attributes')) + ->raw(', ') + ->subcompile($this->getNode('options')) + ->raw(");\n") + ; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/config/debug.xml b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/config/debug.xml new file mode 100644 index 0000000..2857e18 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/config/debug.xml @@ -0,0 +1,24 @@ + + + + + + Symfony\Bundle\TwigBundle\Debug\TimedTwigEngine + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd new file mode 100644 index 0000000..810e24f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml new file mode 100644 index 0000000..3d4a697 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml @@ -0,0 +1,94 @@ + + + + + + Twig_Environment + Symfony\Bundle\TwigBundle\Loader\FilesystemLoader + Symfony\Bundle\TwigBundle\TwigEngine + Symfony\Bundle\TwigBundle\CacheWarmer\TemplateCacheCacheWarmer + Symfony\Bridge\Twig\Extension\TranslationExtension + Symfony\Bundle\TwigBundle\Extension\AssetsExtension + Symfony\Bundle\TwigBundle\Extension\ActionsExtension + Symfony\Bundle\TwigBundle\Extension\CodeExtension + Symfony\Bridge\Twig\Extension\RoutingExtension + Symfony\Bridge\Twig\Extension\YamlExtension + Symfony\Bridge\Twig\Extension\FormExtension + Symfony\Bridge\Twig\Translation\TwigExtractor + Symfony\Component\HttpKernel\EventListener\ExceptionListener + + + + + + %twig.options% + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %twig.form.resources% + + + + + + + + + + + %twig.exception_listener.controller% + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.atom.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.atom.twig new file mode 100644 index 0000000..9c1ab3e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.atom.twig @@ -0,0 +1 @@ +{% include 'TwigBundle:Exception:error.xml.twig' with { 'exception': exception } %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.css.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.css.twig new file mode 100644 index 0000000..d8a9369 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.css.twig @@ -0,0 +1,4 @@ +/* +{{ status_code }} {{ status_text }} + +*/ diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.html.twig new file mode 100644 index 0000000..22d0c3a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.html.twig @@ -0,0 +1,17 @@ + + + + + An Error Occurred: {{ status_text }} + + +

    Oops! An Error Occurred

    +

    The server returned a "{{ status_code }} {{ status_text }}".

    + +
    + Something is broken. Please e-mail us at [email] and let us know + what you were doing when this error occurred. We will fix it as soon + as possible. Sorry for any inconvenience caused. +
    + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.js.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.js.twig new file mode 100644 index 0000000..d8a9369 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.js.twig @@ -0,0 +1,4 @@ +/* +{{ status_code }} {{ status_text }} + +*/ diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.json.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.json.twig new file mode 100644 index 0000000..fc19fd8 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.json.twig @@ -0,0 +1 @@ +{{ { 'error': { 'code': status_code, 'message': status_text } }|json_encode|raw }} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.rdf.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.rdf.twig new file mode 100644 index 0000000..9c1ab3e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.rdf.twig @@ -0,0 +1 @@ +{% include 'TwigBundle:Exception:error.xml.twig' with { 'exception': exception } %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.txt.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.txt.twig new file mode 100644 index 0000000..b621b08 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.txt.twig @@ -0,0 +1,8 @@ +Oops! An Error Occurred +======================= + +The server returned a "{{ status_code }} {{ status_text }}". + +Please e-mail us at [email] and let us know what you were doing when this +error occurred. We will fix it as soon as possible. Sorry for any +inconvenience caused. diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.xml.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.xml.twig new file mode 100644 index 0000000..5ea8f56 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.xml.twig @@ -0,0 +1,3 @@ + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.atom.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.atom.twig new file mode 100644 index 0000000..989740f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.atom.twig @@ -0,0 +1 @@ +{% include 'TwigBundle:Exception:exception.xml.twig' with { 'exception': exception } %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.css.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.css.twig new file mode 100644 index 0000000..870d4a0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.css.twig @@ -0,0 +1,3 @@ +/* +{% include 'TwigBundle:Exception:exception.txt.twig' with { 'exception': exception } %} +*/ diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.html.twig new file mode 100644 index 0000000..a3d953a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.html.twig @@ -0,0 +1,129 @@ +
    + +
    +
    +
    + Exception detected! +
    +
    + +
    + +
    + +

    + {{ exception.message|nl2br|format_file_from_text }} +

    + +
    + {{ status_code }} {{ status_text }} - {{ exception.class|abbr_class }} +
    + + {% set previous_count = exception.allPrevious|length %} + {% if previous_count %} +
    {{ previous_count }} linked Exception{{ previous_count > 1 ? 's' : '' }}: +
      + {% for i, previous in exception.allPrevious %} +
    • + {{ previous.class|abbr_class }} » +
    • + {% endfor %} +
    +
    + {% endif %} + +
    + +
    + +
    +
    +
    + + {% for position, e in exception.toarray %} + {% include 'TwigBundle:Exception:traces.html.twig' with { 'exception': e, 'position': position, 'count': previous_count } only %} + {% endfor %} + + {% if logger %} +
    +
    + {% spaceless %} +

    + Logs  + + + - + +

    + {% endspaceless %} + + {% if logger.counterrors %} +
    + + {{ logger.counterrors }} error{{ logger.counterrors > 1 ? 's' : ''}} + +
    + {% endif %} + +
    + +
    + {% include 'TwigBundle:Exception:logs.html.twig' with { 'logs': logger.logs } only %} +
    + +
    + {% endif %} + + {% if currentContent %} +
    + {% spaceless %} +

    + Content of the Output  + + + + + +

    + {% endspaceless %} + + + +
    +
    + {% endif %} + +
    + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.js.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.js.twig new file mode 100644 index 0000000..870d4a0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.js.twig @@ -0,0 +1,3 @@ +/* +{% include 'TwigBundle:Exception:exception.txt.twig' with { 'exception': exception } %} +*/ diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.json.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.json.twig new file mode 100644 index 0000000..042e082 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.json.twig @@ -0,0 +1 @@ +{{ exception.toarray|json_encode|raw }} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.rdf.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.rdf.twig new file mode 100644 index 0000000..989740f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.rdf.twig @@ -0,0 +1 @@ +{% include 'TwigBundle:Exception:exception.xml.twig' with { 'exception': exception } %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.txt.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.txt.twig new file mode 100644 index 0000000..3c7a912 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.txt.twig @@ -0,0 +1,7 @@ +[exception] {{ status_code ~ ' | ' ~ status_text ~ ' | ' ~ exception.class }} +[message] {{ exception.message }} +{% for i, e in exception.toarray %} +[{{ i + 1 }}] {{ e.class }}: {{ e.message }} +{% include 'TwigBundle:Exception:traces.txt.twig' with { 'exception': e } only %} + +{% endfor %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.xml.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.xml.twig new file mode 100644 index 0000000..fa99d44 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.xml.twig @@ -0,0 +1,9 @@ + + + +{% for e in exception.toarray %} + +{% include 'TwigBundle:Exception:traces.xml.twig' with { 'exception': e } only %} + +{% endfor %} + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception_full.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception_full.html.twig new file mode 100644 index 0000000..78a07c0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception_full.html.twig @@ -0,0 +1,9 @@ +{% extends 'TwigBundle::layout.html.twig' %} + +{% block title %} + {{ exception.message }} ({{ status_code }} {{ status_text }}) +{% endblock %} + +{% block body %} + {% include 'TwigBundle:Exception:exception.html.twig' %} +{% endblock %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/logs.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/logs.html.twig new file mode 100644 index 0000000..88a3528 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/logs.html.twig @@ -0,0 +1,7 @@ +
      + {% for log in logs %} + + {{ log.message }} + + {% endfor %} +
    diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/trace.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/trace.html.twig new file mode 100644 index 0000000..cc2e0dd --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/trace.html.twig @@ -0,0 +1,22 @@ +{% if trace.function %} + at + + {{ trace.short_class }} + {{ trace.type ~ trace.function }} + + ({{ trace.args|format_args }}) +{% endif %} + +{% if trace.file is defined and trace.file and trace.line is defined and trace.line %} + {{ trace.function ? '
    ' : '' }} + in {{ trace.file|format_file(trace.line) }}  + {% spaceless %} + + - + + + + {% endspaceless %} +
    + {{ trace.file|file_excerpt(trace.line) }} +
    +{% endif %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/trace.txt.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/trace.txt.twig new file mode 100644 index 0000000..1b3b77d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/trace.txt.twig @@ -0,0 +1,8 @@ +{% if trace.function %} + at {{ trace.class ~ trace.type ~ trace.function }}({{ trace.args|format_args_as_text }}) +{% else %} + at n/a +{% endif %} +{% if trace.file is defined and trace.line is defined %} + in {{ trace.file }} line {{ trace.line }} +{% endif %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces.html.twig new file mode 100644 index 0000000..f82b754 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces.html.twig @@ -0,0 +1,25 @@ +
    + {% if count > 0 %} +

    + [{{ count - position + 1 }}/{{ count + 1 }}] + {{ exception.class|abbr_class }}: {{ exception.message|nl2br|format_file_from_text }}  + {% spaceless %} + + - + + + + {% endspaceless %} +

    + {% else %} +

    Stack Trace

    + {% endif %} + + +
      + {% for i, trace in exception.trace %} +
    1. + {% include 'TwigBundle:Exception:trace.html.twig' with { 'prefix': position, 'i': i, 'trace': trace } only %} +
    2. + {% endfor %} +
    +
    diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces.txt.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces.txt.twig new file mode 100644 index 0000000..2cb3ba4 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces.txt.twig @@ -0,0 +1,6 @@ +{% if exception.trace|length %} +{% for trace in exception.trace %} +{% include 'TwigBundle:Exception:trace.txt.twig' with { 'trace': trace } only %} + +{% endfor %} +{% endif %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces.xml.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces.xml.twig new file mode 100644 index 0000000..133a626 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces.xml.twig @@ -0,0 +1,8 @@ + +{% for trace in exception.trace %} + +{% include 'TwigBundle:Exception:trace.txt.twig' with { 'trace': trace } only %} + + +{% endfor %} + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/layout.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/layout.html.twig new file mode 100644 index 0000000..d8c359c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/layout.html.twig @@ -0,0 +1,42 @@ + + + + + + {% block title '' %} + + + + +
    +
    + + + +
    + + {% block body '' %} +
    + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/Controller/ExceptionControllerTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/Controller/ExceptionControllerTest.php new file mode 100644 index 0000000..b35b0fc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/Controller/ExceptionControllerTest.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\Bundle\TwigBundle\Tests\Controller; + +use Symfony\Bundle\TwigBundle\Tests\TestCase; + +use Symfony\Bundle\TwigBundle\Controller\ExceptionController; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Scope; +use Symfony\Component\HttpFoundation\Request; + +class ExceptionControllerTest extends TestCase +{ + protected $controller; + protected $container; + protected $flatten; + protected $templating; + protected $kernel; + + protected function setUp() + { + parent::setUp(); + + $this->flatten = $this->getMock('Symfony\Component\HttpKernel\Exception\FlattenException'); + $this->flatten + ->expects($this->once()) + ->method('getStatusCode') + ->will($this->returnValue(404)); + $this->flatten + ->expects($this->once()) + ->method('getHeaders') + ->will($this->returnValue(array())); + $this->controller = new ExceptionController(); + $this->kernel = $this->getMock('Symfony\\Component\\HttpKernel\\KernelInterface'); + $this->templating = $this->getMockBuilder('Symfony\\Bundle\\TwigBundle\\TwigEngine') + ->disableOriginalConstructor() + ->getMock(); + $this->templating + ->expects($this->any()) + ->method('renderResponse') + ->will($this->returnValue($this->getMock('Symfony\Component\HttpFoundation\Response'))); + $this->request = Request::create('/'); + $this->container = $this->getContainer(); + } + + protected function tearDown() + { + parent::tearDown(); + + $this->controller = null; + $this->container = null; + $this->flatten = null; + $this->templating = null; + $this->kernel = null; + } + + public function testOnlyClearOwnOutputBuffers() + { + $this->request->headers->set('X-Php-Ob-Level', 1); + + $this->controller->setContainer($this->container); + $this->controller->showAction($this->flatten); + } + + private function getContainer() + { + $container = new ContainerBuilder(); + $container->addScope(new Scope('request')); + $container->set('request', $this->request); + $container->set('templating', $this->templating); + $container->setParameter('kernel.bundles', array()); + $container->setParameter('kernel.cache_dir', __DIR__); + $container->setParameter('kernel.root_dir', __DIR__); + $container->set('kernel', $this->kernel); + + return $container; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/php/full.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/php/full.php new file mode 100644 index 0000000..7733f17 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/php/full.php @@ -0,0 +1,21 @@ +loadFromExtension('twig', array( + 'form' => array( + 'resources' => array( + 'MyBundle::form.html.twig', + ) + ), + 'globals' => array( + 'foo' => '@bar', + 'pi' => 3.14, + 'bad' => array('key' => 'foo'), + ), + 'auto_reload' => true, + 'autoescape' => true, + 'base_template_class' => 'stdClass', + 'cache' => '/tmp', + 'charset' => 'ISO-8859-1', + 'debug' => true, + 'strict_variables' => true, +)); diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/xml/full.xml b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/xml/full.xml new file mode 100644 index 0000000..dacc523 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/xml/full.xml @@ -0,0 +1,16 @@ + + + + + + + MyBundle::form.html.twig + + + 3.14 + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/yml/full.yml b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/yml/full.yml new file mode 100644 index 0000000..baf7661 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/yml/full.yml @@ -0,0 +1,15 @@ +twig: + form: + resources: + - MyBundle::form.html.twig + globals: + foo: "@bar" + pi: 3.14 + bad: {key: foo} + auto_reload: true + autoescape: true + base_template_class: stdClass + cache: /tmp + charset: ISO-8859-1 + debug: true + strict_variables: true diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php new file mode 100644 index 0000000..eccc1f2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php @@ -0,0 +1,158 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\TwigBundle\Tests\DependencyInjection; + +use Symfony\Bundle\TwigBundle\DependencyInjection\TwigExtension; +use Symfony\Bundle\TwigBundle\Tests\TestCase; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; + +class TwigExtensionTest extends TestCase +{ + public function testLoadEmptyConfiguration() + { + $container = $this->createContainer(); + $container->registerExtension(new TwigExtension()); + $container->loadFromExtension('twig', array()); + $this->compileContainer($container); + + $this->assertEquals('Twig_Environment', $container->getParameter('twig.class'), '->load() loads the twig.xml file'); + $this->assertContains('form_div_layout.html.twig', $container->getParameter('twig.form.resources'), '->load() includes default template for form resources'); + + // Twig options + $options = $container->getParameter('twig.options'); + $this->assertEquals(__DIR__.'/twig', $options['cache'], '->load() sets default value for cache option'); + $this->assertEquals('UTF-8', $options['charset'], '->load() sets default value for charset option'); + $this->assertFalse($options['debug'], '->load() sets default value for debug option'); + } + + /** + * @dataProvider getFormats + */ + public function testLoadFullConfiguration($format) + { + $container = $this->createContainer(); + $container->registerExtension(new TwigExtension()); + $this->loadFromFile($container, 'full', $format); + $this->compileContainer($container); + + $this->assertEquals('Twig_Environment', $container->getParameter('twig.class'), '->load() loads the twig.xml file'); + + // Form resources + $resources = $container->getParameter('twig.form.resources'); + $this->assertContains('form_div_layout.html.twig', $resources, '->load() includes default template for form resources'); + $this->assertContains('MyBundle::form.html.twig', $resources, '->load() merges new templates into form resources'); + + // Globals + $calls = $container->getDefinition('twig')->getMethodCalls(); + $this->assertEquals('foo', $calls[0][1][0], '->load() registers services as Twig globals'); + $this->assertEquals(new Reference('bar'), $calls[0][1][1], '->load() registers services as Twig globals'); + $this->assertEquals('pi', $calls[1][1][0], '->load() registers variables as Twig globals'); + $this->assertEquals(3.14, $calls[1][1][1], '->load() registers variables as Twig globals'); + + // Yaml and Php specific configs + if (in_array($format, array('yml', 'php'))) { + $this->assertEquals('bad', $calls[2][1][0], '->load() registers variables as Twig globals'); + $this->assertEquals(array('key' => 'foo'), $calls[2][1][1], '->load() registers variables as Twig globals'); + } + + // Twig options + $options = $container->getParameter('twig.options'); + $this->assertTrue($options['auto_reload'], '->load() sets the auto_reload option'); + $this->assertTrue($options['autoescape'], '->load() sets the autoescape option'); + $this->assertEquals('stdClass', $options['base_template_class'], '->load() sets the base_template_class option'); + $this->assertEquals('/tmp', $options['cache'], '->load() sets the cache option'); + $this->assertEquals('ISO-8859-1', $options['charset'], '->load() sets the charset option'); + $this->assertTrue($options['debug'], '->load() sets the debug option'); + $this->assertTrue($options['strict_variables'], '->load() sets the strict_variables option'); + } + + public function testGlobalsWithDifferentTypesAndValues() + { + $globals = array( + 'array' => array(), + 'false' => false, + 'float' => 2.0, + 'integer' => 3, + 'null' => null, + 'object' => new \stdClass(), + 'string' => 'foo', + 'true' => true, + ); + + $container = $this->createContainer(); + $container->registerExtension(new TwigExtension()); + $container->loadFromExtension('twig', array('globals' => $globals)); + $this->compileContainer($container); + + $calls = $container->getDefinition('twig')->getMethodCalls(); + + foreach ($calls as $call) { + list($name, $value) = each($globals); + $this->assertEquals($name, $call[1][0]); + $this->assertSame($value, $call[1][1]); + } + } + + public function getFormats() + { + return array( + array('php'), + array('yml'), + array('xml'), + ); + } + + private function createContainer() + { + $container = new ContainerBuilder(new ParameterBag(array( + 'kernel.cache_dir' => __DIR__, + 'kernel.charset' => 'UTF-8', + 'kernel.debug' => false, + ))); + + return $container; + } + + private function compileContainer(ContainerBuilder $container) + { + $container->getCompilerPassConfig()->setOptimizationPasses(array()); + $container->getCompilerPassConfig()->setRemovingPasses(array()); + $container->compile(); + } + + private function loadFromFile(ContainerBuilder $container, $file, $format) + { + $locator = new FileLocator(__DIR__.'/Fixtures/'.$format); + + switch ($format) { + case 'php': + $loader = new PhpFileLoader($container, $locator); + break; + case 'xml': + $loader = new XmlFileLoader($container, $locator); + break; + case 'yml': + $loader = new YamlFileLoader($container, $locator); + break; + default: + throw new \InvalidArgumentException('Unsupported format: '.$format); + } + + $loader->load($file.'.'.$format); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php new file mode 100644 index 0000000..0d29d30 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.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\Bundle\TwigBundle\Tests\Loader; + +use Symfony\Bundle\TwigBundle\Tests\TestCase; +use Symfony\Bundle\TwigBundle\Loader\FilesystemLoader; +use Symfony\Component\Config\FileLocatorInterface; +use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference; +use Symfony\Component\Templating\TemplateNameParserInterface; +use InvalidArgumentException; + +class FilesystemLoaderTest extends TestCase +{ + /** @var FileLocatorInterface */ + private $locator; + /** @var TemplateNameParserInterface */ + private $parser; + /** @var FilesystemLoader */ + private $loader; + + protected function setUp() + { + parent::setUp(); + + $this->locator = $this->getMock('Symfony\Component\Config\FileLocatorInterface'); + $this->parser = $this->getMock('Symfony\Component\Templating\TemplateNameParserInterface'); + $this->loader = new FilesystemLoader($this->locator, $this->parser); + + $this->parser->expects($this->once()) + ->method('parse') + ->with('name.format.engine') + ->will($this->returnValue(new TemplateReference('', '', 'name', 'format', 'engine'))) + ; + } + + protected function tearDown() + { + parent::tearDown(); + + $this->locator = null; + $this->parser = null; + $this->loader = null; + } + + public function testTwigErrorIfLocatorThrowsInvalid() + { + $this->setExpectedException('Twig_Error_Loader'); + $invalidException = new InvalidArgumentException('Unable to find template "NonExistent".'); + $this->locator->expects($this->once()) + ->method('locate') + ->will($this->throwException($invalidException)); + + $this->loader->getCacheKey('name.format.engine'); + } + + public function testTwigErrorIfLocatorReturnsFalse() + { + $this->setExpectedException('Twig_Error_Loader'); + $this->locator->expects($this->once()) + ->method('locate') + ->will($this->returnValue(false)); + + $this->loader->getCacheKey('name.format.engine'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/TestCase.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/TestCase.php new file mode 100644 index 0000000..a3848ef --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/TestCase.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\Bundle\TwigBundle\Tests; + +class TestCase extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Twig_Environment')) { + $this->markTestSkipped('Twig is not available.'); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/TwigEngineTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/TwigEngineTest.php new file mode 100644 index 0000000..f15ef3f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Tests/TwigEngineTest.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\Bundle\TwigBundle\Tests; + +use Symfony\Bundle\TwigBundle\TwigEngine; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Session\Session; +use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; +use Symfony\Component\Templating\TemplateNameParser; +use Symfony\Bundle\FrameworkBundle\Templating\GlobalVariables; + +class TwigEngineTest extends TestCase +{ + public function testEvaluateAddsAppGlobal() + { + $environment = $this->getTwigEnvironment(); + $container = $this->getContainer(); + $locator = $this->getMock('Symfony\Component\Config\FileLocatorInterface'); + $engine = new TwigEngine($environment, new TemplateNameParser(), $locator, $app = new GlobalVariables($container)); + + $template = $this->getMock('\Twig_TemplateInterface'); + + $environment->expects($this->once()) + ->method('loadTemplate') + ->will($this->returnValue($template)); + + $engine->render('name'); + + $request = $container->get('request'); + $globals = $environment->getGlobals(); + $this->assertSame($app, $globals['app']); + } + + public function testEvaluateWithoutAvailableRequest() + { + $environment = $this->getTwigEnvironment(); + $container = new Container(); + $locator = $this->getMock('Symfony\Component\Config\FileLocatorInterface'); + $engine = new TwigEngine($environment, new TemplateNameParser(), $locator, new GlobalVariables($container)); + + $template = $this->getMock('\Twig_TemplateInterface'); + + $environment->expects($this->once()) + ->method('loadTemplate') + ->will($this->returnValue($template)); + + $container->set('request', null); + + $engine->render('name'); + + $globals = $environment->getGlobals(); + $this->assertEmpty($globals['app']->getRequest()); + } + + /** + * Creates a Container with a Session-containing Request service. + * + * @return Container + */ + protected function getContainer() + { + $container = new Container(); + $request = new Request(); + $session = new Session(new MockArraySessionStorage()); + + $request->setSession($session); + $container->set('request', $request); + + return $container; + } + + /** + * Creates a mock Twig_Environment object. + * + * @return \Twig_Environment + */ + protected function getTwigEnvironment() + { + return $this + ->getMockBuilder('\Twig_Environment') + ->setMethods(array('loadTemplate')) + ->getMock(); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/TokenParser/RenderTokenParser.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/TokenParser/RenderTokenParser.php new file mode 100644 index 0000000..272324b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/TokenParser/RenderTokenParser.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\Bundle\TwigBundle\TokenParser; + +use Symfony\Bundle\TwigBundle\Node\RenderNode; + +/** + * Token Parser for the render tag. + * + * @author Fabien Potencier + */ +class RenderTokenParser extends \Twig_TokenParser +{ + /** + * Parses a token and returns a node. + * + * @param \Twig_Token $token A \Twig_Token instance + * + * @return \Twig_NodeInterface A \Twig_NodeInterface instance + */ + public function parse(\Twig_Token $token) + { + $expr = $this->parser->getExpressionParser()->parseExpression(); + + // attributes + if ($this->parser->getStream()->test(\Twig_Token::NAME_TYPE, 'with')) { + $this->parser->getStream()->next(); + + $hasAttributes = true; + $attributes = $this->parser->getExpressionParser()->parseExpression(); + } else { + $hasAttributes = false; + $attributes = new \Twig_Node_Expression_Array(array(), $token->getLine()); + } + + // options + if ($hasAttributes && $this->parser->getStream()->test(\Twig_Token::PUNCTUATION_TYPE, ',')) { + $this->parser->getStream()->next(); + + $options = $this->parser->getExpressionParser()->parseExpression(); + } else { + $options = new \Twig_Node_Expression_Array(array(), $token->getLine()); + } + + $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE); + + return new RenderNode($expr, $attributes, $options, $token->getLine(), $this->getTag()); + } + + /** + * Gets the tag name associated with this token parser. + * + * @return string The tag name + */ + public function getTag() + { + return 'render'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/TwigBundle.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/TwigBundle.php new file mode 100644 index 0000000..a67756c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/TwigBundle.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\Bundle\TwigBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\TwigEnvironmentPass; +use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\ExceptionListenerPass; + +/** + * Bundle. + * + * @author Fabien Potencier + */ +class TwigBundle extends Bundle +{ + public function build(ContainerBuilder $container) + { + parent::build($container); + + $container->addCompilerPass(new TwigEnvironmentPass()); + $container->addCompilerPass(new ExceptionListenerPass()); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/TwigEngine.php b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/TwigEngine.php new file mode 100644 index 0000000..53a2ca2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/TwigEngine.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\Bundle\TwigBundle; + +use Symfony\Bridge\Twig\TwigEngine as BaseEngine; +use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface; +use Symfony\Bundle\FrameworkBundle\Templating\GlobalVariables; +use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference; +use Symfony\Component\Templating\TemplateNameParserInterface; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Config\FileLocatorInterface; + +/** + * This engine renders Twig templates. + * + * @author Fabien Potencier + */ +class TwigEngine extends BaseEngine implements EngineInterface +{ + protected $locator; + + /** + * Constructor. + * + * @param \Twig_Environment $environment A \Twig_Environment instance + * @param TemplateNameParserInterface $parser A TemplateNameParserInterface instance + * @param FileLocatorInterface $locator A FileLocatorInterface instance + * @param GlobalVariables|null $globals A GlobalVariables instance or null + */ + public function __construct(\Twig_Environment $environment, TemplateNameParserInterface $parser, FileLocatorInterface $locator, GlobalVariables $globals = null) + { + parent::__construct($environment, $parser); + + $this->locator = $locator; + + if (null !== $globals) { + $environment->addGlobal('app', $globals); + } + } + + public function setDefaultEscapingStrategy($strategy) + { + $this->environment->getExtension('escaper')->setDefaultStrategy($strategy); + } + + public function guessDefaultEscapingStrategy($filename) + { + // remove .twig + $filename = substr($filename, 0, -5); + + // get the format + $format = substr($filename, strrpos($filename, '.') + 1); + + if ('js' === $format) { + return 'js'; + } + + return 'html'; + } + + /** + * Renders a template. + * + * @param mixed $name A template name + * @param array $parameters An array of parameters to pass to the template + * + * @return string The evaluated template as a string + * + * @throws \InvalidArgumentException if the template does not exist + * @throws \RuntimeException if the template cannot be rendered + */ + public function render($name, array $parameters = array()) + { + try { + return parent::render($name, $parameters); + } catch (\Twig_Error $e) { + if ($name instanceof TemplateReference) { + try { + // try to get the real file name of the template where the error occurred + $e->setTemplateFile(sprintf('%s', $this->locator->locate($this->parser->parse($e->getTemplateFile())))); + } catch (\Exception $ex) { + } + } + + throw $e; + } + } + + /** + * Renders a view and returns a Response. + * + * @param string $view The view name + * @param array $parameters An array of parameters to pass to the view + * @param Response $response A Response instance + * + * @return Response A Response instance + */ + public function renderResponse($view, array $parameters = array(), Response $response = null) + { + if (null === $response) { + $response = new Response(); + } + + $response->setContent($this->render($view, $parameters)); + + return $response; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/composer.json b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/composer.json new file mode 100644 index 0000000..22538b2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/composer.json @@ -0,0 +1,31 @@ +{ + "name": "symfony/twig-bundle", + "type": "symfony-bundle", + "description": "Symfony TwigBundle", + "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/twig-bridge": "self.version" + }, + "autoload": { + "psr-0": { "Symfony\\Bundle\\TwigBundle": "" } + }, + "target-dir": "Symfony/Bundle/TwigBundle", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/CHANGELOG.md b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/CHANGELOG.md new file mode 100644 index 0000000..38cac53 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/CHANGELOG.md @@ -0,0 +1,14 @@ +CHANGELOG +========= + +2.1.0 +----- + + * deprecated the verbose setting (not relevant anymore) + * [BC BREAK] You must clear old profiles after upgrading to 2.1 (don't forget + to remove the table if you are using a DB) + * added support for the request method + * added a routing panel + * added a timeline panel + * The toolbar position can now be configured via the `position` option (can + be `top` or `bottom`) diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Controller/ExceptionController.php b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Controller/ExceptionController.php new file mode 100644 index 0000000..f646d50 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Controller/ExceptionController.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\Bundle\WebProfilerBundle\Controller; + +use Symfony\Component\HttpKernel\Exception\FlattenException; +use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Bundle\TwigBundle\Controller\ExceptionController as BaseExceptionController; + +/** + * ExceptionController. + * + * @author Fabien Potencier + */ +class ExceptionController extends BaseExceptionController +{ + /** + * {@inheritdoc} + */ + public function showAction(FlattenException $exception, DebugLoggerInterface $logger = null, $format = 'html') + { + $template = $this->container->get('kernel')->isDebug() ? 'exception' : 'error'; + $code = $exception->getStatusCode(); + + return $this->container->get('templating')->renderResponse( + 'TwigBundle:Exception:'.$template.'.html.twig', + array( + 'status_code' => $code, + 'status_text' => Response::$statusTexts[$code], + 'exception' => $exception, + 'logger' => null, + 'currentContent' => '', + ) + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php new file mode 100644 index 0000000..9399053 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php @@ -0,0 +1,358 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\WebProfilerBundle\Controller; + +use Symfony\Component\DependencyInjection\ContainerAware; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Symfony\Component\HttpFoundation\Session\Flash\AutoExpireFlashBag; +use Symfony\Component\HttpFoundation\Request; + +/** + * ProfilerController. + * + * @author Fabien Potencier + */ +class ProfilerController extends ContainerAware +{ + /** + * Renders a profiler panel for the given token. + * + * @param Request $request The HTTP request + * @param string $token The profiler token + * + * @return Response A Response instance + */ + public function panelAction(Request $request, $token) + { + $profiler = $this->container->get('profiler'); + $profiler->disable(); + + $panel = $this->container->get('request')->query->get('panel', 'request'); + $page = $this->container->get('request')->query->get('page', 'home'); + + if (!$profile = $profiler->loadProfile($token)) { + return $this->container->get('templating')->renderResponse('WebProfilerBundle:Profiler:info.html.twig', array('about' => 'no_token', 'token' => $token)); + } + + if (!$profile->hasCollector($panel)) { + throw new NotFoundHttpException(sprintf('Panel "%s" is not available for token "%s".', $panel, $token)); + } + + return $this->container->get('templating')->renderResponse($this->getTemplateName($profiler, $panel), array( + 'token' => $token, + 'profile' => $profile, + 'collector' => $profile->getCollector($panel), + 'panel' => $panel, + 'page' => $page, + 'templates' => $this->getTemplates($profiler), + 'is_ajax' => $request->isXmlHttpRequest(), + )); + } + + /** + * Exports data for a given token. + * + * @param string $token The profiler token + * + * @return Response A Response instance + */ + public function exportAction($token) + { + $profiler = $this->container->get('profiler'); + $profiler->disable(); + + if (!$profile = $profiler->loadProfile($token)) { + throw new NotFoundHttpException(sprintf('Token "%s" does not exist.', $token)); + } + + return new Response($profiler->export($profile), 200, array( + 'Content-Type' => 'text/plain', + 'Content-Disposition' => 'attachment; filename= '.$token.'.txt', + )); + } + + /** + * Purges all tokens. + * + * @return Response A Response instance + */ + public function purgeAction() + { + $profiler = $this->container->get('profiler'); + $profiler->disable(); + $profiler->purge(); + + return new RedirectResponse($this->container->get('router')->generate('_profiler_info', array('about' => 'purge'))); + } + + /** + * Imports token data. + * + * @return Response A Response instance + */ + public function importAction() + { + $profiler = $this->container->get('profiler'); + $profiler->disable(); + + $router = $this->container->get('router'); + + $file = $this->container->get('request')->files->get('file'); + + if (empty($file) || !$file->isValid()) { + return new RedirectResponse($router->generate('_profiler_info', array('about' => 'upload_error'))); + } + + if (!$profile = $profiler->import(file_get_contents($file->getPathname()))) { + return new RedirectResponse($router->generate('_profiler_info', array('about' => 'already_exists'))); + } + + return new RedirectResponse($router->generate('_profiler', array('token' => $profile->getToken()))); + } + + /** + * Displays information page. + * + * @param string $about + * + * @return Response A Response instance + */ + public function infoAction($about) + { + $profiler = $this->container->get('profiler'); + $profiler->disable(); + + return $this->container->get('templating')->renderResponse('WebProfilerBundle:Profiler:info.html.twig', array( + 'about' => $about + )); + } + + /** + * Renders the Web Debug Toolbar. + * + * @param string $token The profiler token + * @param string $position The toolbar position (top, bottom, normal, or null -- use the configuration) + * + * @return Response A Response instance + */ + public function toolbarAction($token, $position = null) + { + $request = $this->container->get('request'); + $session = $request->getSession(); + + if (null !== $session && $session->getFlashBag() instanceof AutoExpireFlashBag) { + // keep current flashes for one more request if using AutoExpireFlashBag + $session->getFlashBag()->setAll($session->getFlashBag()->peekAll()); + } + + if (null === $token) { + return new Response(); + } + + $profiler = $this->container->get('profiler'); + $profiler->disable(); + + if (!$profile = $profiler->loadProfile($token)) { + return new Response(); + } + + if (null === $position) { + $position = $this->container->getParameter('web_profiler.debug_toolbar.position'); + } + + $url = null; + try { + $url = $this->container->get('router')->generate('_profiler', array('token' => $token)); + } catch (\Exception $e) { + // the profiler is not enabled + } + + return $this->container->get('templating')->renderResponse('WebProfilerBundle:Profiler:toolbar.html.twig', array( + 'position' => $position, + 'profile' => $profile, + 'templates' => $this->getTemplates($profiler), + 'profiler_url' => $url, + )); + } + + /** + * Renders the profiler search bar. + * + * @return Response A Response instance + */ + public function searchBarAction() + { + $profiler = $this->container->get('profiler'); + $profiler->disable(); + + if (null === $session = $this->container->get('request')->getSession()) { + $ip = + $method = + $url = + $limit = + $token = null; + } else { + $ip = $session->get('_profiler_search_ip'); + $method = $session->get('_profiler_search_method'); + $url = $session->get('_profiler_search_url'); + $limit = $session->get('_profiler_search_limit'); + $token = $session->get('_profiler_search_token'); + } + + return $this->container->get('templating')->renderResponse('WebProfilerBundle:Profiler:search.html.twig', array( + 'token' => $token, + 'ip' => $ip, + 'method' => $method, + 'url' => $url, + 'limit' => $limit, + )); + } + + /** + * Search results. + * + * @param string $token The token + * + * @return Response A Response instance + */ + public function searchResultsAction($token) + { + $profiler = $this->container->get('profiler'); + $profiler->disable(); + + $profile = $profiler->loadProfile($token); + + $ip = $this->container->get('request')->query->get('ip'); + $method = $this->container->get('request')->query->get('method'); + $url = $this->container->get('request')->query->get('url'); + $limit = $this->container->get('request')->query->get('limit'); + + return $this->container->get('templating')->renderResponse('WebProfilerBundle:Profiler:results.html.twig', array( + 'token' => $token, + 'profile' => $profile, + 'tokens' => $profiler->find($ip, $url, $limit, $method), + 'ip' => $ip, + 'method' => $method, + 'url' => $url, + 'limit' => $limit, + 'panel' => null, + )); + } + + /** + * Narrow the search bar. + * + * @return Response A Response instance + */ + public function searchAction() + { + $profiler = $this->container->get('profiler'); + $profiler->disable(); + + $request = $this->container->get('request'); + + $ip = preg_replace('/[^:\d\.]/', '', $request->query->get('ip')); + $method = $request->query->get('method'); + $url = $request->query->get('url'); + $limit = $request->query->get('limit'); + $token = $request->query->get('token'); + + if (null !== $session = $request->getSession()) { + $session->set('_profiler_search_ip', $ip); + $session->set('_profiler_search_method', $method); + $session->set('_profiler_search_url', $url); + $session->set('_profiler_search_limit', $limit); + $session->set('_profiler_search_token', $token); + } + + if (!empty($token)) { + return new RedirectResponse($this->container->get('router')->generate('_profiler', array('token' => $token))); + } + + $tokens = $profiler->find($ip, $url, $limit, $method); + + return new RedirectResponse($this->container->get('router')->generate('_profiler_search_results', array( + 'token' => $tokens ? $tokens[0]['token'] : 'empty', + 'ip' => $ip, + 'method' => $method, + 'url' => $url, + 'limit' => $limit, + ))); + } + + /** + * Displays the PHP info. + * + * @return Response A Response instance + */ + public function phpinfoAction() + { + $profiler = $this->container->get('profiler'); + $profiler->disable(); + + ob_start(); + phpinfo(); + $phpinfo = ob_get_clean(); + + return new Response($phpinfo); + } + + protected function getTemplateNames($profiler) + { + $templates = array(); + foreach ($this->container->getParameter('data_collector.templates') as $arguments) { + if (null === $arguments) { + continue; + } + + list($name, $template) = $arguments; + if (!$profiler->has($name)) { + continue; + } + + if ('.html.twig' === substr($template, -10)) { + $template = substr($template, 0, -10); + } + + if (!$this->container->get('templating')->exists($template.'.html.twig')) { + throw new \UnexpectedValueException(sprintf('The profiler template "%s.html.twig" for data collector "%s" does not exist.', $template, $name)); + } + + $templates[$name] = $template.'.html.twig'; + } + + return $templates; + } + + protected function getTemplateName($profiler, $panel) + { + $templates = $this->getTemplateNames($profiler); + + if (!isset($templates[$panel])) { + throw new NotFoundHttpException(sprintf('Panel "%s" is not registered.', $panel)); + } + + return $templates[$panel]; + } + + protected function getTemplates($profiler) + { + $templates = $this->getTemplateNames($profiler); + foreach ($templates as $name => $template) { + $templates[$name] = $this->container->get('twig')->loadTemplate($template); + } + + return $templates; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php new file mode 100644 index 0000000..758b1b7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.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\Bundle\WebProfilerBundle\Controller; + +use Symfony\Component\DependencyInjection\ContainerAware; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Matcher\TraceableUrlMatcher; + +/** + * RouterController. + * + * @author Fabien Potencier + */ +class RouterController extends ContainerAware +{ + /** + * Renders the profiler panel for the given token. + * + * @param string $token The profiler token + * + * @return Response A Response instance + */ + public function panelAction($token) + { + $profiler = $this->container->get('profiler'); + $profiler->disable(); + + if (!$this->container->has('router')) { + return new Response('The Router is not enabled.'); + } + $router = $this->container->get('router'); + + $profile = $profiler->loadProfile($token); + + $context = $router->getContext(); + $context->setMethod($profile->getMethod()); + $matcher = new TraceableUrlMatcher($router->getRouteCollection(), $context); + + $request = $profile->getCollector('request'); + + return $this->container->get('templating')->renderResponse('WebProfilerBundle:Router:panel.html.twig', array( + 'request' => $request, + 'router' => $profile->getCollector('router'), + 'traces' => $matcher->getTraces($request->getPathInfo()), + )); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/Configuration.php b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/Configuration.php new file mode 100644 index 0000000..6ba5e1a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/Configuration.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\Bundle\WebProfilerBundle\DependencyInjection; + +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; + +/** + * This class contains the configuration information for the bundle + * + * This information is solely responsible for how the different configuration + * sections are normalized, and merged. + * + * @author Fabien Potencier + */ +class Configuration implements ConfigurationInterface +{ + /** + * Generates the configuration tree builder. + * + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder + */ + public function getConfigTreeBuilder() + { + $treeBuilder = new TreeBuilder(); + $rootNode = $treeBuilder->root('web_profiler'); + + $rootNode + ->children() + ->booleanNode('verbose')->defaultTrue()->info('DEPRECATED, it is not useful anymore and can be removed safely from your configuration')->end() + ->booleanNode('toolbar')->defaultFalse()->end() + ->scalarNode('position') + ->defaultValue('bottom') + ->validate() + ->ifNotInArray(array('bottom', 'top')) + ->thenInvalid('The CSS position %s is not supported') + ->end() + ->end() + ->booleanNode('intercept_redirects')->defaultFalse()->end() + ->end() + ; + + return $treeBuilder; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/WebProfilerExtension.php b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/WebProfilerExtension.php new file mode 100644 index 0000000..cbcd824 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/WebProfilerExtension.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\Bundle\WebProfilerBundle\DependencyInjection; + +use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Config\FileLocator; +use Symfony\Bundle\WebProfilerBundle\EventListener\WebDebugToolbarListener; + +/** + * WebProfilerExtension. + * + * Usage: + * + * + * + * @author Fabien Potencier + */ +class WebProfilerExtension extends Extension +{ + /** + * Loads the web profiler configuration. + * + * @param array $configs An array of configuration settings + * @param ContainerBuilder $container A ContainerBuilder instance + */ + public function load(array $configs, ContainerBuilder $container) + { + $configuration = $this->getConfiguration($configs, $container); + $config = $this->processConfiguration($configuration, $configs); + + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('toolbar.xml'); + + $container->setParameter('web_profiler.debug_toolbar.intercept_redirects', $config['intercept_redirects']); + + if (!$config['toolbar']) { + $mode = WebDebugToolbarListener::DISABLED; + } else { + $mode = WebDebugToolbarListener::ENABLED; + } + + $container->setParameter('web_profiler.debug_toolbar.mode', $mode); + $container->setParameter('web_profiler.debug_toolbar.position', $config['position']); + } + + /** + * Returns the base path for the XSD files. + * + * @return string The XSD base path + */ + public function getXsdValidationBasePath() + { + return __DIR__.'/../Resources/config/schema'; + } + + public function getNamespace() + { + return 'http://symfony.com/schema/dic/webprofiler'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php new file mode 100644 index 0000000..27a0be4 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.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\Bundle\WebProfilerBundle\EventListener; + +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Bundle\TwigBundle\TwigEngine; +use Symfony\Component\HttpFoundation\Session\Flash\AutoExpireFlashBag; + +/** + * WebDebugToolbarListener injects the Web Debug Toolbar. + * + * The onKernelResponse method must be connected to the kernel.response event. + * + * The WDT is only injected on well-formed HTML (with a proper tag). + * This means that the WDT is never included in sub-requests or ESI requests. + * + * @author Fabien Potencier + */ +class WebDebugToolbarListener +{ + const DISABLED = 1; + const ENABLED = 2; + + protected $templating; + protected $interceptRedirects; + protected $mode; + protected $position; + + public function __construct(TwigEngine $templating, $interceptRedirects = false, $mode = self::ENABLED, $position = 'bottom') + { + $this->templating = $templating; + $this->interceptRedirects = (Boolean) $interceptRedirects; + $this->mode = (integer) $mode; + $this->position = $position; + } + + public function isEnabled() + { + return self::DISABLED !== $this->mode; + } + + public function onKernelResponse(FilterResponseEvent $event) + { + if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) { + return; + } + + $response = $event->getResponse(); + $request = $event->getRequest(); + + // do not capture redirects or modify XML HTTP Requests + if ($request->isXmlHttpRequest()) { + return; + } + + if ($response->headers->has('X-Debug-Token') && $response->isRedirect() && $this->interceptRedirects) { + $session = $request->getSession(); + if ($session && $session->getFlashBag() instanceof AutoExpireFlashBag) { + // keep current flashes for one more request if using AutoExpireFlashBag + $session->getFlashBag()->setAll($session->getFlashBag()->peekAll()); + } + + $response->setContent($this->templating->render('WebProfilerBundle:Profiler:toolbar_redirect.html.twig', array('location' => $response->headers->get('Location')))); + $response->setStatusCode(200); + $response->headers->remove('Location'); + } + + if (self::DISABLED === $this->mode + || !$response->headers->has('X-Debug-Token') + || $response->isRedirection() + || ($response->headers->has('Content-Type') && false === strpos($response->headers->get('Content-Type'), 'html')) + || 'html' !== $request->getRequestFormat() + ) { + return; + } + + $this->injectToolbar($response); + } + + /** + * Injects the web debug toolbar into the given Response. + * + * @param Response $response A Response instance + */ + protected function injectToolbar(Response $response) + { + if (function_exists('mb_stripos')) { + $posrFunction = 'mb_strripos'; + $posFunction = 'mb_stripos'; + $substrFunction = 'mb_substr'; + } else { + $posrFunction = 'strripos'; + $posFunction = 'stripos'; + $substrFunction = 'substr'; + } + + $content = $response->getContent(); + + if ($this->position === 'bottom') { + $pos = $posrFunction($content, ''); + } else { + $pos = $posFunction($content, '', $pos) + 1; + } + } + if (false !== $pos) { + $toolbar = "\n".str_replace("\n", '', $this->templating->render( + 'WebProfilerBundle:Profiler:toolbar_js.html.twig', + array('token' => $response->headers->get('X-Debug-Token')) + ))."\n"; + $content = $substrFunction($content, 0, $pos).$toolbar.$substrFunction($content, $pos); + $response->setContent($content); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/LICENSE b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/LICENSE new file mode 100644 index 0000000..cdffe7a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 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/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/ICONS_LICENSE.txt b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/ICONS_LICENSE.txt new file mode 100644 index 0000000..2e20272 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/ICONS_LICENSE.txt @@ -0,0 +1,5 @@ +Icons License +============= + +Icons created by Sensio (http://www.sensio.com/) are shared under a Creative +Commons Attribution license (http://creativecommons.org/licenses/by-sa/3.0/). \ No newline at end of file diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/profiler.xml b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/profiler.xml new file mode 100644 index 0000000..a7383ab --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/profiler.xml @@ -0,0 +1,49 @@ + + + + + + WebProfilerBundle:Profiler:search + + + + WebProfilerBundle:Profiler:purge + + + + WebProfilerBundle:Profiler:info + + + + WebProfilerBundle:Profiler:import + + + + WebProfilerBundle:Profiler:export + + + + WebProfilerBundle:Profiler:phpinfo + + + + WebProfilerBundle:Profiler:searchResults + + + + WebProfilerBundle:Profiler:panel + + + + FrameworkBundle:Redirect:redirect + _profiler_search_results + empty + + + + 10 + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/wdt.xml b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/wdt.xml new file mode 100644 index 0000000..da52074 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/wdt.xml @@ -0,0 +1,10 @@ + + + + + + WebProfilerBundle:Profiler:toolbar + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/config/schema/webprofiler-1.0.xsd b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/config/schema/webprofiler-1.0.xsd new file mode 100644 index 0000000..5c95e72 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/config/schema/webprofiler-1.0.xsd @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/config/toolbar.xml b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/config/toolbar.xml new file mode 100644 index 0000000..5ce61a0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/config/toolbar.xml @@ -0,0 +1,20 @@ + + + + + + Symfony\Bundle\WebProfilerBundle\EventListener\WebDebugToolbarListener + + + + + + + %web_profiler.debug_toolbar.intercept_redirects% + %web_profiler.debug_toolbar.mode% + %web_profiler.debug_toolbar.position% + + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/css/profiler.css b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/css/profiler.css new file mode 100644 index 0000000..548530d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/css/profiler.css @@ -0,0 +1,485 @@ +/* +Copyright (c) 2008, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.net/yui/license.txt +version: 2.6.0 +*/ +html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var,optgroup{font-style:inherit;font-weight:inherit;}del,ins{text-decoration:none;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:baseline;}sub{vertical-align:baseline;}legend{color:#000;}input,button,textarea,select,optgroup,option{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;}input,button,textarea,select{*font-size:100%;} + +html, body { + background-color: #efefef; +} +body { + font: 1em "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif; + text-align: left; +} + +p { + font-size: 14px; + line-height: 20px; + color: #313131; + padding-bottom: 20px +} + +strong { + color: #313131; + font-weight: bold; +} +em { + font-style: italic; +} + +a { + color: #6c6159; +} +a img { + border: none; +} +a:hover { + text-decoration: underline; +} + +button::-moz-focus-inner { + padding: 0; + border: none; +} +button { + overflow: visible; + width: auto; + background-color: transparent; + font-weight: bold; +} + +caption { + margin-bottom: 7px; +} +table, tr, th, td { + border-collapse: collapse; + border: 1px solid #d0dbb3; +} +table { + width: 100%; + margin: 10px 0 30px; +} +table th { + font-weight: bold; + background-color: #f1f7e2; +} +table th, table td { + font-size: 12px; + padding: 8px 10px; +} + +fieldset { + border: none; +} + +abbr { + border-bottom: 1px dotted #000; + cursor: help; +} + +.clear { + clear: both; + height: 0; + font-size: 0; + line-height: 0; +} +.clear_fix:after +{ + content: "\0020"; + display: block; + height: 0; + clear: both; + visibility: hidden; +} +* html .clear_fix +{ + height: 1%; +} +.clear_fix +{ + display: block; +} + +#content { + padding: 0 50px; + margin: 0 auto; + font-family: Arial, Helvetica, sans-serif; + min-width: 970px; +} + +#header { + padding: 30px 30px 20px; +} + +#header h1 { + float: left; +} + +.search { + float: right; +} + +#menu_profiler { + border-right: 1px solid #dfdfdf; +} + +#menu_profiler li { + border-bottom: 1px solid #dfdfdf; + position: relative; + padding-bottom: 0; + display: block; + background-color: #f6f6f6; +} + +#menu_profiler li a { + color: #404040; + display: block; + font-size: 13px; + text-transform: uppercase; + text-decoration: none; + cursor: pointer; +} + +#menu_profiler li a span.label { + display: block; + padding: 20px 20px 16px 65px; + min-height: 24px; + _height: 24px; +} + +#menu_profiler li a span.icon { + display: block; + position: absolute; + left: 0; + top: 12px; + width: 60px; + text-align: center; +} + +#menu_profiler li.selected a, +#menu_profiler li a:hover { + background: #d1d1d1 url(../images/profiler/bg_submenu.png) repeat-x 0 0; +} + +#navigation div:first-child, +#menu_profiler li:first-child, +#menu_profiler li:first-child a, +#menu_profiler li:first-child a span.label { + -moz-border-radius: 16px 0 0 0; + -webkit-border-radius: 16px 0 0 0; + border-radius: 16px 0 0 0; +} + +#menu_profiler li a span.count { + padding: 0; + position: absolute; + right: 10px; + top: 20px; +} + +#collector_wrapper { + float: left; + width: 100%; +} + +#collector_content { + margin-left: 250px; + padding: 40px 50px; +} + +#navigation { + float: left; + width: 250px; + margin-left: -100%; +} + +#collector_content table td { + background-color: white; +} + +h1 { + font-family: Georgia, "Times New Roman", Times, serif; + color: #404040; +} +h2, h3 { + font-weight: bold; + margin-bottom: 20px; +} + +li { + padding-bottom: 10px; + +} + +#main { + -moz-border-radius: 16px; + -webkit-border-radius: 16px; + border-radius: 16px; + margin-bottom: 20px; +} + +#menu_profiler span.count span { + display: inline-block; + background-color: #aacd4e; + -moz-border-radius: 6px; + -webkit-border-radius: 6px; + border-radius: 6px; + padding: 4px; + color: #fff; + margin-right: 2px; + font-size: 11px; +} + +#resume { + background-color: #f6f6f6; + border-bottom: 1px solid #dfdfdf; + padding: 10px 50px; + margin-left: 210px; + color: #313131; + font-size: 12px; + -moz-border-radius-topright: 16px; + -webkit-border-top-right-radius: 16px; + border-top-right-radius: 16px; +} + +a#resume-view-all { + display: inline-block; + padding: 0.2em 0.7em; + margin-right: 0.5em; + background-color: #666; + border-radius: 16px; + color: white; + font-weight: bold; + text-decoration: none; +} + +table th.value { + width: 450px; + background-color: #dfeeb8; +} + +#content h2 { + font-size: 24px; + color: #313131; + font-weight: bold; +} + +#content #main { + padding: 0; + background-color: #FFF; + border: 1px solid #dfdfdf; +} + +#content #main p { + color: #313131; + font-size: 14px; + padding-bottom: 20px; +} + +.sf-toolbarreset { + border-top: 0; + padding: 0; +} + +.sf-exceptionreset .block_exception_detected .text_exception { + width: 520px; +} + +.sf-exceptionreset .block_exception_detected .illustration_exception { + display: none; +} + +ul.alt { + margin: 10px 0 30px; +} + +ul.alt li { + padding: 5px 7px; + font-size: 13px; +} + +ul.alt li.even { + background: #f1f7e2; +} + +ul.alt li.error { + background-color: #f66; + margin-bottom: 1px; +} + +td.main, td.menu { + text-align: left; + margin: 0; + padding: 0; + border: 0; + vertical-align: top; +} + +.search { + padding-top: 20px; +} + +.search label { + line-height: 28px; + vertical-align: middle; +} + +.search input { + width: 188px; + margin-right: 10px; + font-size: 12px; + border: 1px solid #dadada; + background: #FFF url(../images/profiler/input_bg.gif) repeat-x left top; + padding: 5px 6px; + color: #565656; +} + +.search input[type="search"] { + -webkit-appearance: textfield; +} + +.search button { + -webkit-appearance: button-bevel; + float: none; + padding: 0; + margin: 0; + border: 0; + text-decoration: none; + cursor: pointer; + white-space: nowrap; + display: inline-block; + text-align: center; + vertical-align: middle; + background: none; +} + +.search button:hover { + text-decoration: none; +} + +.search button span span, +.search button span span span { + position: static; +} + +.search button span { + position: relative; + text-decoration: none; + display: block; + height: 28px; + float: left; + padding: 0 0 0 8px; + background: transparent url(../images/profiler/border_l.png) no-repeat top left; +} + +.search button span span { + padding: 0 8px 0 0; + background: transparent url(../images/profiler/border_r.png) right top no-repeat; +} + +.search button span span span { + padding: 0 7px; + font: bold 11px Arial, Helvetica, sans-serif; + color: #6b6b6b; + line-height: 28px; + background: transparent url(../images/profiler/btn_bg.png) repeat-x top left; +} + +#navigation div:first-child { + margin: 0 0 20px; + border-top: 0; +} + +#navigation .search { + padding-top: 15px; + float: none; + background: none repeat scroll 0 0 #f6f6f6; + color: #333; + margin: 20px 0; + border: 1px solid #dfdfdf; + border-left: none; +} + +#navigation .search h3 { + font-family: Arial, Helvetica, sans-serif; + text-transform: uppercase; + margin-left: 10px; + font-size: 13px; +} + +#navigation .search form { + padding: 15px 0; +} + +#navigation .search button { + float: right; + margin-right: 20px; +} + +#navigation .search label { + display: block; + float: left; + width: 50px; +} + +#navigation .search input, +#navigation .search select, +#navigation .search label, +#navigation .search a { + font-size: 12px; +} + +#navigation .search form { + padding-left: 10px; +} + +#navigation .search input { + width: 160px; +} + +#navigation .import label { + float: none; + display: inline; +} + +#navigation .import input { + width: 100px; +} + +.timeline { + background-color: #fbfbfb; + margin-bottom: 15px; + margin-top: 5px; +} + +#collector_content .routing tr.matches td { + background-color: #0e0; +} + +#collector_content .routing tr.almost td { + background-color: #fa0; +} + +.loading { + background: transparent url(../images/profiler/spinner.gif) scroll no-repeat 50% 50%; + height: 30px; + display: none; +} + +.sf-profiler-timeline .legends { + font-size: 12px; + line-height: 1.5em; +} + +.sf-profiler-timeline .legends span { + border-left-width: 10px; + border-left-style: solid; + padding: 0 10px 0 5px; +} + +.sf-profiler-timeline canvas { + border: 1px solid #999; + border-width: 1px 0; +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/favicon.ico b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..864803618e0888f8463c0b30038633c018f939cc GIT binary patch literal 1150 zcmaizUr1AN6vuy3^oL%AsH~?RBQobI=ccaNk~J)QQD?41%~lUl4?1&O#PTUgotA-9 zsDZB9Dx!CTsTlUUw?V5x4YK5>5M*n+r|-FL<1!X8KKK0Y+4-K|Ip_DgLX_ZFS}O27 zD6VZ4Vy_V55P%DwO+Snf_;2^FO_X=lLt9ZPzz)z@c~ldI{Q@#slCUp96W9qfs%tQ*oXL6(4`+eocJ>~>XTi!Tx6`NE0#k>{2Oo} ztK9}W2EBZ;)|i=(L{i>6UU}sHFa>93DOU?()OGNh>)?K^U==8P)fsB(g!Z`H)Oe2K zAL8V3c}P=UQK;p237iK()-qO$m3q1_)5Uf>)l?g3abZDzzr3uhc^8WX1k|b(vZuwUYd`2nOcXxJ?f6`A^uQ+Js>k0*)1Z4Ms zn^LJ1IeVQ{e)veSS*BUf_2AsdWHfQT>0~mg)MIP0(fZmtg+pPwU~40@=~Q74tpCV* z?ho@%#bU9aI76NxIeHwFNF*?aMWwIcY>?`WCUqU3p`BrU7P-H#KQlGy-*EQ!{qC?| zBHyTwqR}XwX|T}E>o*E#8G_CNzUOjq9hiOEpwp*$E~o3w^mcAenG2uk(7mCIUZ>~% zB=me1mhaCn;Cq#;BX2o}t+|y3?+$Lc6{R^^&pjZF^ literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/close.png b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/close.png new file mode 100644 index 0000000000000000000000000000000000000000..6a4de0354d85b9d30921cac498cd4b0d00ef3a11 GIT binary patch literal 402 zcmeAS@N?(olHy`uVBq!ia0vp^{2@j7K zvs2ce=MWwB(R})q8=oF4u?C*GUKkR*RNDHvnl5X8=vfKD1K*zT0bRx5>FVdQ&MBb@ E0NzsAIRF3v literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/config.png b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/config.png new file mode 100644 index 0000000000000000000000000000000000000000..e0898afb5ed30c21ef05835249fb604be332619b GIT binary patch literal 379 zcmeAS@N?(olHy`uVBq!ia0vp^qChOe!3-pK9%IP?QfUD`A+GLQ&_>0QAirP+ZXQ*24NZL`V>4?T2XCLC^s4IG zhMflv9zK5Ji|9{WhJi;!* z@ji2=PcELst@*DeOJd4loBa&4Jfc}#4ssre6_1usdc5ZS+}@P@kQ1Fn8iwq z@?OgHN<1<{)!%!Y%$eB_g5EcI*K+K;b~bUc{)W_yTdA4SKc#24t?ST=EzrGTqoC+D zK{nW|Vg9Oq&DkOT%Yx4ClkU!lU3^*KTIml)jr-y6fBc|zd2E~P{tP4LkX6rmxWPjF5aHzlW_ck&n}HX$jc~AVRgC<_pwnwF6G4^8u1rB9RF3%!Gb{YPEVGnM{5_5(|Yw5uTaQFHose z7%xv1i^W~6iS_mME%Drheu0&hm3@7#3zSMFj&n$2*ayEj7Zw(_km~$Z&Lij-z#EG8_Vx^t zST>to=bV|D*+B|sx7(lNsUBV*qF-QfaZ&X5_rF6@KA+ziA0NNRYe}$lI{m$;r{_Jd z5794BC=|r(?Cc(rGMUT^uh;A3wIpzy;dL&T`-8QOXLa-o;JAhtC&>?2fEdo5x7lp> z)#J9dwr5CDN54QxJ4<#N4Lk8!8`z>i$4d!BxQU@*8jH#f&0JljYi z5py^kcSc4=zVTYITCHnHq2LI^h7>-oz-j1!TabhzJe{1J{5?HAP1t-(NFfpH?CgBP zS#NZ7beG>u!57#kb&l7D1#l@Z_4f8gd_Lc!fq{WHLqkKGxTJg7;UrxE!SGve@eEhz zE2lKUX~wVszUj_FH^ku~yoS#}l2C?+hc|hqpy*F|ZXM`2P45A`cmrIaw@6YVk;od) z4a@^c^Gz3s#bOOS9?vS0>f8iz1pT`p8jUu%p9brJf05)R-x7!^>5*r*G+~%19 z{Q}`|xB>3}yGUYzK%mAm1NsHz|CqE2oU8(W0iU|2^=5jyzyJUM M07*qoM6N<$f|KG{cmMzZ literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/exception.png b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/exception.png new file mode 100644 index 0000000000000000000000000000000000000000..b02aac786ad78700bec10aa73d17c9fe2b4d67ac GIT binary patch literal 921 zcmV;K17`e*P)lZKjl)u z|0&?yWd*aq0(`wJQjb-!7MOtX@o~r0)Rd^GsMtXG3}_Gsd4f6Cu$DdSRV`p*V&W?3 z1!8Du$Q>LU{1kqWCzxXmYuUqI)dI%G#$x48Vj#6+|o+iyc<@0&C?y&fqM61%$-M$A3*oNcax_F}NEW8~drI zre@aRa0qX(CMG84vve>Ya0X{_rq2Qf2M4bJLE75dwzIRdXK=!gi;IhYhJ}TFOioUo zYi(_Hc6D`qA@sS%9BbH@nwt8&zP^5)KH*HiZo$C7z#Aq%0HqTw_kAwzhV)v$JzYiWdVqggrey_rS~M=H@+E;ScEf4Li*lfgD0DxB;TT zP22`|cXzk&1Mb`jdanbWG)wEVfbj6}`N+t~g@}jpn?OjsD=#lUiy_99mX`K|mhnY2Ha70TPAb+m1N|N_V9R&ycDp!FU0t0ELKd(i zGqjB5Tt-I53VQFTc@ka&PxN~Ii|Xp?!-j?iah{^0qQ%V2%xM|Mat=MN=;-J-oWWWC z3ebdxhJMJ;&v)Uk+rkd4;#nZhV=|fEr>Cb+%P^L56z41`DA?x=&f-j;1wegBRaMn7 zEWd=dVDDE}R&Fy^z-``4OiY}^Q|}cmW3EfJHq1DJ<-6e&HrTIQfFZ-c4GI9`Bp{UF zTfmJ2xnnRGHfR}3xg@E_EXDf)zm9RZ&cLmhgcaUkjiN{W_W)ilN;F^|hznp&qo`Le vps=ve6A!^I5QIM0Jk=_$%m0in1$g8yv3?9zY$BFI00000NkvXXu0mjffpfD? literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/import.png b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/import.png new file mode 100644 index 0000000000000000000000000000000000000000..5d724cbdd0330e0ac234748faa688468d47a0f1d GIT binary patch literal 988 zcmV<210(#2P)$bMGPt()WN9*hBCmS0ZT3B0K3)j@t1QQbz-I&vJEhQyodw6*GKs3>yhFW@*HKdWt znW17${n zYt)FIUiMJ@sHmuT>-BmySzKHUBbSR2V})7>c@o$-CrL?3H*jJh@hvPYcv!b$4r)YC zFMB9{OifLN=I7@%nVp^Wm`$jWJZ3YcrKK+Mcs!m%WE<;N%s~yc;$sh0TwLtJZZsJm zA3sF4nN65S1W$rbe7(KBucGO!(bw1aQhe3b)hnv1s>+8G(4@1o^Oe$k<% z)YSAen$8+^b#>3h*V5ARP&GC-`p3q`G^wqvePK1A9ue&RnfTD?Q8b+;F5`{*L42*P ztz+DPdvtVE6CCRY>+^~FZ%{+6_?nxWCn9JZ%;vzWyrsXt|Eu^$Mn>+a!NI{hctdH@ z-QE3-BC`qg-=Lea=muJ!G4b=;-LM z;m2nWSqmj4CHv{=>AP$~IA+bPf#)5)xN3KPetr=1Fzcs*U&i;yc4ZCRk#^k8?~!#Z zK>Lv%pfC=^=z9#Vs%U|``6_q}^cg%cw93E+CP65Ib{BZTZ53-YG&I}a zHc(N>1A8Wq`q$u_>rb(PNf6@vp962lza@|PjJWt?a3Q7V-u^$a7^EJg@9f#LU;{Kr(Tt1(0s@wR46q?b^YiD=S2#O6 z{{R`_fK34qoCo6lAR34K99LIYyap72%!rOqjVej6(%^<@- z2B>`d_N}q2tLv_>ukTkRv!lS0swdLLTpmpZCd~U002ovPDHLkV1jKGbGrZl literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/mail.png b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/mail.png new file mode 100644 index 0000000000000000000000000000000000000000..1713d40c060bf2ccee2ac2a09cffa42da910d3e5 GIT binary patch literal 568 zcmV-80>}M{P)`6+&*pk#3bBkd2 zBE^eTDg_f_T+JpRrcK{MkYwHbA85cP#x}Si5Hj$Wb$0eQvYk$c zb2^hhr_W=*LJ&|#{}4>h=1ka5(%sm&C;bcD zXN1oo0c0KFWJn%)fy@#<^Jjtugq<=Bt(ag$asPt8WB3`$ogOTTvV#-=0000)Eqs|6>4qdwaN8Z*MP< zn`-dB52%HwB*-tAfk8mQz``N2VEz8>8`D{{|Yz;OXk;vd$@?2>{|QPv-yt literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/bg_submenu.gif b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/bg_submenu.gif new file mode 100644 index 0000000000000000000000000000000000000000..fc77660ee663d1a415dcbf56540d290146865653 GIT binary patch literal 176 zcmZ?wbhEHbWMr^rIKsg2_U+qOuU=ihe*M9N2Y2t@y?XWP#fum3-@kw3#*OFCpFeu^ z=+>=UckbMI^5n_GhYz1Vefs9jo0l(NK701;@#DvrFJHcQ@80d(w_m(?ap}^fn>TM> zyLRo$l`F4bzh-~|#h)x-rVfY%+3CQlt03UvHC0ri+_YIWM?gIG{F9I~O&QXu42FIQ Z(umr;+o5m?Xj*6#? zV+coda>eN*2foO6Nlv&S@ULFPj%D#C1(Qu#DW)8TBEgI&r^>p;|BtW-s%P+Y^>bP0 Hl+XkKuhJeq literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/border_l.png b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/border_l.png new file mode 100644 index 0000000000000000000000000000000000000000..df27713055121a905d1105f17c4e4c9ca48b9798 GIT binary patch literal 249 zcmVNK0>rvd3;C00000NkvXXu0mjfS~+5n literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/border_r.png b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/border_r.png new file mode 100644 index 0000000000000000000000000000000000000000..fdd6dc6699d7418a90f22f706045fb40beb49cad GIT binary patch literal 253 zcmVSk!+zrx!6>i2 ztY;=K!`pA2RRv{r!*zXL%pXT()lp(xgbN3a-0R9amHu`3X5BqX00000NkvXXu0mjf D?AT_F literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/btn_bg.png b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/btn_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..303c12952684a30aa8d0903d42c3cddf6dbfaa17 GIT binary patch literal 87 zcmeAS@N?(olHy`uVBq!ia0vp^j6f{I!2%??LS)^6l$@uFV+hCf_3mj l3wbl4$&Bg~CCLQ&_>0QAirP+ZXQ*24NZL`V>4?T2XCLC^s4IG zhMflv9zK5Ji|9{WhJi;!* z@ji2=PcELst@*DeOJd4loBa&4Jfc}#4ssre6_1usdc5ZS+}@P@kQ1Fn8iwq z@?OgHN<1<{)!%!Y%$eB_g5EcI*K+K;b~bUc{)W_yTdA4SKc#24t?ST=EzrGTqoC+D zK{nW|Vg9Oq&DkOT%Yx4ClkU!lU3^*KTIml)jr-y6fBcEqByClst+F}H;@= zc!2!U5;r(BL)r>gP;WTIEjAX>5_23kA;Slz`ibo6kZCOuLdo000B)NklHtqOmq3dkMR-j{EN}yH75GylFBwa@b z8+1$741%H6F5PHl8lrW|T!9T;GMO=hB}&-Tn8{?oCWFD_{b14}(4Cu``+hvXd(J)Y zc`xy3fK$GuuuN{#=738C4REzNa$8|p`4(_!KL|L%SJes5$=zgAqZ%g}4wX?wZO|x3fLV z>ogA4heyd9pM1 zhC#KkyZs>YkOc11hErZ%`$1v%pxWLbJA>R^9i)}$Q+o_k*~aEex|WK3H`GW24_tDq z#-K5fTPcV~MbxTKk5pYMHa1UXdklSQ0x3wNu1vf_-3rR$B3jcboEJa<;k>35(NyF` zD)Tz6V6-U&BB}5O@bMI$Mm%LjR_+&I>8jjMDK=1V93?`I5R!>bxSbxr5%akq0Lp_&|(Gh8K^vf zxUkSfn(Q7ew%lu;q@UR{BkAC*i6ElE%r2|H_eVc#eP}^cn8oR?&_c}&Dq+w~Gy8WP z@oOQRz#HN@TB!f)j_eOv>22B;Eqo!xy49g4-fvwzJin=b${pP|Dq%d63o)xh&#K30 zk>Q^U7bOq3-5>MS-lhHAaU`#XtaBBz^OQ{IO<(NoysVsPxz0w8m4mx7^kh{RD=D5D zcEEtjv+kT3HnQgeHmwN#ow{xD)a|=9OyUK+^p#}?wSQ|=3lT?*tUyCGpyYn>;kQoH ztysT!=IgC1R12~C0G%wDe>m{T&sj|8=FANCqessyQ9FW!|5fNlhGdpbT1PM2b$<#V zpBFC(Q2Oh4ADz0&R?CyKtXhaN+t_80zl$jG2X}5?`DMs-m;O(@b3?>rjBfCjHMw@= zQ8VnA4)ozLicpMW{_okXSgh9bArGumDTR3%Vt^<4UGWghpS3%Bod_1ODV6mo( zplTt;6Sa3NZWWPN|8jY^zQeGHU^n(5UmI4t!E_!(b5AI zo`64u2u0?nLloL{3u-(`6e0OlH{D_&ap+liucOXlJq2(l5CVZ~8-(?KM77~sY;z$X zz_yW7R4dlIYK4zxZ?gKb(5>Xa(Ul$=ZS}TJq zHA_7iZ>^Z1WBFvv?2;BeTRBQcEf+Vlq#@VvS>itomMrO}*HG>0$-J35bAmnI_Qk*@ zJx(&%nBg$epp!2gaLAlx9s1J?`|%Dw;acd4-2NO&WNsMBVrzF5Lk8n`m9=ha>_gHn z*pBeQ66XtBw5Qth`Aal*Pe_J6p69n7&!~yv=*)T^H8=^0tEGIwW=yYEMb)(Vs>H$9 zx~`v{S}ix{9ux?}QxGjSKVC4OfA>DSBC%)`Dz(mCQFcInY{WC~faA2qat_b)t`|H8 z32JQ}eZO6sa8H(7CthOwnEGXdX4kGM;7>7~EuOYM3 zuo(ho7n4P73k028lYi%D;C-YLU>E{dy$0b+(21U}7CV++tx3uYfluMH8RfC#o^d21 zaE;3v;tjWyn6CT(q0t_Q_=kc&(3eOd|NEfPnbv4+R%O3W?uVSkMcITI9@R0 z?q{2^Z*6FJ!wvUEKlQW>x_zQEobK|^?(wFp*t0ft3$!1PEuNpFc>u*Yp)+M}=KoWwn6UXo^@%zzA zBD?X(dj6z^*bXt0aS#y*fgk)4idUh80xx3|yx~XGNa81BKZ*FSB>V>=&rC#_tbtqr O0000YH z0D^Y*AYBhfdtYY{Z|hju|4aK!Hk+|Em85|8xE4{xAAL-`mID zH_!AxD^!6aQ2l(X{{j%F{b%_vkq2~9io<_Sr~((D`c5-Am*GEu3{XLy<9{BgKoZc3 z2-p8yFh8x7asq1Uvii>rRWRQQ250VyAfim;BEHvs2)+P7g{zfnbt3LIKNvq5tYvY!UK&bj(zzgM))Fw{O2+Q&aO4#CCUg{|K~5jwTiX!3-c?2({=JkZr<1 zgr@UAydMdlCqhpM5Jy5S`VC}T6Jt>U5IZ2@0wVN))goDBLyScZ$jKCDz^Fx|7L8g& zyhUUdL8BI76siY4e*AcaRu&-_s?IN7yr`vlssplF?%cT(G_)-mP2O~~$jQm+FVJ9n znp@P>)pY}CusMcBz$WZpkbtYJ>%TW|-dqI=9z<*Pkb*Zr^PK{QMf2y+KZDe&e0k=~ znN*;JBU;OcSZo2cglEQ#8Ko!|fm|?c+O(%gjr5NpAt7r50s>Z$g98HtSNi+=9|xNA z6J(x`kIxTqyADX`0CCl!Lx(Pum6d()^78sgt@r|3`e((86`-gv1X;uZ#GqDx91!;d v@p2$u0mRG5#2~%vfp{CJSq#MSKr9IWWrXsZtL8yN00000NkvXXu0mjf2Is<6 literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/logo_symfony_profiler.gif b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/logo_symfony_profiler.gif new file mode 100644 index 0000000000000000000000000000000000000000..61d5f94d07c5b98abe28946293d7dbc7c6a33265 GIT binary patch literal 2589 zcmb8q`#+P51Hkd;*@YR)GrKerwuUYvq!N-bm)t^Hbj4Ykj5Cfjmuj2UP==CQE_0bA zVv?gJjieQFsSp(_$w7x4_3CSEP>(S;rsWMYPCA_ zNSLF&)4O-?dU|@URo7%mvU#TxRVvlU$cU%A*UZdJL4ILSAd?dneXFT?X=&;G`}aE? zc6oXF%+JqvbaaSP&-L{5UM(uVckftr2CVNJfCT!(wXL@zL;CO?^{#+8pan6ijw<}@1t5+ z=;0&v1p)#`i+3?ol9hef;Pf72v4uVdZ(>oLU&tni*XPnu2jF}5C1`-4www0NM)&Kq z8y+`7je|(VF$@gmiUR;6jC2MLH!^N7o`OSbJuA6i}x<|`Q`^|NW4!MWH-ReZ4qruBVR@H1ysNW zyGftz4?iU4+p{79{ClX|D*iNZ-U860pJlVh@Gg5J_SpZVz5mfT9lcX?V6BL^cI)qX zF!(d7XRC=xP8NB!4fRq9@(tNo-zUfoF$bS>(Sdk+Mt$GNEiT~^Sb-{Lz1u+0UM%sD zG*gQf`G)|>;7R*5a8N-X+8p|H*$=MZ7HbnZjVqlR1JE_!bCxK(VtR}cr*ewq2~{}! z6mEpmmY!3Rwn#UW$+7HbHnJf*YxwBY5#qMX7iRDu`5{u3(%gW7n zNBv#FkT`jfZn`}F7Ix33#u!a&!fbf9X-pWSztd#UcEY85Mfxh6z0i^ zp^ga~2q{*L4Y~e_ZgudfX&Cc?UTo0WT}^b-9h!(}9%E^!{Diwfp--rGDzXoIGWdiU z$oAx20StF$bUIC=)>eYtRnG!jdir9Ez(8Z- zH}le91k}hhmd(3>)T^A*EcU>74ur?V&Ifs{Pyd8Nkg(Sv`{A8kXO__(5~0>jr3rQ; zCZ@Km;Q;J?)Id96<^ z1TSXn_iS45&lLt@MeZY-@?h!j7206c<&#XG(dxI3>37Q~gzdXUyy#|aSbRzUSH@j& zN@;Don_*A)J=a&ma;$cGebTH;-ACb!t7=5!k`H=!GBzn<>t(wKnlhOBzVTr6;HF?) zAv4_UeY!WwOm%cHblQ=E4`n3;_&KsnWo76Bvp4 zUbW5pG>*20A5=*53D3jqbi>Ka6YD$7QDoRP7T?~sQ;HF{Zdf4qVAfD8^t{ilWknxP z_g|ib*+Pv@I?iyy#R{VLN&YX}4Di)>1<7|W&}fLoK-p^2NKFAsw3voKty}Yfq-9vT z5~~|mRcSOg+3w&(M;P;;YL=e7w$ngQ*JDQ|%2CZ{q*0)g0r2muc0aZ{G%canF|^RJ z>7nHU;6z>3dikQ#LBYN(jze#xZ+pU&yMkyEJx!#PM2>b`_*ugbiCujcPC>MhOKAK>js9*HJdcxXVi>1Wr`Ij5dc32TbQuxx_)NeOUN)ha1U`R@r zynBa-tloq%3p~63#DAAlV>R-=&jZRqldH*S3TAZN(DS=;Ahdtfy$jCVd9B%u5QttPyh z;H{LL)3U4BFYgHTtIV%Y#&x7Jm4cJ4&PZJsP1b3q>p2_CBHQaU_^vLUA|49RIpG|n zLqs(>g<0mOO%1nBZXJM@g)OetykOJPiRRl0UpG{jF5+*rEw`ZV2*>5|nnd#XFDToP z%U;rLqB8&OYu#_e6cUdsb-wxWJO2rJZs~k?TbdGN)vwH$lJXvZsLF^6;Z|mQJ%-Jt zOdYwkx8#kmS@D^$WgRK8bHmaN`$@m~gimU$=7?S^A{KD%csI#)96wwJG_qY24bP5; z?)WGV#eE(aD_Q2Zy+Q>;59T-G1`Y(k5;WHx|E0h*VnV$)T~@?Y;A-P8paD zr1JM8HV1q`OOlHcv{Z+y(zS1`L)gefliNoAW9*S3F*;XSrWc%R&}@i$S+y~@{{{ur zQ{J91`&3mDaXT|4x;;qQFA(^`;T)Y9^UUO3mXgog41ivc6;E+xuKoNXhEvy^my1?LV)x%Y~8Cp2ioCer~#|&Qv_9d^zGLiZ6?O#mV}i hY0Xb?;{51}>rW<5p#>W&)F4!o_eOI;XaWEZ{{sdMXSDzT literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/logo_symfony_profiler.png b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/logo_symfony_profiler.png new file mode 100644 index 0000000000000000000000000000000000000000..0d267cc0b5934dcfaa878bfca380ebf222d42bde GIT binary patch literal 2222 zcmV;f2vPTmP)2NKEYP?7_jogoB04%gmdaoV~rh#Kgq0v9j9Q+J1b0*x1=|Z*o^vSkKST zWMXBcq@~^6-P6<4zP`VUiHyw5%(}X|FfKCx|Nrmr@6CP%hyVZpFLY8)Q~&?}|NsC0 z|NsC0|NsC0|NsC0|NsC0|NsC0|NsC0|NsC0|NsC0|NsC0|Ns90TBSJm00009c5p#w z0003K0000!0CytY^#A||j7da6RCwC$o9BA!I1q;23$9=~p@a}pEc^a1Z#ARl62;_f zl4lp6?*|sPrDR@4Gb0&{S|fA2w(X3N%(mBCvmTQ^WD;#{(viK5#>~V=Abr{XSef`S z(JJ=G$i&RZr;5$7F>%*qP`NuQCSFEvQ0$F}$IlwKQC$dXd(TXUXU>_Dc!tKN!NhUznMp8!WI?@THkV99m<{iki93{YPT(eT4q*%R zzY4R7F_}CiqHS28F&TD~w4yq*_WS}~qIVQ;8U*GS7eqcRvwnIJbtplJQI?asw#w4@ zoJmZ2T3jyk=FF)I(vl{kOyfT&UP3~Co=LJR%Xj0YzKuyg>C96sMNV%F%O0zeTdLXZ zpG+zb@_OL^bckRSZeN@&ToC#ocA&VONf6XuR`@H6r%74L_AnEVv{gX#kj3jB z-&ZpcYd55&Y2A?h#XzEZ{nwamJIk7?Vfp-2ohoqxXVEKZDfpUoo@qwdh_KP`WtyF& z<XZu+>Mwfo#(R&pUEYjISewN0%$N{7?b+Dy=vgl060v{937{kNFr%D+*7SrU z_dMN<#5`Qq*HsCcAO>n^@=!8!54#d&EP;R&(ojr9|CJ>MG_aFRTG~|YG&2(+c5&Rm zv8}jOXMmyNo#@Ui_g<>`ORNM5LnHcbYrC&?9tIEDvQlw5E`_3AE_gO#s8L zKqfD%5}7O~U?^T$6soGrBsi+iqj_^HzbluB+3+@o?sT* zqC$&Zc0O*#lZ-;d(L6`?h+Te1h$yCbS->_B31~?_=_@ed0Kk0;c7;ND(J@)>00kfF zr7>Wa2~HMO%)es$L^SFKRTEvsnX)OfGeL&jdXKRWt~_4lwCa@zAoInI1C~F}p6E ztIZ?;!?_%cKytD~cxS}l$D+T{NFHDfFabA_4HP6C4U-r2E#t;pFjT*=sOs1qFC{5Ozy{MPac&Ql^ zwb5uK_42R+tF=rDsPYc9a6LSgEhc7r=k=7P8|fSAP&o0MOoHxmc`IiZ23$Rp*5g@3 z@*xwCmp&?^>`JEhnln*QP=G|wq`pFbRGUdn8d^LTNMXNdRIz)amD?}Zh!dJ3u&8}( z6N+1uB*rP(fB@wNNF@$bk4~3Z24ZeP@{Y?|qZUkrlBXTAvT7|8(2}hh%Lk*)BquG+ zFPBBT&VM92Wtt5Vq3o-B&)8optn0fWv9J>T{>rd$ccr)Y=o6h5yvWyR@bPE_!S?&4 zmc)w5kI4Ask=IdQ*bnc|i)G+9Y70~GH<&=~)M$^fWlnSoKXno_|JG;9F7CZ}zr-XW z8qEgW#2k2R1Bv+C%L0C?kW)ys`a8G8l4|V1&P=b;D01Ni@#iTt{n-uQ)(t wj7(5|-p7*r?udVzk1~VYmSHsy%z8xn2M#?biPf5D^8f$<07*qoM6N<$f@M`lDF6Tf literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/mail.png b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/mail.png new file mode 100644 index 0000000000000000000000000000000000000000..bdfa605520b0a3afadf5cad62027b7a235314637 GIT binary patch literal 1093 zcmV-L1iJf)P)Y z8^>id(;U|sm(bK2r*tF}vvS6J`hOQEMsynIj#mge@Mq?nx%WH2`z`0YvxhNek?QK| zEYY_2`474dvA4Us`$T(tyL($(+k@uj=JKYdCV4|cgGwTiydD`DIZfB>7AOzY+uLg+ zlgXS~TU+l-rP7xGdJCWh{LYN2v$OLF?mZ+5=z;Tai#KGVkL2;Tjv z(P-|$rj4bb`v?djOK53nc?zKB#>U2vw27sHx4DId1sUuPVINx|p!+*IIzj<7N(RMH zeSJNfot;%6ci+=|W@hF#_O&t>)D};x77LOzIXOA4P$=H%=SrpW5%#q<7xXHgR4EoD z@>>HBN(|Tf`ubjB-(%*2UR0@6&*tXllt=*`8A743yu3W-<>kd39UVoLv$OM;u&}VZ zl!B%}Posd^F;qzQw(03P%G#rLhw}&ijZ$G?BnA@>9AH%P@uIG zGAAd8cLa)c!-Heo+D;3-ju(t^W1u8gS65b9S;=Z@YIJUHZbFKNRa8{0QNg;qyYp*8 zKrf+NNdE>(LOxNKA&+o=etzZ@4dp%EOXoA?yI{~WQ&Uq#ra)_JYguV&Da**nVB_QC zEG8yqJ4M3=2M1YZW+p2sDWR^!Eb*w#;^Jbm9<-;YXOp40xHx{@)6=KQ^QGh?~Axq?9tLf&{e(E^k_u&HRMt;WX2ZdgO>V>n`1adGjMMKd}& z$|55p4MR;feyG*zF&7sXL7-NU11eiXpeU>j#^dATS$=;0mR>{k@}8!)8xgwtbtE;O6I-Rb! ztgLJZ9@81S9=15-`T#x!fu37lUVaS7Z|MDckMf}l3JTis&gAXw{VOps@w*VvBaj1> z1xXCN#Y2iAN(~{Pd!eJyB`6wa-=_Q$5%@cGMmj)%lE}6lK^prj@=xeD6T-hD>{$G#00000 LNkvXXu0mjf+fV`B literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/request.png b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/request.png new file mode 100644 index 0000000000000000000000000000000000000000..62cda7bf019f29472e30edf240ca69020e18fd93 GIT binary patch literal 1042 zcmV+t1nv8YP)>OZ=T5lrpPJAqabVSi3JG9p6aG6T4nCQ;;=s%{ z-h|KOFphYDDJ;c+rIW*=_un7)|04&@O+AodL`@D`1Zi2nYr$dT%WF_U z3K@k??yrQ80t9=LV#shhyX+&6;-=UqgwHkFMpP(mHrbZ zLHrke8(BjZ6;^^R3zn3m?<)+4FJko#sl#-iwBII7g8P|Nb%F=>8BUUY+X-gX3W7^5 ze?s@+SrN(zragyXczs>C=nqoQDizm9{gY5IiUwn2`W4T1bl-h;pAIAQtyZim}9zyTZlM~#OJ zDq}|rMDYD{h0sj*`BsP66B*P@+?A}So^5gPw8I9D)a#Vy($}M|TTjCa^C83z>_Q3_ zz;|=YsHU(g&6@7P3Pjb(>3GF)#gff)$%R1-wp-NO`&?3{R^ty}1QPQ*vNYqmODXEL z)eIMvH*aj`J7X1%RY-#Ae2@obA!Hj_K({2r`U}~zEO~lk(hGOxo2&OEYv07%=ljgV zxADsr9oJEUIz&_Dv_xcJTIk|Fh_%;wBp!*)riKIplor}6r0WMn+6%qlF;iI4L##zX zwv{x|L8O3<>4@3WMJYE+Fpq+TJg>~PGC_Uy%AiE#-fAw1j5~5_3#P%dHBn@?AC09l zmV$XBq5n*tGoO_fDzh#teO+#K=Gkh}ARZin(Rs3#%!}Do$&S5s3um#BouAS`;9w;t#r` z>Nc`b3^h^X35tdJ5Mw9K=Fs9l*@^GK#X^E|;@Aknas(ixXQ$N2b!-IEfnF(s5r{~l zvZ+3XkKl(zNdJPg`s%@sr@Kgu>Slyt2C0Ja177$H<+y@2Vn3k_pJLWKx^wvN4cc}b zLJ_L&|AX5R1WtC&mF^@zp-L?ISIm`=TY3o?4o$uT9H`Tzg` M07*qoM6N<$f*-f;hyVZp literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/routing.png b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/routing.png new file mode 100644 index 0000000000000000000000000000000000000000..27df877ff2392618a12b2704e06effe19f52ebd9 GIT binary patch literal 696 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0VB`z%330WzxBpK%ShZ>uT+@;z zOWqPkdV;W*f?|M%<}SbZ*OlOAD`ad-pP|EdwP1h zy1Kf!xB!iEa&ig{4RvsE05U>CLV#>wH~^*U^f}G|11O>-$S;_Ik%^g=jh%y&o0m^i zOj<@>K}ktjRn5T2#LV2n($?O=!NtqRFCaE9K0CjlxTLbGp`odzr+@0=Wh+*%+pu%j z{)0!)oV|YQ&fSNPpTBtd>eIKMzkdJy`}dz<%dX?V&}Z~?aSW-rb@t-TphFGGsWJis OoWax8&t;ucLK6U4)pJ?^ literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/security.png b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/security.png new file mode 100644 index 0000000000000000000000000000000000000000..8f3b4ea3bd1ecd8b45ed8f349a320d9df9a73611 GIT binary patch literal 994 zcmV<810DQ{P)(t7K+01!mnmtO#BG3 zviZ@5`8mxYtW`Eyj(M>{LE8eisk#0qUSqtNZ)-17;KiRk?|II7p5LDHob!$ybGzOD zg^ob~IndD1P+#OT=;^q)I4u@(AC_o8+Sgmq%M^UrqJ6yu4cQCUYPA+TPeNmiUb|eb zar&fZmL|#H2hb32LBl+Ps~`c{ps1FXmIqN$Q4WDXU@tB%9-5k(62l(B%nQhWKM0{v z=&q=!a5XhG+2wM%T_%$`5)u-2S)gIQfC?ag#(pk2Ir*dK;)#ig?_m$5!eIOaY{=5m z(#`et^_hu@2~BHj>uhapt)Zu6S7n5J_y)a+l)KoVNWX|qlMN~oiMDMvn=(B; z-GVgRbUIy+)oOjB*XsvVDwU?QvvW8tE$y?(WE$if^hRD@-YVzv{r&yV0JV~un)(&?JAgKlU8B(`F;`3DhK2?`zHA@gsrTR5*ocdXiTMeN zyY~&YSm@M#pjA~>I)y?pMQO!7z6Z(s`ufJ(+uNI$mzO0S9UY?vgF%7L!CNu;)z{ab z5sSsQ0jJxWBY>Qooaay^d`_@Ik=m`LrKQJ+vr^wJDJgliSN)lpnYzNl!da?(zS>hn zb#?W1EcoT1w+cW$)YQ~mf`7QDJvTSkh%7t;q=_99A0NMozWNSp@A3h9DU7_OS15`pSD=T}8!uk{$8M)2dE3~VttBv{`GzyI!pkb&+sZ_R5oEP#P^lx)y3EocyQA5wW#^&nIZ zU1U_w*v2@;9jjvY3-T5;fC&nQ!aQ^h3MA2(v2lw#HkjEj;OGyCBT$xp03qV7(1w$i Qi~s-t07*qoM6N<$f*l3ov;Y7A literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/spinner.gif b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/spinner.gif new file mode 100644 index 0000000000000000000000000000000000000000..6954f42e8232f8f30c1ca480a20ff7ef9ff8af87 GIT binary patch literal 1505 zcmY+^YfMvT9LMpex6@O4fnK3X3)ET)R0Qb|wVHZ*Kyh?C3)yyXzQA|S+fTl~=f7oZOw_t` zAK(N2kO4B0oVqjBcbV_pPjgKtn;0yHR3@GObKc=}G&M9yCDQrV^E?4h5vm|V~M4S0kf0M<>Q7cpP5GXB`6<2OOsz3=c+Oe&NDD3x&mnieSa) z*yzIF3+6I&MOB3<$CR0sIs0N(xkjm4uj**)NKH=F>a+tx0~O^JHmeOq(208!vp>vE zKcB|**!0tBED7uF>(y@4PCcALW6-I`Q<)i=wmO?KQmNXc3iy|S| z06@TBWEuoyK!Lw;qz?elxVkYfI~lF1efTogf-gb?Z9hXltqp(TKP2*K=qLVoN@EUAXw=1u->wAe!h)XrYz6Y5+{90O;g73A3QbFKvZOYD3swX@*n6 zG)501$OYW~6zZe2eW-8-8ZDl9lENYGq0Az*=^sI9YjzFxI0c@{Al4f5Ukz4 z%B|xNF&0zVr;$LM5;l*L5gOfC&W4ke7I#L1*ISfuDeAi0mM0&v>mkkfywR)mK?_O! zMMey}D>6dgv8x_OO*)<87nZYU1v&TWS(ilOnC|I<$;X{PBZp8fCbAUK8M~>~DV`YZ zXo5h7?QPIVSp-~UN0~qlfuOS*T+|#v+YL zF<$&|iZ}`|zD6UITuJo?3O_E;2ZLZ;QC>WUn24Jc@)h<)5ymQ;heMb|;+(((BF1YQ4@ z=+2t>tYZdzc0}4o2l$dVvrAf5g}_O$EXiC?PYS_F^%^E%;-pqQkXJ|8d44z10rj0@ z?gV9a76=h0ky|;9i!+qei#Jko{Xk@8eF~o)QqZTFER;Mgf?FxUFM4w(ZvIromSlPBz&_Z2Z7ivd5{YvP;ZB52+ zB_iCk7h~{`hyRku;!RnXT*D-8;gP?-s}C?-(yzV!1{X-pfW-`4=44a`hsOIIzg7 zq1I3;8;wT*+-zj)2~H!9YS(#2Zi-T^?b3>a0OZoD^!6bip`JW!rVKPROGxh{e)<*d zQWkR+!anF|z6uy5jUb;ZDVC=4wZi-yEghDpwruARp}SS`{3kD4`_aoE^PalGm?r;U J??_>=;XgR+=cxby literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/time.png b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/time.png new file mode 100644 index 0000000000000000000000000000000000000000..3250e11944f0099e5eb958c70bfb7981d76c7789 GIT binary patch literal 776 zcmV+j1NZ!iP)D{o!y|ga zR!k<--F!a3V@u*xDm93q%QBNT(ChUS+LO=~i?L{8UD75GD3I?a$5h=%oT!^vcnu#K z`FaJ&>fdyFK0Q5s0kMLP;-#gfJ!-Xjg@#y0o{`ZJW7<9-c6TRnFaFt063m{M;Pd%h zq}MItVXM{pk}I*(=}aMhSBtn@E+0`S6cw(-I-Tw_;tw>7d*bo<1PNkaOehozXX;z- zMzJUoiCkqMJ_>?>YS1~&(&_XBe&cTxOJcFu6a#TTk;@u%PP2uD1smB)8)DqN%s|{i zrzt>j`MJ8fs%;kc0<}t|`auF&$7nQufkO^@ep_5%)a`b^=SuAHc$VQf*)ER{MWfLe zSK?$c`2ddn?ZiWsO63yD**CVOsLyL?{~Q=-Cl-R!$mi#5O0lTwY4jLvkF;)?4Tix* zzu*6nEpaFmdW$wE!QiH45gf*l&!S+I{#5GqdOxAP>tw6scN7!)z$tKhZfF|cb z;d&{&1xC6b1R6-l(!Y_-W?!JP(9Um{%k_P6aWRW$r@%2F-s&k+1P%f_xR=RfUI&B0 zGLA*nW*N$96?0k2<#MkOdk0v+KCqqX@m2taNbe_s4@AJTVzD@1DwXDOodgfTEU<#( zr0(+Bc#{x-0n&>TKnBhdq+}lVlAwQ_yiu4Hhux{q<0kGTc?8n0000F zzp^XpXx0ewM`RzGrLnXbng-gI8g`pc@0{0BZsK3h;atu=&w0*)^Pa<5q0$>HH&Jk@ z+|(Pq3<9|2n+~5T5H!juu-Ygu5Tu>G91gB;nqNh8 zK0-Q7!Iw&h^$}jXBA~E}!ctmTg#d5F&?m(rC!2KKsdE^=*Elj3A|hvd2|~RQLmpqO zwz`wFjwu>9putT?n|j(EtG3dY5aNZXFtN3BW|$fzJ7S7XT6ZDUu1{xJMA3@CMZ^Rr z3)j7d93H~CYX9!LA5vf(pKSm`4wX_FA+#;fImIbdGvF&Z1 zj3FIoEk%efZD$eTERv38q+LLeGFSEhyg6dYAPXNEu}6XGduXt|qmld}E@gs6N(LcS zwo#A|3K`KPwz{XPw!P5V-3i$(@3-S1av^&Yt9J{UKQsT>|osn);>8P|0-Le#w2eagSoa>Xt2i*!luZCJ8axGv zFDBnC=Bok81!f8apH?=dzjS#iQ~E4&9axW)NquwQNJqcfL+m$?bTs$b8<2{~nVeUa zvL7t+>=P=nckUh$iv7sIA>^q?-Jp6DdE`G6aR@^YqHxO4N#XkVHA3&KLp(Oj-z5C8 z4uRMK4QMuSq=#YIo1S00000NkvXXu0mjf*^pR4 literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/routing.png b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/routing.png new file mode 100644 index 0000000000000000000000000000000000000000..6c620bfb5a1a55b0847cd18107ca1b8659316a3f GIT binary patch literal 337 zcmV-X0j~auP)ky^G7nE0Gk0I93LOw%McS2GaFgZ)z$R}P*X0F0S&kesH&=3#ZXjKv;$et z-QE2+P*V*d17^*dbss2~4Dv$Ogb5R#;xV8Ai2H$fKN4OC#3ewi3o^hEh%1430}$^4 z;x05VBp}=D<>mF}*s){LKyd|lAVN77Kn&8MM<@_IJw2bCKYv~VUo<-43Ijhszu&ue z@16-1R{~;2VhlhI1CSTz0dW`*ixTUC03bF1i2<=4lr0Lx%)}btKu%J&&dA7k3Bn*Y jIR>ah;~9k2@fiRBN=VE9ZwhAW00000NkvXXu0mjf4MlwL literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/search.png b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/search.png new file mode 100644 index 0000000000000000000000000000000000000000..4405064ab227a3c905905360a05293e08a423eed GIT binary patch literal 785 zcmV+s1Md8ZP)jn9dCz${Np8GXBO?FR?Errz zu6Z>;5(@Ad-fApp9_zkd)&tZ*s#Sov)=Z5X z4R9wM4!;^59sRVsyX)@l?a6hx&N|k!4>_X(4^S74M$7B#>*tk9Mf_qt``C|j1HlG} zL?Y?6wYBqdxh#tB@(9s^CNLTu&5MV9?AMw=12hZ`4Sn3%*%2z0N|%UP2!pvw^I6on zUJv`R&pjO5575%m@&Xr_TPzkuJqP0h>x9_f*4CC`-g1Mot6u(-H*i73?9*LR|Kyb#XKRm^jp zbzTqpe{&xQ^p}udLwSBR!$J5i(QFsp$#MIPO zwWp^?hY0vUGC4UJfgD_bTu0X{;MV3RCMK#~U0t<9*gukukB?Imyo3Wd1JQV(`6jJ% zzy(qKB~?2+J2^yupaD{;lr0Bb5YO1yShc;q{RrDVvK{~zSr87mAfAztk!ove>!Ixc zygdiyfD7VDBoaTZ2f)+KO*r6!5T2kvTMsZeICxV};Y>Zg{nzYvfUEuhvoJY4k!qI+ P00000NkvXXu0mjf-zaj^ literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/security.png b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/security.png new file mode 100644 index 0000000000000000000000000000000000000000..fff6dd2eae93a991a5753a5b3d283413aabb42bf GIT binary patch literal 808 zcmV+@1K0eCP)Od}MALrH}s*_7rBD+j(0Syl)RL70(A z%MsyR7fvxSbf#95$~uAGR65-zZR`7k^T3d^jUeeF2OqZQ`~3F%ob#OL*$zdc(S7AW z@Sg}$@cMfKsc~y2{JT zJ^lUtB$QE3^RW$bb8{n@-*h+}-$q78*6FiCp@_uvlaPR8fzae=V`HN>wvoYLP$54; z^DL{VsMz&-y$iLqwR~P)-nL4m+N!Uw|BP%gKR-V#^yBslIB>#jHuvrk+^3w?W@l%I z=jP_7b8>RF+S=Nt$MNdu=$IWI9)1e(N2}HPC6VCF;NYMoR?ySaV?%zH)iyUbZ{TW| zv4pEWpRW%OG-$C{#=E+@9FYF7+wHFt2~tC$&~=SQvrSoXadD96`J2d3v)bBJG#VGH ztE=D4%*^ycc|^9*@U{9p}Zm?_eo^ zHZ(LWjgF4aW@KcD3;ce+j^ntnm;hI{h1wf?vXEY{U$)t7UYvoIs;VlU&4~(d+h&aK zf)`*ihUegp%jGg9JH2rQ`+&FrxBUwTYn4zcmBD09)M|AEhb=(h1V@qzuqy({hQLE? z(RaxNPN#DjwGY4}{2r}}2_z*YC7TqmEr?7F00002e+feX literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/symfony.png b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/symfony.png new file mode 100644 index 0000000000000000000000000000000000000000..6b66c424b9b1d78e05f6cef0f0c00a4594e73a9d GIT binary patch literal 1332 zcmeAS@N?(olHy`uVBq!ia0vp^Qa~)j!3-ol&c;7vU|>oK@Ck7>&@=i^I%sKb18VB+ z?wdYs23+@wnK=-~vZc$BHNq7@1pR#jfsE3UGGsMC_JaoxfTXXF ze@A;4L<;CI2&1f|eBy*jPo6wEefmslavDT%&g{7m#?GC)fQ%O}UO>24u3P~!oE=?q zvU69jUbANP+Qj%Iph$ODPjFzUqrJ0>lUrtb*0E#9fr8mtxj^#Go41oDPL7XDEG#Gj zI)2BFou^Kn28IbRD9TGKfbNM1iv$`4v~lg4b!X3>v$3*^jgG6SuA4h&o~^b0`STZ& z5|R(>KLE7!!uboK!C{LQE_QeIJb3U>cxa@Rg^j1XcX?UmlEq7b8ka6v2Gp`;%htn( zjs*AxR#(*m$wv<#0Udet=rN!RfkqYN7uD6)o10p?I=hDih3?qC186nSRY2`Pm-P2d z@b>hbH+OziWQ@I?BhW`c#{kVYF){-hWom35;2#tl6A$!SWkpq6YrC_PE0AGkY60|k zU_da?%-rle3o|P>7Z0Fymgd$#D}c7=<>Uk140Jru0oIl_9&Vo2mbM=5UO-EMsSD_4 ziIUuMV6r<^666=mz`)4N!pg?Q&BMzlAS5gzDJ3l}tDvZ)qNb*Vrpq+ zZDVKe?CRm=?c?Vk5D**{9T%67l#-g3nUh;kP*_}2QdU`6Ti@8!+}7RK-#=mE%vrPM z&YQPj`HIzR)^6CaVbkU zx^?Hy-Me=mK791(>C~P0{Q2`2 z5d8lA`_G@hfB&77bJ-5`%~nqr$B>F!sh3j2Ljon*9+sbz8g`S%z}xF4N-Dt?3Q@PP1 ze(|1;v+P-#b8kl3BZI}y!}iZt*x8rsdg#n{mbNlo=ZV$_ z=3mO%#P;ry+k6+PrQzMoBC6|@%oB}HRi9+F__m?!^A~=d*W37>uF^UFte&sueO%in zcehYsAqk_28+=~woj+l-r>ll}?W40Rn0AzjZ`!`#itY;yxAk+Xe%O?&Z!Z%rQ&_oj zhmEFsqj35>HV*6QVyip7^JmxXnb+2(e$+kkw!y9byI=Y^?(?UW7|n6r8U6E_ye@y- zzrPh#fnL_iTb$QMP8Te`CO+j(bx6>L!iO{D40mmIo_$YgUwqN4DJvgO`d$8Q$Klt! k*Ir2EuThT*=l{=Ob*=M|$G)3tz+}nb>FVdQ&MBb@0N#S`-v9sr literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/time.png b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/time.png new file mode 100644 index 0000000000000000000000000000000000000000..d7c2e7dbb9405c3fe63e3012bb9c165585e8fa96 GIT binary patch literal 482 zcmV<80UiE{P)Kj@h+2dohY%qeI?BZ%p`bxp z8X6jcaEQW7f>cVb&l_F{o}OtCbnw8zeV^yJ_kIycl1Ab`1j^;IA{L9K-bs(S-wddu z9>6u}!r`#P?RKBoY&H>RmMGYN_INxwj^mawqwRELQIpAJOc0Ay=m$c_xm?aj9qN9` z*=%;kZnrIv>T4VWvH%D&I%`xsOX27^se6u05d(|`du5IKs)VhuGp zkx0DNYPAD6Rxn8e8ejygV7E{x++lH=xI5nx%d%23nQW9wrCZGKfB{p~m0#yEU;t*o zfjw|qtyV8_whQbFUF7Qrkq0^J~=H2KoBZ8W{+{{Fx4 Y37#u7c<*%S3;+NC07*qoM6N<$g4T`DZU6uP literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/config.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/config.html.twig new file mode 100644 index 0000000..2793be5 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/config.html.twig @@ -0,0 +1,164 @@ +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} + +{% block toolbar %} + {# Symfony Logo #} + {% set icon %} + + Symfony + {{ collector.symfonyversion }} + + {% endset %} + {% set text %} +
    + Symfony {{ collector.symfonyversion }} +
    + + {% endset %} + {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': false } %} + + {# PHP Information #} + {% set icon %} + + PHP + + {% endset %} + {% set text %} + {% spaceless %} +
    + PHP + {{ collector.phpversion }} +
    +
    + PHP Extensions + xdebug + accel +
    + {% endspaceless %} + {% endset %} + {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': false } %} + + {# Environment #} + {% set debug_status_class %}sf-toolbar-status sf-toolbar-status-{{ collector.debug ? 'green' : 'red' }}{% endset %} + {% set icon %} + Environment + + {{ token }} + + {{ collector.appname }}{{ collector.env }} + + {% endset %} + {% set text %} + {% spaceless %} +
    + Name + {{ collector.appname }} +
    +
    + Environment + {{ collector.env }} +
    +
    + Debug + {{ collector.debug ? 'en' : 'dis' }}abled +
    +
    + Token + + {% if profiler_url %} + {{ collector.token }} + {% else %} + {{ collector.token }} + {% endif %} + +
    + {% endspaceless %} + {% endset %} + {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %} +{% endblock %} + +{% block menu %} + + Configuration + Config + +{% endblock %} + +{% block panel %} +

    Project Configuration

    + + + + + + + + + + + + + + + + + + + + + +
    KeyValue
    Symfony version{{ collector.symfonyversion }}
    Application name{{ collector.appname }}
    Environment{{ collector.env }}
    Debug{{ collector.debug ? 'enabled' : 'disabled' }}
    + +

    PHP configuration

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    KeyValue
    PHP version{{ collector.phpversion }}
    Xdebug{{ collector.hasxdebug ? 'enabled' : 'disabled' }}
    PHP acceleration{{ collector.hasaccelerator ? 'enabled' : 'disabled' }}
    XCache{{ collector.hasxcache ? 'enabled' : 'disabled' }}
    APC{{ collector.hasapc ? 'enabled' : 'disabled' }}
    EAccelerator{{ collector.haseaccelerator ? 'enabled' : 'disabled' }}
    Full PHP configurationphpinfo
    + +

    Active bundles

    + + + + + + {% set bundles = collector.bundles %} + {% for name in bundles|keys|sort %} + + + + + {% endfor %} +
    NamePath
    {{ name }}{{ bundles[name] }}
    + +{% endblock %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/events.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/events.html.twig new file mode 100644 index 0000000..6fc8f6f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/events.html.twig @@ -0,0 +1,61 @@ +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} + +{% from _self import display_listener %} + +{% block menu %} + + Events + Events + +{% endblock %} + +{% block panel %} +

    Called Listeners

    + + + + + + + + {% for listener in collector.calledlisteners %} + + + + + + {% endfor %} +
    Event namePriorityListener
    {{ listener.event }}{{ listener.priority }}{{ display_listener(listener) }}
    + + {% if collector.notcalledlisteners %} +

    Not Called Listeners

    + + + + + + + + {% set listeners = collector.notcalledlisteners %} + {% for listener in listeners|keys|sort %} + + + + + + {% endfor %} +
    Event namePriorityListener
    {{ listeners[listener].event }}{{ listeners[listener].priority }}{{ display_listener(listeners[listener]) }}
    + {% endif %} +{% endblock %} + +{% macro display_listener(listener) %} + {% if listener.type == "Closure" %} + Closure + {% elseif listener.type == "Function" %} + {% set link = listener.file|file_link(listener.line) %} + {% if link %}{{ listener.function }}{% else %}{{ listener.function }}{% endif %} + {% elseif listener.type == "Method" %} + {% set link = listener.file|file_link(listener.line) %} + {{ listener.class|abbr_class }}::{% if link %}{{ listener.method }}{% else %}{{ listener.method }}{% endif %} + {% endif %} +{% endmacro %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.html.twig new file mode 100644 index 0000000..a684d1d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.html.twig @@ -0,0 +1,30 @@ +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} + +{% block head %} + + {{ parent() }} +{% endblock %} + +{% block menu %} + + Exception + Exception + + {% if collector.hasexception %} + 1 + {% endif %} + + +{% endblock %} + +{% block panel %} +

    Exception

    + + {% if not collector.hasexception %} +

    + No exception was thrown and uncaught during the request. +

    + {% else %} + {% render 'WebProfilerBundle:Exception:show' with { 'exception': collector.exception, 'format': 'html' } %} + {% endif %} +{% endblock %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig new file mode 100644 index 0000000..badce63 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig @@ -0,0 +1,75 @@ +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} + +{% block toolbar %} + {% if collector.counterrors %} + {% set icon %} + Logs + {{ collector.counterrors }} + {% endset %} + {% set text %} +
    + Exception + {{ collector.counterrors }} +
    + {% endset %} + {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %} + {% endif %} +{% endblock %} + +{% block menu %} + + Logger + Logs + {% if collector.counterrors %} + + {{ collector.counterrors }} + + {% endif %} + +{% endblock %} + +{% block panel %} +

    Logs

    + + {% set priority = app.request.query.get('priority', 0) %} + + + + + + +
    Filter +
    + + + + +
    +
    + + {% if collector.logs %} +
      + {% for log in collector.logs if log.priority >= priority %} +
    • + {{ log.message }} + {% if log.context is defined and log.context is not empty %} +
      + + Context: {{ log.context|yaml_encode }} + + {% endif %} +
    • + {% endfor %} +
    + {% else %} +

    + No logs available. +

    + {% endif %} +{% endblock %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/memory.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/memory.html.twig new file mode 100644 index 0000000..ca6d3ca --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/memory.html.twig @@ -0,0 +1,17 @@ +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} + +{% block toolbar %} + {% set icon %} + + Memory Usage + {{ '%.1f'|format(collector.memory / 1024 / 1024) }} MB + + {% endset %} + {% set text %} +
    + Memory usage + {{ '%.1f'|format(collector.memory / 1024 / 1024) }} MB +
    + {% endset %} + {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': false } %} +{% endblock %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig new file mode 100644 index 0000000..fa43c50 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig @@ -0,0 +1,161 @@ +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} + +{% block toolbar %} + {% set request_handler %} + {% if collector.controller.class is defined %} + {% set link = collector.controller.file|file_link(collector.controller.line) %} + {{ collector.controller.class|abbr_class }} + + {{ collector.controller.method }} + + {% else %} + {{ collector.controller }} + {% endif %} + {% endset %} + {% set request_status_code_color = (400 > collector.statuscode) ? ((200 == collector.statuscode) ? 'green' : 'yellow') : 'red'%} + {% set request_route = collector.route ? collector.route : 'NONE' %} + {% set icon %} + Request + {{ collector.statuscode }} + {{ request_handler }} + on {{ request_route }} + {% endset %} + {% set text %} + {% spaceless %} +
    + Status Code + {{ collector.statuscode }} +
    +
    + Controller + {{ request_handler }} +
    +
    + Route name + {{ request_route }} +
    +
    + Has session + {% if collector.sessionmetadata|length %}yes{% else %}no{% endif %} +
    + {% endspaceless %} + {% endset %} + {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %} +{% endblock %} + +{% block menu %} + + Request + Request + +{% endblock %} + +{% block panel %} +

    Request GET Parameters

    + + {% if collector.requestquery.all|length %} + {% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': collector.requestquery } only %} + {% else %} +

    + No GET parameters +

    + {% endif %} + +

    Request POST Parameters

    + + {% if collector.requestrequest.all|length %} + {% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': collector.requestrequest } only %} + {% else %} +

    + No POST parameters +

    + {% endif %} + +

    Request Attributes

    + + {% if collector.requestattributes.all|length %} + {% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': collector.requestattributes } only %} + {% else %} +

    + No attributes +

    + {% endif %} + +

    Request Cookies

    + + {% if collector.requestcookies.all|length %} + {% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': collector.requestcookies } only %} + {% else %} +

    + No cookies +

    + {% endif %} + +

    Request Headers

    + + {% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': collector.requestheaders } only %} + +

    Request Content

    + + {% if collector.content == false %} +

    Request content not available (it was retrieved as a resource).

    + {% elseif collector.content %} +
    {{ collector.content }}
    + {% else %} +

    No content

    + {% endif %} + +

    Request Server Parameters

    + + {% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': collector.requestserver } only %} + +

    Response Headers

    + + {% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': collector.responseheaders } only %} + +

    Session Metadata

    + + {% if collector.sessionmetadata|length %} + {% include 'WebProfilerBundle:Profiler:table.html.twig' with { 'data': collector.sessionmetadata } only %} + {% else %} +

    + No session metadata +

    + {% endif %} + +

    Session Attributes

    + + {% if collector.sessionattributes|length %} + {% include 'WebProfilerBundle:Profiler:table.html.twig' with { 'data': collector.sessionattributes } only %} + {% else %} +

    + No session attributes +

    + {% endif %} + +

    Flashes

    + + {% if collector.flashes|length %} + {% include 'WebProfilerBundle:Profiler:table.html.twig' with { 'data': collector.flashes } only %} + {% else %} +

    + No flashes +

    + {% endif %} + + {% if profile.parent %} +

    Parent request: {{ profile.parent.token }}

    + + {% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': profile.parent.getcollector('request').requestattributes } only %} + {% endif %} + + {% if profile.children|length %} +

    Sub requests

    + + {% for child in profile.children %} +

    {{ child.token }}

    + {% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': child.getcollector('request').requestattributes } only %} + {% endfor %} + {% endif %} + +{% endblock %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/router.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/router.html.twig new file mode 100644 index 0000000..a37ffe7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/router.html.twig @@ -0,0 +1,15 @@ +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} + +{% block toolbar %} +{% endblock %} + +{% block menu %} + + Routing + Routing + +{% endblock %} + +{% block panel %} + {% render "WebProfilerBundle:Router:panel" with {'token': token} %} +{% endblock %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig new file mode 100644 index 0000000..cc7552f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig @@ -0,0 +1,459 @@ +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} + +{% if colors is not defined %} + {% set colors = { + 'default': '#aacd4e', + 'section': '#666', + 'event_listener': '#3dd', + 'event_listener_loading': '#add', + 'template': '#dd3', + 'doctrine': '#d3d', + 'propel': '#f4d', + 'child_sections': '#eed', + } %} +{% endif %} + +{% block toolbar %} + {% set icon %} + Time + {{ '%.0f'|format(collector.totaltime) }} ms + {% endset %} + {% set text %} +
    + Total time + {{ '%.0f'|format(collector.totaltime) }} ms +
    + {% endset %} + {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %} +{% endblock %} + +{% block menu %} + + Timeline + Timeline + +{% endblock %} + +{% block panel %} +

    Timeline

    + +
    + + + + + + + + + + + + + + +
    Total time{{ '%.0f'|format(collector.totaltime) }} ms
    Initialization time{{ '%.0f'|format(collector.inittime) }} ms
    Threshold ms
    +
    + +

    + {{ profile.parent ? "Request" : "Main Request" }} + + - {{ collector.events.__section__.totaltime }} ms + {% if profile.parent %} + - parent + {% endif %} + +

    + + {% set max = collector.events.__section__.endtime %} + + {{ _self.display_timeline('timeline_' ~ token, collector.events, colors) }} + + {% if profile.children|length %} + {% for child in profile.children %} + {% set events = child.getcollector('time').events %} +

    + Sub-request "{{ child.getcollector('request').requestattributes.get('_controller') }}" + - {{ events.__section__.totaltime }} ms +

    + + {{ _self.display_timeline('timeline_' ~ child.token, events, colors) }} + {% endfor %} + {% endif %} + + +{% endblock %} + +{% macro dump_request_data(token, profile, events, origin) %} + { + "id": "{{ token }}", + "left": {{ "%F"|format(events.__section__.origin - origin) }}, + "events": [ +{{ _self.dump_events(events) }} + ] + } +{% endmacro %} + +{% macro dump_events(events) %} +{% for name, event in events %} +{% if '__section__' != name %} + { + "name": "{{ name }}", + "category": "{{ event.category }}", + "origin": {{ "%F"|format(event.origin) }}, + "starttime": {{ "%F"|format(event.starttime) }}, + "endtime": {{ "%F"|format(event.endtime) }}, + "totaltime": {{ "%F"|format(event.totaltime) }}, + "periods": [ + {%- for period in event.periods -%} + {"begin": {{ "%F"|format(period.0) }}, "end": {{ "%F"|format(period.1) }}}{{ loop.last ? '' : ', ' }} + {%- endfor -%} + ] + }{{ loop.last ? '' : ',' }} +{% endif %} +{% endfor %} +{% endmacro %} + +{% macro display_timeline(id, events, colors) %} +
    +
    + {% for category, color in colors %} + {{ category }} + {% endfor %} +
    + +
    +{% endmacro %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/admin.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/admin.html.twig new file mode 100644 index 0000000..2488af4 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/admin.html.twig @@ -0,0 +1,27 @@ + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/ajax_layout.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/ajax_layout.html.twig new file mode 100644 index 0000000..3e2f6f0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/ajax_layout.html.twig @@ -0,0 +1 @@ +{% block panel '' %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/bag.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/bag.html.twig new file mode 100644 index 0000000..b85d744 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/bag.html.twig @@ -0,0 +1,16 @@ + + + + + + + + + {% for key in bag.keys|sort %} + + + + + {% endfor %} + +
    KeyValue
    {{ key }}{{ bag.get(key)|yaml_dump }}
    diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base.html.twig new file mode 100644 index 0000000..0198e7b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base.html.twig @@ -0,0 +1,16 @@ + + + + + + {% block title 'Profiler' %} + + {% block head %} + + {% endblock %} + {% include 'WebProfilerBundle:Profiler:toolbar_style.html.twig' with { 'position': 'top', 'floatable': false } %} + + + {% block body '' %} + + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig new file mode 100644 index 0000000..d6cd784 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig @@ -0,0 +1,72 @@ + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/header.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/header.html.twig new file mode 100644 index 0000000..ce548de --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/header.html.twig @@ -0,0 +1,25 @@ + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/info.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/info.html.twig new file mode 100644 index 0000000..d35f91c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/info.html.twig @@ -0,0 +1,43 @@ +{% extends 'WebProfilerBundle:Profiler:base.html.twig' %} + +{% block body %} +
    + {% include 'WebProfilerBundle:Profiler:header.html.twig' only %} + +
    +
    +
    +
    + {% block panel %} + {% if about == 'purge' %} +

    The profiler database was purged successfully

    +

    + Now you need to browse some pages with the Symfony Profiler enabled to collect data. +

    + {% elseif about == 'upload_error' %} +

    A problem occurred when uploading the data

    +

    + No file given or the file was not uploaded successfully. +

    + {% elseif about == 'already_exists' %} +

    A problem occurred when uploading the data

    +

    + The token already exists in the database. +

    + {% elseif about == 'no_token' %} +

    Token not found

    +

    + Token "{{ token }}" was not found in the database. +

    + {% endif %} + {% endblock %} +
    +
    + +
    +
    +
    +{% endblock %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig new file mode 100644 index 0000000..2c4a0a7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig @@ -0,0 +1,54 @@ +{% extends 'WebProfilerBundle:Profiler:base.html.twig' %} + +{% block body %} + + {% render 'WebProfilerBundle:Profiler:toolbar' with { 'token': token, 'position': 'normal' } %} + +
    + {% include 'WebProfilerBundle:Profiler:header.html.twig' only %} + +
    + +
    +
    + {% if profile %} +
    + View all + Profile for: + {{ profile.method|upper }} + {% if profile.method|upper in ['GET', 'HEAD'] %} + {{ profile.url }} + {% else %} + {{ profile.url }} + {% endif %} + + by {{ profile.ip }} at {{ profile.time|date('r') }} + +
    + {% endif %} + +
    + {% include 'WebProfilerBundle:Profiler:base_js.html.twig' %} + {% block panel '' %} +
    +
    + +
    +
    +
    +{% endblock %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/results.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/results.html.twig new file mode 100644 index 0000000..d8db945 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/results.html.twig @@ -0,0 +1,35 @@ +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} + +{% block panel %} +

    Search Results

    + + {% if tokens %} + + + + + + + + + + + + {% for elements in tokens %} + + + + + + + + {% endfor %} + +
    TokenIPMethodURLTime
    {{ elements.token }}{{ elements.ip }}{{ elements.method }}{{ elements.url }}{{ elements.time|date('r') }}
    + {% else %} +

    + The query returned no result. +

    + {% endif %} + +{% endblock %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/search.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/search.html.twig new file mode 100644 index 0000000..d308240 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/search.html.twig @@ -0,0 +1,39 @@ + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/table.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/table.html.twig new file mode 100644 index 0000000..246edbd --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/table.html.twig @@ -0,0 +1,16 @@ + + + + + + + + + {% for key in data|keys|sort %} + + + + + {% endfor %} + +
    KeyValue
    {{ key }}{{ data[key]|yaml_dump }}
    diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.html.twig new file mode 100644 index 0000000..65e9b1d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.html.twig @@ -0,0 +1,26 @@ + +{% if 'normal' != position %} + {% include 'WebProfilerBundle:Profiler:toolbar_style.html.twig' with { 'position': position, 'floatable': true } %} +
    +{% endif %} + +
    + {% for name, template in templates %} + {{ template.renderblock('toolbar', { + 'collector': profile.getcollector(name), + 'profiler_url': profiler_url, + 'token': profile.token, + 'name': name + }) + }} + {% endfor %} + + {% if 'normal' != position %} + + {% endif %} +
    + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_item.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_item.html.twig new file mode 100644 index 0000000..42bbfea --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_item.html.twig @@ -0,0 +1,9 @@ +{% if link %} + {% set icon %} + {{ icon }} + {% endset %} +{% endif %} +
    +
    {{ icon|default('') }}
    +
    {{ text|default('') }}
    +
    diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_js.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_js.html.twig new file mode 100644 index 0000000..f3ce853 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_js.html.twig @@ -0,0 +1,18 @@ + +{% include 'WebProfilerBundle:Profiler:base_js.html.twig' %} + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_redirect.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_redirect.html.twig new file mode 100644 index 0000000..9156125 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_redirect.html.twig @@ -0,0 +1,18 @@ +{% extends 'TwigBundle::layout.html.twig' %} + +{% block title 'Redirection Intercepted' %} + +{% block body %} +
    +
    +

    This request redirects to {{ location }}.

    + +

    + + The redirect was intercepted by the web debug toolbar to help debugging. + For more information, see the "intercept-redirects" option of the Profiler. + +

    +
    +
    +{% endblock %} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_style.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_style.html.twig new file mode 100644 index 0000000..15b8ef3 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_style.html.twig @@ -0,0 +1,270 @@ + diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig new file mode 100644 index 0000000..ab0eaf6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig @@ -0,0 +1,44 @@ +

    Routing for "{{ request.pathinfo }}"

    + +
      +
    • + Route:  + {% if request.route %} + {{ request.route }} + {% else %} + No matching route + {% endif %} +
    • +
    • + Route parameters:  + {% if request.routeParams|length %} + {% include 'WebProfilerBundle:Profiler:table.html.twig' with { 'data': request.routeParams, 'class': 'inline' } only %} + {% else %} + No parameters + {% endif %} +
    • + {% if router.redirect %} +
    • + Redirecting to:  "{{ router.targetUrl }}" {% if router.targetRoute %}(route: "{{ router.targetRoute }}"){% endif %} +
    • + {% endif %} +
    • + Route matching logs + + + + + + + {% for trace in traces %} + + + + + + {% endfor %} +
      Route namePatternLog
      {{ trace.name }}{{ trace.pattern }}{{ trace.log }}
      + Note: The above matching is based on the configuration for the current router which might differ from + the configuration used while routing this request. +
    • +
    diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ExceptionControllerTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ExceptionControllerTest.php new file mode 100644 index 0000000..03ff572 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ExceptionControllerTest.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\Bundle\WebProfilerBundle\Tests\Controller; + +use Symfony\Bundle\WebProfilerBundle\Tests\TestCase; + +use Symfony\Bundle\WebProfilerBundle\Controller\ExceptionController; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Scope; +use Symfony\Component\DependencyInjection\Definition; + +class ExceptionControllerTest extends TestCase +{ + protected $controller; + protected $container; + protected $flatten; + protected $kernel; + + protected function setUp() + { + parent::setUp(); + + $this->flatten = $this->getMock('Symfony\Component\HttpKernel\Exception\FlattenException'); + $this->flatten->expects($this->once())->method('getStatusCode')->will($this->returnValue(404)); + $this->controller = new ExceptionController(); + $this->kernel = $this->getMock('Symfony\\Component\\HttpKernel\\KernelInterface'); + $this->container = $this->getContainer(); + } + + protected function tearDown() + { + parent::tearDown(); + + $this->controller = null; + $this->container = null; + $this->flatten = null; + $this->kernel = null; + } + + /** + * @dataProvider getDebugModes + */ + public function testShowActionDependingOnDebug($debug) + { + $this->container->setParameter('kernel.debug', $debug); + $this->controller->setContainer($this->container); + $this->controller->showAction($this->flatten); + } + + public function getDebugModes() + { + return array( + array(true), + array(false), + ); + } + + private function getContainer() + { + $container = new ContainerBuilder(); + $container->addScope(new Scope('request')); + $container->register('request', 'Symfony\\Component\\HttpFoundation\\Request')->setScope('request'); + $container->register('templating.helper.assets', $this->getMockClass('Symfony\\Component\\Templating\\Helper\\AssetsHelper')); + $container->register('templating.helper.router', $this->getMockClass('Symfony\\Bundle\\FrameworkBundle\\Templating\\Helper\\RouterHelper')) + ->addArgument(new Definition($this->getMockClass('Symfony\\Component\\Routing\\RouterInterface'))); + $container->register('twig', 'Twig_Environment'); + $container->register('templating.engine.twig', $this->getMockClass('Symfony\\Bundle\\TwigBundle\\TwigEngine')) + ->addArgument($this->getMock('Twig_Environment')) + ->addArgument($this->getMock('Symfony\\Component\\Templating\\TemplateNameParserInterface')) + ->addArgument(new Definition($this->getMockClass('Symfony\Component\Config\FileLocatorInterface'))) + ->addArgument($this->getMock('Symfony\\Bundle\\FrameworkBundle\\Templating\\GlobalVariables', array(), array($this->getMock('Symfony\\Component\\DependencyInjection\\Container')))); + $container->setAlias('templating', 'templating.engine.twig'); + $container->setParameter('kernel.bundles', array()); + $container->setParameter('kernel.cache_dir', __DIR__); + $container->setParameter('kernel.root_dir', __DIR__); + $container->set('kernel', $this->kernel); + + return $container; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/ConfigurationTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/ConfigurationTest.php new file mode 100644 index 0000000..729d271 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/ConfigurationTest.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\Bundle\WebProfilerBundle\Tests\DependencyInjection; + +use Symfony\Bundle\WebProfilerBundle\DependencyInjection\Configuration; +use Symfony\Component\Config\Definition\Processor; + +class ConfigurationTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getDebugModes + */ + public function testConfigTree($options, $results) + { + $processor = new Processor(); + $configuration = new Configuration(array()); + $config = $processor->processConfiguration($configuration, array($options)); + + $this->assertEquals($results, $config); + } + + public function getDebugModes() + { + return array( + array(array(), array('intercept_redirects' => false, 'toolbar' => false, 'verbose' => true, 'position' => 'bottom')), + array(array('intercept_redirects' => true), array('intercept_redirects' => true, 'toolbar' => false, 'verbose' => true, 'position' => 'bottom')), + array(array('intercept_redirects' => false), array('intercept_redirects' => false, 'toolbar' => false, 'verbose' => true, 'position' => 'bottom')), + array(array('toolbar' => true), array('intercept_redirects' => false, 'toolbar' => true, 'verbose' => true, 'position' => 'bottom')), + array(array('verbose' => false, 'position' => 'top'), array('intercept_redirects' => false, 'toolbar' => false, 'verbose' => false, 'position' => 'top')), + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/WebProfilerExtensionTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/WebProfilerExtensionTest.php new file mode 100644 index 0000000..5ba03b9 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/WebProfilerExtensionTest.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\Bundle\WebProfilerBundle\Tests\DependencyInjection; + +use Symfony\Bundle\WebProfilerBundle\Tests\TestCase; + +use Symfony\Bundle\WebProfilerBundle\DependencyInjection\WebProfilerExtension; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Dumper\PhpDumper; +use Symfony\Component\DependencyInjection\Scope; + +class WebProfilerExtensionTest extends TestCase +{ + private $kernel; + /** + * @var Symfony\Component\DependencyInjection\Container $container + */ + private $container; + + static public function assertSaneContainer(Container $container, $message = '') + { + $errors = array(); + foreach ($container->getServiceIds() as $id) { + try { + $container->get($id); + } catch (\Exception $e) { + $errors[$id] = $e->getMessage(); + } + } + + self::assertEquals(array(), $errors, $message); + } + + protected function setUp() + { + parent::setUp(); + + $this->kernel = $this->getMock('Symfony\\Component\\HttpKernel\\KernelInterface'); + + $this->container = new ContainerBuilder(); + $this->container->addScope(new Scope('request')); + $this->container->register('request', 'Symfony\\Component\\HttpFoundation\\Request')->setScope('request'); + $this->container->register('templating.helper.assets', $this->getMockClass('Symfony\\Component\\Templating\\Helper\\AssetsHelper')); + $this->container->register('templating.helper.router', $this->getMockClass('Symfony\\Bundle\\FrameworkBundle\\Templating\\Helper\\RouterHelper')) + ->addArgument(new Definition($this->getMockClass('Symfony\\Component\\Routing\\RouterInterface'))); + $this->container->register('twig', 'Twig_Environment'); + $this->container->register('templating.engine.twig', $this->getMockClass('Symfony\\Bundle\\TwigBundle\\TwigEngine')) + ->addArgument(new Definition($this->getMockClass('Twig_Environment'))) + ->addArgument(new Definition($this->getMockClass('Symfony\\Component\\Templating\\TemplateNameParserInterface'))) + ->addArgument(new Definition($this->getMockClass('Symfony\Component\Config\FileLocatorInterface'))) + ->addArgument(new Definition($this->getMockClass('Symfony\\Bundle\\FrameworkBundle\\Templating\\GlobalVariables'), array(new Definition($this->getMockClass('Symfony\\Component\\DependencyInjection\\Container'))))); + $this->container->setParameter('kernel.bundles', array()); + $this->container->setParameter('kernel.cache_dir', __DIR__); + $this->container->setParameter('kernel.debug', false); + $this->container->setParameter('kernel.root_dir', __DIR__); + $this->container->set('kernel', $this->kernel); + } + + protected function tearDown() + { + parent::tearDown(); + + $this->container = null; + $this->kernel = null; + } + + /** + * @dataProvider getDebugModes + */ + public function testDefaultConfig($debug) + { + $this->container->setParameter('kernel.debug', $debug); + + $extension = new WebProfilerExtension(); + $extension->load(array(array()), $this->container); + + $this->assertFalse($this->container->get('web_profiler.debug_toolbar')->isEnabled()); + + $this->assertSaneContainer($this->getDumpedContainer()); + } + + /** + * @dataProvider getDebugModes + */ + public function testToolbarConfig($enabled) + { + $extension = new WebProfilerExtension(); + $extension->load(array(array('toolbar' => $enabled)), $this->container); + + $this->assertSame($enabled, $this->container->get('web_profiler.debug_toolbar')->isEnabled()); + + $this->assertSaneContainer($this->getDumpedContainer()); + } + + public function getDebugModes() + { + return array( + array(true), + array(false), + ); + } + + private function getDumpedContainer() + { + static $i = 0; + $class = 'WebProfilerExtensionTestContainer'.$i++; + + $this->container->compile(); + + $dumper = new PhpDumper($this->container); + eval('?>'.$dumper->dump(array('class' => $class))); + + $container = new $class(); + $container->enterScope('request'); + $container->set('kernel', $this->kernel); + + return $container; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Tests/EventListener/WebDebugToolbarListenerTest.php b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Tests/EventListener/WebDebugToolbarListenerTest.php new file mode 100644 index 0000000..c9e4a59 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Tests/EventListener/WebDebugToolbarListenerTest.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\Bundle\WebProfilerBundle\Tests\EventListener; + +use Symfony\Bundle\WebProfilerBundle\EventListener\WebDebugToolbarListener; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Component\HttpKernel\HttpKernelInterface; + +class WebDebugToolbarListenerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getInjectToolbarTests + */ + public function testInjectToolbar($content, $expected) + { + $listener = new WebDebugToolbarListener($this->getTemplatingMock()); + $m = new \ReflectionMethod($listener, 'injectToolbar'); + $m->setAccessible(true); + + $response = new Response($content); + + $m->invoke($listener, $response); + $this->assertEquals($expected, $response->getContent()); + } + + public function getInjectToolbarTests() + { + return array( + array('', "\nWDT\n"), + array(' + + + + + ', " + + + + \nWDT\n + "), + ); + } + + /** + * @dataProvider provideRedirects + */ + public function testRedirectionIsIntercepted($statusCode, $hasSession) + { + $response = new Response('Some content', $statusCode); + $response->headers->set('X-Debug-Token', 'xxxxxxxx'); + $event = new FilterResponseEvent($this->getKernelMock(), $this->getRequestMock(false, 'html', $hasSession), HttpKernelInterface::MASTER_REQUEST, $response); + + $listener = new WebDebugToolbarListener($this->getTemplatingMock('Redirection'), true); + $listener->onKernelResponse($event); + + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('Redirection', $response->getContent()); + } + + public function testToolbarIsInjected() + { + $response = new Response(''); + $response->headers->set('X-Debug-Token', 'xxxxxxxx'); + + $event = new FilterResponseEvent($this->getKernelMock(), $this->getRequestMock(), HttpKernelInterface::MASTER_REQUEST, $response); + + $listener = new WebDebugToolbarListener($this->getTemplatingMock()); + $listener->onKernelResponse($event); + + $this->assertEquals("\nWDT\n", $response->getContent()); + } + + /** + * @depends testToolbarIsInjected + * @dataProvider provideRedirects + */ + public function testToolbarIsNotInjectedOnRedirection($statusCode, $hasSession) + { + $response = new Response('', $statusCode); + $response->headers->set('X-Debug-Token', 'xxxxxxxx'); + $event = new FilterResponseEvent($this->getKernelMock(), $this->getRequestMock(false, 'html', $hasSession), HttpKernelInterface::MASTER_REQUEST, $response); + + $listener = new WebDebugToolbarListener($this->getTemplatingMock()); + $listener->onKernelResponse($event); + + $this->assertEquals('', $response->getContent()); + } + + public function provideRedirects() + { + return array( + array(301, true), + array(302, true), + array(301, false), + array(302, false), + ); + } + + /** + * @depends testToolbarIsInjected + */ + public function testToolbarIsNotInjectedWhenThereIsNoNoXDebugTokenResponseHeader() + { + $response = new Response(''); + + $event = new FilterResponseEvent($this->getKernelMock(), $this->getRequestMock(), HttpKernelInterface::MASTER_REQUEST, $response); + + $listener = new WebDebugToolbarListener($this->getTemplatingMock()); + $listener->onKernelResponse($event); + + $this->assertEquals('', $response->getContent()); + } + + /** + * @depends testToolbarIsInjected + */ + public function testToolbarIsNotInjectedWhenOnSubRequest() + { + $response = new Response(''); + $response->headers->set('X-Debug-Token', 'xxxxxxxx'); + + $event = new FilterResponseEvent($this->getKernelMock(), $this->getRequestMock(), HttpKernelInterface::SUB_REQUEST, $response); + + $listener = new WebDebugToolbarListener($this->getTemplatingMock()); + $listener->onKernelResponse($event); + + $this->assertEquals('', $response->getContent()); + } + + /** + * @depends testToolbarIsInjected + */ + public function testToolbarIsNotInjectedOnIncompleteHtmlResponses() + { + $response = new Response('
    Some content
    '); + $response->headers->set('X-Debug-Token', 'xxxxxxxx'); + + $event = new FilterResponseEvent($this->getKernelMock(), $this->getRequestMock(), HttpKernelInterface::MASTER_REQUEST, $response); + + $listener = new WebDebugToolbarListener($this->getTemplatingMock()); + $listener->onKernelResponse($event); + + $this->assertEquals('
    Some content
    ', $response->getContent()); + } + + /** + * @depends testToolbarIsInjected + */ + public function testToolbarIsNotInjectedOnXmlHttpRequests() + { + $response = new Response(''); + $response->headers->set('X-Debug-Token', 'xxxxxxxx'); + + $event = new FilterResponseEvent($this->getKernelMock(), $this->getRequestMock(true), HttpKernelInterface::MASTER_REQUEST, $response); + + $listener = new WebDebugToolbarListener($this->getTemplatingMock()); + $listener->onKernelResponse($event); + + $this->assertEquals('', $response->getContent()); + } + + /** + * @depends testToolbarIsInjected + */ + public function testToolbarIsNotInjectedOnNonHtmlRequests() + { + $response = new Response(''); + $response->headers->set('X-Debug-Token', 'xxxxxxxx'); + + $event = new FilterResponseEvent($this->getKernelMock(), $this->getRequestMock(false, 'json'), HttpKernelInterface::MASTER_REQUEST, $response); + + $listener = new WebDebugToolbarListener($this->getTemplatingMock()); + $listener->onKernelResponse($event); + + $this->assertEquals('', $response->getContent()); + } + + protected function getRequestMock($isXmlHttpRequest = false, $requestFormat = 'html', $hasSession = true) + { + $request = $this->getMock( + 'Symfony\Component\HttpFoundation\Request', + array('getSession', 'isXmlHttpRequest', 'getRequestFormat'), + array(), '', false + ); + $request->expects($this->any()) + ->method('isXmlHttpRequest') + ->will($this->returnValue($isXmlHttpRequest)); + $request->expects($this->any()) + ->method('getRequestFormat') + ->will($this->returnValue($requestFormat)); + + if ($hasSession) { + $session = $this->getMock('Symfony\Component\HttpFoundation\Session\Session', array(), array(), '', false); + $request->expects($this->any()) + ->method('getSession') + ->will($this->returnValue($session)); + } + + return $request; + } + + protected function getTemplatingMock($render = 'WDT') + { + $templating = $this->getMock('Symfony\Bundle\TwigBundle\TwigEngine', array(), array(), '', false); + $templating->expects($this->any()) + ->method('render') + ->will($this->returnValue($render)); + + return $templating; + } + + protected function getKernelMock() + { + return $this->getMock('Symfony\Component\HttpKernel\Kernel', array(), array(), '', false); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Tests/TestCase.php b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Tests/TestCase.php new file mode 100644 index 0000000..586da13 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Tests/TestCase.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\Bundle\WebProfilerBundle\Tests; + +class TestCase extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Twig_Environment')) { + $this->markTestSkipped('Twig is not available.'); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/WebProfilerBundle.php b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/WebProfilerBundle.php new file mode 100644 index 0000000..fecc0f3 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/WebProfilerBundle.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\Bundle\WebProfilerBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +/** + * Bundle. + * + * @author Fabien Potencier + */ +class WebProfilerBundle extends Bundle +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/composer.json b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/composer.json new file mode 100644 index 0000000..f4c5baa --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/composer.json @@ -0,0 +1,31 @@ +{ + "name": "symfony/web-profiler-bundle", + "type": "symfony-bundle", + "description": "Symfony WebProfilerBundle", + "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/twig-bundle": "self.version" + }, + "autoload": { + "psr-0": { "Symfony\\Bundle\\WebProfilerBundle": "" } + }, + "target-dir": "Symfony/Bundle/WebProfilerBundle", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/CHANGELOG.md b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/CHANGELOG.md new file mode 100644 index 0000000..42d32a7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/CHANGELOG.md @@ -0,0 +1,8 @@ +CHANGELOG +========= + +2.1.0 +----- + + * [BC BREAK] The CookieJar internals have changed to allow cookies with the + same name on different sub-domains/sub-paths diff --git a/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Client.php b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Client.php new file mode 100644 index 0000000..c57b9e3 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Client.php @@ -0,0 +1,492 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\BrowserKit; + +use Symfony\Component\DomCrawler\Crawler; +use Symfony\Component\DomCrawler\Link; +use Symfony\Component\DomCrawler\Form; +use Symfony\Component\Process\PhpProcess; + +/** + * Client simulates a browser. + * + * To make the actual request, you need to implement the doRequest() method. + * + * If you want to be able to run requests in their own process (insulated flag), + * you need to also implement the getScript() method. + * + * @author Fabien Potencier + * + * @api + */ +abstract class Client +{ + protected $history; + protected $cookieJar; + protected $server; + protected $request; + protected $response; + protected $crawler; + protected $insulated; + protected $redirect; + protected $followRedirects; + + /** + * Constructor. + * + * @param array $server The server parameters (equivalent of $_SERVER) + * @param History $history A History instance to store the browser history + * @param CookieJar $cookieJar A CookieJar instance to store the cookies + * + * @api + */ + public function __construct(array $server = array(), History $history = null, CookieJar $cookieJar = null) + { + $this->setServerParameters($server); + $this->history = null === $history ? new History() : $history; + $this->cookieJar = null === $cookieJar ? new CookieJar() : $cookieJar; + $this->insulated = false; + $this->followRedirects = true; + } + + /** + * Sets whether to automatically follow redirects or not. + * + * @param Boolean $followRedirect Whether to follow redirects + * + * @api + */ + public function followRedirects($followRedirect = true) + { + $this->followRedirects = (Boolean) $followRedirect; + } + + /** + * Sets the insulated flag. + * + * @param Boolean $insulated Whether to insulate the requests or not + * + * @throws \RuntimeException When Symfony Process Component is not installed + * + * @api + */ + public function insulate($insulated = true) + { + if ($insulated && !class_exists('Symfony\\Component\\Process\\Process')) { + // @codeCoverageIgnoreStart + throw new \RuntimeException('Unable to isolate requests as the Symfony Process Component is not installed.'); + // @codeCoverageIgnoreEnd + } + + $this->insulated = (Boolean) $insulated; + } + + /** + * Sets server parameters. + * + * @param array $server An array of server parameters + * + * @api + */ + public function setServerParameters(array $server) + { + $this->server = array_merge(array( + 'HTTP_HOST' => 'localhost', + 'HTTP_USER_AGENT' => 'Symfony2 BrowserKit', + ), $server); + } + + /** + * Sets single server parameter. + * + * @param string $key A key of the parameter + * @param string $value A value of the parameter + */ + public function setServerParameter($key, $value) + { + $this->server[$key] = $value; + } + + /** + * Gets single server parameter for specified key. + * + * @param string $key A key of the parameter to get + * @param string $default A default value when key is undefined + * + * @return string A value of the parameter + */ + public function getServerParameter($key, $default = '') + { + return (isset($this->server[$key])) ? $this->server[$key] : $default; + } + + /** + * Returns the History instance. + * + * @return History A History instance + * + * @api + */ + public function getHistory() + { + return $this->history; + } + + /** + * Returns the CookieJar instance. + * + * @return CookieJar A CookieJar instance + * + * @api + */ + public function getCookieJar() + { + return $this->cookieJar; + } + + /** + * Returns the current Crawler instance. + * + * @return Crawler A Crawler instance + * + * @api + */ + public function getCrawler() + { + return $this->crawler; + } + + /** + * Returns the current Response instance. + * + * @return Response A Response instance + * + * @api + */ + public function getResponse() + { + return $this->response; + } + + /** + * Returns the current Request instance. + * + * @return Request A Request instance + * + * @api + */ + public function getRequest() + { + return $this->request; + } + + /** + * Clicks on a given link. + * + * @param Link $link A Link instance + * + * @return Crawler + * + * @api + */ + public function click(Link $link) + { + if ($link instanceof Form) { + return $this->submit($link); + } + + return $this->request($link->getMethod(), $link->getUri()); + } + + /** + * Submits a form. + * + * @param Form $form A Form instance + * @param array $values An array of form field values + * + * @return Crawler + * + * @api + */ + public function submit(Form $form, array $values = array()) + { + $form->setValues($values); + + return $this->request($form->getMethod(), $form->getUri(), $form->getPhpValues(), $form->getPhpFiles()); + } + + /** + * Calls a URI. + * + * @param string $method The request method + * @param string $uri The URI to fetch + * @param array $parameters The Request parameters + * @param array $files The files + * @param array $server The server parameters (HTTP headers are referenced with a HTTP_ prefix as PHP does) + * @param string $content The raw body data + * @param Boolean $changeHistory Whether to update the history or not (only used internally for back(), forward(), and reload()) + * + * @return Crawler + * + * @api + */ + public function request($method, $uri, array $parameters = array(), array $files = array(), array $server = array(), $content = null, $changeHistory = true) + { + $uri = $this->getAbsoluteUri($uri); + + $server = array_merge($this->server, $server); + if (!$this->history->isEmpty()) { + $server['HTTP_REFERER'] = $this->history->current()->getUri(); + } + $server['HTTP_HOST'] = parse_url($uri, PHP_URL_HOST); + $server['HTTPS'] = 'https' == parse_url($uri, PHP_URL_SCHEME); + + $request = new Request($uri, $method, $parameters, $files, $this->cookieJar->allValues($uri), $server, $content); + + $this->request = $this->filterRequest($request); + + if (true === $changeHistory) { + $this->history->add($request); + } + + if ($this->insulated) { + $this->response = $this->doRequestInProcess($this->request); + } else { + $this->response = $this->doRequest($this->request); + } + + $response = $this->filterResponse($this->response); + + $this->cookieJar->updateFromResponse($response); + + $this->redirect = $response->getHeader('Location'); + + if ($this->followRedirects && $this->redirect) { + return $this->crawler = $this->followRedirect(); + } + + return $this->crawler = $this->createCrawlerFromContent($request->getUri(), $response->getContent(), $response->getHeader('Content-Type')); + } + + /** + * Makes a request in another process. + * + * @param Request $request A Request instance + * + * @return Response A Response instance + * + * @throws \RuntimeException When processing returns exit code + */ + protected function doRequestInProcess($request) + { + // We set the TMPDIR (for Macs) and TEMP (for Windows), because on these platforms the temp directory changes based on the user. + $process = new PhpProcess($this->getScript($request), null, array('TMPDIR' => sys_get_temp_dir(), 'TEMP' => sys_get_temp_dir())); + $process->run(); + + if (!$process->isSuccessful() || !preg_match('/^O\:\d+\:/', $process->getOutput())) { + throw new \RuntimeException('OUTPUT: '.$process->getOutput().' ERROR OUTPUT: '.$process->getErrorOutput()); + } + + return unserialize($process->getOutput()); + } + + /** + * Makes a request. + * + * @param Request $request A Request instance + * + * @return Response A Response instance + */ + abstract protected function doRequest($request); + + /** + * Returns the script to execute when the request must be insulated. + * + * @param Request $request A Request instance + * + * @throws \LogicException When this abstract class is not implemented + */ + protected function getScript($request) + { + // @codeCoverageIgnoreStart + throw new \LogicException('To insulate requests, you need to override the getScript() method.'); + // @codeCoverageIgnoreEnd + } + + /** + * Filters the request. + * + * @param Request $request The request to filter + * + * @return Request + */ + protected function filterRequest(Request $request) + { + return $request; + } + + /** + * Filters the Response. + * + * @param Response $response The Response to filter + * + * @return Response + */ + protected function filterResponse($response) + { + return $response; + } + + /** + * Creates a crawler. + * + * This method returns null if the DomCrawler component is not available. + * + * @param string $uri A uri + * @param string $content Content for the crawler to use + * @param string $type Content type + * + * @return Crawler|null + */ + protected function createCrawlerFromContent($uri, $content, $type) + { + if (!class_exists('Symfony\Component\DomCrawler\Crawler')) { + return null; + } + + $crawler = new Crawler(null, $uri); + $crawler->addContent($content, $type); + + return $crawler; + } + + /** + * Goes back in the browser history. + * + * @return Crawler + * + * @api + */ + public function back() + { + return $this->requestFromRequest($this->history->back(), false); + } + + /** + * Goes forward in the browser history. + * + * @return Crawler + * + * @api + */ + public function forward() + { + return $this->requestFromRequest($this->history->forward(), false); + } + + /** + * Reloads the current browser. + * + * @return Crawler + * + * @api + */ + public function reload() + { + return $this->requestFromRequest($this->history->current(), false); + } + + /** + * Follow redirects? + * + * @return Crawler + * + * @throws \LogicException If request was not a redirect + * + * @api + */ + public function followRedirect() + { + if (empty($this->redirect)) { + throw new \LogicException('The request was not redirected.'); + } + + return $this->request('get', $this->redirect); + } + + /** + * Restarts the client. + * + * It flushes history and all cookies. + * + * @api + */ + public function restart() + { + $this->cookieJar->clear(); + $this->history->clear(); + } + + /** + * Takes a URI and converts it to absolute if it is not already absolute. + * + * @param string $uri A uri + * + * @return string An absolute uri + */ + protected function getAbsoluteUri($uri) + { + // already absolute? + if (0 === strpos($uri, 'http')) { + return $uri; + } + + if (!$this->history->isEmpty()) { + $currentUri = $this->history->current()->getUri(); + } else { + $currentUri = sprintf('http%s://%s/', + isset($this->server['HTTPS']) ? 's' : '', + isset($this->server['HTTP_HOST']) ? $this->server['HTTP_HOST'] : 'localhost' + ); + } + + // anchor? + if (!$uri || '#' == $uri[0]) { + return preg_replace('/#.*?$/', '', $currentUri).$uri; + } + + if ('/' !== $uri[0]) { + $path = parse_url($currentUri, PHP_URL_PATH); + + if ('/' !== substr($path, -1)) { + $path = substr($path, 0, strrpos($path, '/') + 1); + } + + $uri = $path.$uri; + } + + return preg_replace('#^(.*?//[^/]+)\/.*$#', '$1', $currentUri).$uri; + } + + /** + * Makes a request from a Request object directly. + * + * @param Request $request A Request instance + * @param Boolean $changeHistory Whether to update the history or not (only used internally for back(), forward(), and reload()) + * + * @return Crawler + */ + protected function requestFromRequest(Request $request, $changeHistory = true) + { + return $this->request($request->getMethod(), $request->getUri(), $request->getParameters(), $request->getFiles(), $request->getServer(), $request->getContent(), $changeHistory); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Cookie.php b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Cookie.php new file mode 100644 index 0000000..16063ee --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Cookie.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\BrowserKit; + +/** + * Cookie represents an HTTP cookie. + * + * @author Fabien Potencier + * + * @api + */ +class Cookie +{ + /** + * Handles dates as defined by RFC 2616 section 3.3.1, and also some other + * non-standard, but common formats. + * + * @var array + */ + private static $dateFormats = array( + 'D, d M Y H:i:s T', + 'D, d-M-y H:i:s T', + 'D, d-M-Y H:i:s T', + 'D M j G:i:s Y', + ); + + protected $name; + protected $value; + protected $expires; + protected $path; + protected $domain; + protected $secure; + protected $httponly; + protected $rawValue; + + /** + * Sets a cookie. + * + * @param string $name The cookie name + * @param string $value The value of the cookie + * @param string $expires The time the cookie expires + * @param string $path The path on the server in which the cookie will be available on + * @param string $domain The domain that the cookie is available + * @param Boolean $secure Indicates that the cookie should only be transmitted over a secure HTTPS connection from the client + * @param Boolean $httponly The cookie httponly flag + * @param Boolean $encodedValue Whether the value is encoded or not + * + * @api + */ + public function __construct($name, $value, $expires = null, $path = null, $domain = '', $secure = false, $httponly = true, $encodedValue = false) + { + if ($encodedValue) { + $this->value = urldecode($value); + $this->rawValue = $value; + } else { + $this->value = $value; + $this->rawValue = urlencode($value); + } + $this->name = $name; + $this->expires = null === $expires ? null : (integer) $expires; + $this->path = empty($path) ? '/' : $path; + $this->domain = $domain; + $this->secure = (Boolean) $secure; + $this->httponly = (Boolean) $httponly; + } + + /** + * Returns the HTTP representation of the Cookie. + * + * @return string The HTTP representation of the Cookie + * + * @api + */ + public function __toString() + { + $cookie = sprintf('%s=%s', $this->name, $this->rawValue); + + if (null !== $this->expires) { + $cookie .= '; expires='.substr(\DateTime::createFromFormat('U', $this->expires, new \DateTimeZone('GMT'))->format(self::$dateFormats[0]), 0, -5); + } + + if ('' !== $this->domain) { + $cookie .= '; domain='.$this->domain; + } + + if ('/' !== $this->path) { + $cookie .= '; path='.$this->path; + } + + if ($this->secure) { + $cookie .= '; secure'; + } + + if ($this->httponly) { + $cookie .= '; httponly'; + } + + return $cookie; + } + + /** + * Creates a Cookie instance from a Set-Cookie header value. + * + * @param string $cookie A Set-Cookie header value + * @param string $url The base URL + * + * @return Cookie A Cookie instance + * + * @api + */ + static public function fromString($cookie, $url = null) + { + $parts = explode(';', $cookie); + + if (false === strpos($parts[0], '=')) { + throw new \InvalidArgumentException('The cookie string "%s" is not valid.'); + } + + list($name, $value) = explode('=', array_shift($parts), 2); + + $values = array( + 'name' => trim($name), + 'value' => trim($value), + 'expires' => null, + 'path' => '/', + 'domain' => '', + 'secure' => false, + 'httponly' => false, + 'passedRawValue' => true, + ); + + if (null !== $url) { + if ((false === $urlParts = parse_url($url)) || !isset($urlParts['host']) || !isset($urlParts['path'])) { + throw new \InvalidArgumentException(sprintf('The URL "%s" is not valid.', $url)); + } + $parts = array_merge($urlParts, $parts); + + $values['domain'] = $parts['host']; + $values['path'] = substr($parts['path'], 0, strrpos($parts['path'], '/')); + } + + foreach ($parts as $part) { + $part = trim($part); + + if ('secure' === strtolower($part)) { + // Ignore the secure flag if the original URI is not given or is not HTTPS + if (!$url || !isset($urlParts['scheme']) || 'https' != $urlParts['scheme']) { + continue; + } + + $values['secure'] = true; + + continue; + } + + if ('httponly' === strtolower($part)) { + $values['httponly'] = true; + + continue; + } + + if (2 === count($elements = explode('=', $part, 2))) { + if ('expires' === strtolower($elements[0])) { + $elements[1] = self::parseDate($elements[1]); + } + + $values[strtolower($elements[0])] = $elements[1]; + } + } + + return new static( + $values['name'], + $values['value'], + $values['expires'], + $values['path'], + $values['domain'], + $values['secure'], + $values['httponly'], + $values['passedRawValue'] + ); + } + + private static function parseDate($dateValue) + { + // trim single quotes around date if present + if (($length = strlen($dateValue)) > 1 && "'" === $dateValue[0] && "'" === $dateValue[$length-1]) { + $dateValue = substr($dateValue, 1, -1); + } + + foreach (self::$dateFormats as $dateFormat) { + if (false !== $date = \DateTime::createFromFormat($dateFormat, $dateValue, new \DateTimeZone('GMT'))) { + return $date->getTimestamp(); + } + } + + throw new \InvalidArgumentException(sprintf('Could not parse date "%s".', $dateValue)); + } + + /** + * Gets the name of the cookie. + * + * @return string The cookie name + * + * @api + */ + public function getName() + { + return $this->name; + } + + /** + * Gets the value of the cookie. + * + * @return string The cookie value + * + * @api + */ + public function getValue() + { + return $this->value; + } + + /** + * Gets the raw value of the cookie. + * + * @return string The cookie value + * + * @api + */ + public function getRawValue() + { + return $this->rawValue; + } + + /** + * Gets the expires time of the cookie. + * + * @return string The cookie expires time + * + * @api + */ + public function getExpiresTime() + { + return $this->expires; + } + + /** + * Gets the path of the cookie. + * + * @return string The cookie path + * + * @api + */ + public function getPath() + { + return $this->path; + } + + /** + * Gets the domain of the cookie. + * + * @return string The cookie domain + * + * @api + */ + public function getDomain() + { + return $this->domain; + } + + /** + * Returns the secure flag of the cookie. + * + * @return Boolean The cookie secure flag + * + * @api + */ + public function isSecure() + { + return $this->secure; + } + + /** + * Returns the httponly flag of the cookie. + * + * @return Boolean The cookie httponly flag + * + * @api + */ + public function isHttpOnly() + { + return $this->httponly; + } + + /** + * Returns true if the cookie has expired. + * + * @return Boolean true if the cookie has expired, false otherwise + * + * @api + */ + public function isExpired() + { + return null !== $this->expires && 0 !== $this->expires && $this->expires < time(); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/CookieJar.php b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/CookieJar.php new file mode 100644 index 0000000..2a5c170 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/CookieJar.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\BrowserKit; + +/** + * CookieJar. + * + * @author Fabien Potencier + * + * @api + */ +class CookieJar +{ + protected $cookieJar = array(); + + /** + * Sets a cookie. + * + * @param Cookie $cookie A Cookie instance + * + * @api + */ + public function set(Cookie $cookie) + { + $this->cookieJar[$cookie->getDomain()][$cookie->getPath()][$cookie->getName()] = $cookie; + } + + /** + * Gets a cookie by name. + * + * @param string $name The cookie name + * @param string $path The cookie path + * @param string $domain The cookie domain + * + * @return Cookie|null A Cookie instance or null if the cookie does not exist + * + * @api + */ + public function get($name, $path = '/', $domain = null) + { + $this->flushExpiredCookies(); + + return isset($this->cookieJar[$domain][$path][$name]) ? $this->cookieJar[$domain][$path][$name] : null; + } + + /** + * Removes a cookie by name. + * + * @param string $name The cookie name + * @param string $path The cookie path + * @param string $domain The cookie domain + * + * @api + */ + public function expire($name, $path = '/', $domain = null) + { + if (null === $path) { + $path = '/'; + } + + unset($this->cookieJar[$domain][$path][$name]); + + if (empty($this->cookieJar[$domain][$path])) { + unset($this->cookieJar[$domain][$path]); + + if (empty($this->cookieJar[$domain])) { + unset($this->cookieJar[$domain]); + } + } + } + + /** + * Removes all the cookies from the jar. + * + * @api + */ + public function clear() + { + $this->cookieJar = array(); + } + + /** + * Updates the cookie jar from a response Set-Cookie headers. + * + * @param array $setCookies Set-Cookie headers from an HTTP response + * @param string $uri The base URL + */ + public function updateFromSetCookie(array $setCookies, $uri = null) + { + $cookies = array(); + + foreach ($setCookies as $cookie) { + foreach (explode(',', $cookie) as $i => $part) { + if (0 === $i || preg_match('/^(?P\s*[0-9A-Za-z!#\$%\&\'\*\+\-\.^_`\|~]+)=/', $part)) { + $cookies[] = ltrim($part); + } else { + $cookies[count($cookies) - 1] .= ','.$part; + } + } + } + + foreach ($cookies as $cookie) { + $this->set(Cookie::fromString($cookie, $uri)); + } + } + + /** + * Updates the cookie jar from a Response object. + * + * @param Response $response A Response object + * @param string $uri The base URL + */ + public function updateFromResponse(Response $response, $uri = null) + { + $this->updateFromSetCookie($response->getHeader('Set-Cookie', false), $uri); + } + + /** + * Returns not yet expired cookies. + * + * @return array An array of cookies + */ + public function all() + { + $this->flushExpiredCookies(); + + $flattenedCookies = array(); + foreach ($this->cookieJar as $path) { + foreach ($path as $cookies) { + foreach ($cookies as $cookie) { + $flattenedCookies[] = $cookie; + } + } + } + + return $flattenedCookies; + } + + /** + * Returns not yet expired cookie values for the given URI. + * + * @param string $uri A URI + * @param Boolean $returnsRawValue Returns raw value or urldecoded value + * + * @return array An array of cookie values + */ + public function allValues($uri, $returnsRawValue = false) + { + $this->flushExpiredCookies(); + + $parts = array_replace(array('path' => '/'), parse_url($uri)); + $cookies = array(); + foreach ($this->cookieJar as $domain => $pathCookies) { + if ($domain) { + $domain = ltrim($domain, '.'); + if ($domain != substr($parts['host'], -strlen($domain))) { + continue; + } + } + + foreach ($pathCookies as $path => $namedCookies) { + if ($path != substr($parts['path'], 0, strlen($path))) { + continue; + } + + foreach ($namedCookies as $cookie) { + if ($cookie->isSecure() && 'https' != $parts['scheme']) { + continue; + } + + $cookies[$cookie->getName()] = $returnsRawValue ? $cookie->getRawValue() : $cookie->getValue(); + } + } + } + + return $cookies; + } + + /** + * Returns not yet expired raw cookie values for the given URI. + * + * @param string $uri A URI + * + * @return array An array of cookie values + */ + public function allRawValues($uri) + { + return $this->allValues($uri, true); + } + + /** + * Removes all expired cookies. + */ + public function flushExpiredCookies() + { + foreach ($this->cookieJar as $domain => $pathCookies) { + foreach ($pathCookies as $path => $namedCookies) { + foreach ($namedCookies as $name => $cookie) { + if ($cookie->isExpired()) { + unset($this->cookieJar[$domain][$path][$name]); + } + } + } + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/History.php b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/History.php new file mode 100644 index 0000000..a22847e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/History.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\BrowserKit; + +/** + * History. + * + * @author Fabien Potencier + */ +class History +{ + protected $stack = array(); + protected $position = -1; + + /** + * Constructor. + */ + public function __construct() + { + $this->clear(); + } + + /** + * Clears the history. + */ + public function clear() + { + $this->stack = array(); + $this->position = -1; + } + + /** + * Adds a Request to the history. + * + * @param Request $request A Request instance + */ + public function add(Request $request) + { + $this->stack = array_slice($this->stack, 0, $this->position + 1); + $this->stack[] = clone $request; + $this->position = count($this->stack) - 1; + } + + /** + * Returns true if the history is empty. + * + * @return Boolean true if the history is empty, false otherwise + */ + public function isEmpty() + { + return count($this->stack) == 0; + } + + /** + * Goes back in the history. + * + * @return Request A Request instance + * + * @throws \LogicException if the stack is already on the first page + */ + public function back() + { + if ($this->position < 1) { + throw new \LogicException('You are already on the first page.'); + } + + return clone $this->stack[--$this->position]; + } + + /** + * Goes forward in the history. + * + * @return Request A Request instance + * + * @throws \LogicException if the stack is already on the last page + */ + public function forward() + { + if ($this->position > count($this->stack) - 2) { + throw new \LogicException('You are already on the last page.'); + } + + return clone $this->stack[++$this->position]; + } + + /** + * Returns the current element in the history. + * + * @return Request A Request instance + * + * @throws \LogicException if the stack is empty + */ + public function current() + { + if (-1 == $this->position) { + throw new \LogicException('The page history is empty.'); + } + + return clone $this->stack[$this->position]; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/LICENSE b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/LICENSE new file mode 100644 index 0000000..cdffe7a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 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/symfony/src/Symfony/Component/BrowserKit/README.md b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/README.md new file mode 100644 index 0000000..061c2d7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/README.md @@ -0,0 +1,26 @@ +BrowserKit Component +==================== + +BrowserKit simulates the behavior of a web browser. + +The component only provide an abstract client and does not provide any +"default" backend for the HTTP layer. + +Resources +--------- + +For a simple implementation of a browser based on an HTTP layer, have a look +at [Goutte](https://github.com/fabpot/Goutte). + +For an implementation based on HttpKernelInterface, have a look at the +[Client](https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpKernel/Client.php) +provided by the HttpKernel component. + +You can run the unit tests with the following command: + + phpunit + +If you also want to run the unit tests that depend on other Symfony +Components, install dev dependencies before running PHPUnit: + + php composer.phar install --dev diff --git a/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Request.php b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Request.php new file mode 100644 index 0000000..c02f657 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Request.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\BrowserKit; + +/** + * Request object. + * + * @author Fabien Potencier + * + * @api + */ +class Request +{ + protected $uri; + protected $method; + protected $parameters; + protected $files; + protected $cookies; + protected $server; + protected $content; + + /** + * Constructor. + * + * @param string $uri The request URI + * @param array $method The HTTP method request + * @param array $parameters The request parameters + * @param array $files An array of uploaded files + * @param array $cookies An array of cookies + * @param array $server An array of server parameters + * @param string $content The raw body data + * + * @api + */ + public function __construct($uri, $method, array $parameters = array(), array $files = array(), array $cookies = array(), array $server = array(), $content = null) + { + $this->uri = $uri; + $this->method = $method; + $this->parameters = $parameters; + $this->files = $files; + $this->cookies = $cookies; + $this->server = $server; + $this->content = $content; + } + + /** + * Gets the request URI. + * + * @return string The request URI + * + * @api + */ + public function getUri() + { + return $this->uri; + } + + /** + * Gets the request HTTP method. + * + * @return string The request HTTP method + * + * @api + */ + public function getMethod() + { + return $this->method; + } + + /** + * Gets the request parameters. + * + * @return array The request parameters + * + * @api + */ + public function getParameters() + { + return $this->parameters; + } + + /** + * Gets the request server files. + * + * @return array The request files + * + * @api + */ + public function getFiles() + { + return $this->files; + } + + /** + * Gets the request cookies. + * + * @return array The request cookies + * + * @api + */ + public function getCookies() + { + return $this->cookies; + } + + /** + * Gets the request server parameters. + * + * @return array The request server parameters + * + * @api + */ + public function getServer() + { + return $this->server; + } + + /** + * Gets the request raw body data. + * + * @return string The request raw body data. + * + * @api + */ + public function getContent() + { + return $this->content; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Response.php b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Response.php new file mode 100644 index 0000000..182fdda --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Response.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\BrowserKit; + +/** + * Response object. + * + * @author Fabien Potencier + * + * @api + */ +class Response +{ + protected $content; + protected $status; + protected $headers; + + /** + * Constructor. + * + * The headers array is a set of key/value pairs. If a header is present multiple times + * then the value is an array of all the values. + * + * @param string $content The content of the response + * @param integer $status The response status code + * @param array $headers An array of headers + * + * @api + */ + public function __construct($content = '', $status = 200, array $headers = array()) + { + $this->content = $content; + $this->status = $status; + $this->headers = $headers; + } + + /** + * Converts the response object to string containing all headers and the response content. + * + * @return string The response with headers and content + */ + public function __toString() + { + $headers = ''; + foreach ($this->headers as $name => $value) { + if (is_string($value)) { + $headers .= $this->buildHeader($name, $value); + } else { + foreach ($value as $headerValue) { + $headers .= $this->buildHeader($name, $headerValue); + } + } + } + + return $headers."\n".$this->content; + } + + /** + * Returns the build header line. + * + * @param string $name The header name + * @param string $value The header value + * + * @return string The built header line + */ + protected function buildHeader($name, $value) + { + return sprintf("%s: %s\n", $name, $value); + } + + /** + * Gets the response content. + * + * @return string The response content + * + * @api + */ + public function getContent() + { + return $this->content; + } + + /** + * Gets the response status code. + * + * @return integer The response status code + * + * @api + */ + public function getStatus() + { + return $this->status; + } + + /** + * Gets the response headers. + * + * @return array The response headers + * + * @api + */ + public function getHeaders() + { + return $this->headers; + } + + /** + * Gets a response header. + * + * @param string $header The header name + * @param Boolean $first Whether to return the first value or all header values + * + * @return string|array The first header value if $first is true, an array of values otherwise + */ + public function getHeader($header, $first = true) + { + foreach ($this->headers as $key => $value) { + if (str_replace('-', '_', strtolower($key)) == str_replace('-', '_', strtolower($header))) { + if ($first) { + return is_array($value) ? (count($value) ? $value[0] : '') : $value; + } + + return is_array($value) ? $value : array($value); + } + } + + return $first ? null : array(); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/ClientTest.php b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/ClientTest.php new file mode 100644 index 0000000..b5d5a0d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/ClientTest.php @@ -0,0 +1,400 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Tests\BrowserKit; + +use Symfony\Component\BrowserKit\Client; +use Symfony\Component\BrowserKit\History; +use Symfony\Component\BrowserKit\CookieJar; +use Symfony\Component\BrowserKit\Request; +use Symfony\Component\BrowserKit\Response; + +class TestClient extends Client +{ + protected $nextResponse = null; + protected $nextScript = null; + + public function setNextResponse(Response $response) + { + $this->nextResponse = $response; + } + + public function setNextScript($script) + { + $this->nextScript = $script; + } + + protected function doRequest($request) + { + if (null === $this->nextResponse) { + return new Response(); + } + + $response = $this->nextResponse; + $this->nextResponse = null; + + return $response; + } + + protected function getScript($request) + { + $r = new \ReflectionClass('Symfony\Component\BrowserKit\Response'); + $path = $r->getFileName(); + + return <<nextScript); +EOF; + } +} + +class ClientTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Symfony\Component\BrowserKit\Client::getHistory + */ + public function testGetHistory() + { + $client = new TestClient(array(), $history = new History()); + $this->assertSame($history, $client->getHistory(), '->getHistory() returns the History'); + } + + /** + * @covers Symfony\Component\BrowserKit\Client::getCookieJar + */ + public function testGetCookieJar() + { + $client = new TestClient(array(), null, $cookieJar = new CookieJar()); + $this->assertSame($cookieJar, $client->getCookieJar(), '->getCookieJar() returns the CookieJar'); + } + + /** + * @covers Symfony\Component\BrowserKit\Client::getRequest + */ + public function testGetRequest() + { + $client = new TestClient(); + $client->request('GET', 'http://example.com/'); + + $this->assertEquals('http://example.com/', $client->getRequest()->getUri(), '->getCrawler() returns the Request of the last request'); + } + + /** + * @covers Symfony\Component\BrowserKit\Client::getResponse + */ + public function testGetResponse() + { + $client = new TestClient(); + $client->setNextResponse(new Response('foo')); + $client->request('GET', 'http://example.com/'); + + $this->assertEquals('foo', $client->getResponse()->getContent(), '->getCrawler() returns the Response of the last request'); + } + + public function testGetContent() + { + $json = '{"jsonrpc":"2.0","method":"echo","id":7,"params":["Hello World"]}'; + + $client = new TestClient(); + $client->request('POST', 'http://example.com/jsonrpc', array(), array(), array(), $json); + $this->assertEquals($json, $client->getRequest()->getContent()); + } + + /** + * @covers Symfony\Component\BrowserKit\Client::getCrawler + */ + public function testGetCrawler() + { + $client = new TestClient(); + $client->setNextResponse(new Response('foo')); + $crawler = $client->request('GET', 'http://example.com/'); + + $this->assertSame($crawler, $client->getCrawler(), '->getCrawler() returns the Crawler of the last request'); + } + + public function testRequestHttpHeaders() + { + $client = new TestClient(); + $client->request('GET', '/'); + $headers = $client->getRequest()->getServer(); + $this->assertEquals('localhost', $headers['HTTP_HOST'], '->request() sets the HTTP_HOST header'); + + $client = new TestClient(); + $client->request('GET', 'http://www.example.com'); + $headers = $client->getRequest()->getServer(); + $this->assertEquals('www.example.com', $headers['HTTP_HOST'], '->request() sets the HTTP_HOST header'); + + $client->request('GET', 'https://www.example.com'); + $headers = $client->getRequest()->getServer(); + $this->assertTrue($headers['HTTPS'], '->request() sets the HTTPS header'); + } + + public function testRequestURIConversion() + { + $client = new TestClient(); + $client->request('GET', '/foo'); + $this->assertEquals('http://localhost/foo', $client->getRequest()->getUri(), '->request() converts the URI to an absolute one'); + + $client = new TestClient(); + $client->request('GET', 'http://www.example.com'); + $this->assertEquals('http://www.example.com', $client->getRequest()->getUri(), '->request() does not change absolute URIs'); + + $client = new TestClient(); + $client->request('GET', 'http://www.example.com/'); + $client->request('GET', '/foo'); + $this->assertEquals('http://www.example.com/foo', $client->getRequest()->getUri(), '->request() uses the previous request for relative URLs'); + + $client = new TestClient(); + $client->request('GET', 'http://www.example.com/foo'); + $client->request('GET', '#'); + $this->assertEquals('http://www.example.com/foo#', $client->getRequest()->getUri(), '->request() uses the previous request for #'); + $client->request('GET', '#'); + $this->assertEquals('http://www.example.com/foo#', $client->getRequest()->getUri(), '->request() uses the previous request for #'); + $client->request('GET', '#foo'); + $this->assertEquals('http://www.example.com/foo#foo', $client->getRequest()->getUri(), '->request() uses the previous request for #'); + + $client = new TestClient(); + $client->request('GET', 'http://www.example.com/foo/'); + $client->request('GET', 'bar'); + $this->assertEquals('http://www.example.com/foo/bar', $client->getRequest()->getUri(), '->request() uses the previous request for relative URLs'); + + $client = new TestClient(); + $client->request('GET', 'http://www.example.com/foo/foobar'); + $client->request('GET', 'bar'); + $this->assertEquals('http://www.example.com/foo/bar', $client->getRequest()->getUri(), '->request() uses the previous request for relative URLs'); + } + + public function testRequestReferer() + { + $client = new TestClient(); + $client->request('GET', 'http://www.example.com/foo/foobar'); + $client->request('GET', 'bar'); + $server = $client->getRequest()->getServer(); + $this->assertEquals('http://www.example.com/foo/foobar', $server['HTTP_REFERER'], '->request() sets the referer'); + } + + public function testRequestHistory() + { + $client = new TestClient(); + $client->request('GET', 'http://www.example.com/foo/foobar'); + $client->request('GET', 'bar'); + + $this->assertEquals('http://www.example.com/foo/bar', $client->getHistory()->current()->getUri(), '->request() updates the History'); + $this->assertEquals('http://www.example.com/foo/foobar', $client->getHistory()->back()->getUri(), '->request() updates the History'); + } + + public function testRequestCookies() + { + $client = new TestClient(); + $client->setNextResponse(new Response('foo', 200, array('Set-Cookie' => 'foo=bar'))); + $client->request('GET', 'http://www.example.com/foo/foobar'); + $this->assertEquals(array('foo' => 'bar'), $client->getCookieJar()->allValues('http://www.example.com/foo/foobar'), '->request() updates the CookieJar'); + + $client->request('GET', 'bar'); + $this->assertEquals(array('foo' => 'bar'), $client->getCookieJar()->allValues('http://www.example.com/foo/foobar'), '->request() updates the CookieJar'); + } + + public function testClick() + { + if (!class_exists('Symfony\Component\DomCrawler\Crawler')) { + $this->markTestSkipped('The "DomCrawler" component is not available'); + } + + if (!class_exists('Symfony\Component\CssSelector\CssSelector')) { + $this->markTestSkipped('The "CssSelector" component is not available'); + } + + $client = new TestClient(); + $client->setNextResponse(new Response('foo')); + $crawler = $client->request('GET', 'http://www.example.com/foo/foobar'); + + $client->click($crawler->filter('a')->link()); + + $this->assertEquals('http://www.example.com/foo', $client->getRequest()->getUri(), '->click() clicks on links'); + } + + public function testSubmit() + { + if (!class_exists('Symfony\Component\DomCrawler\Crawler')) { + $this->markTestSkipped('The "DomCrawler" component is not available'); + } + + if (!class_exists('Symfony\Component\CssSelector\CssSelector')) { + $this->markTestSkipped('The "CssSelector" component is not available'); + } + + $client = new TestClient(); + $client->setNextResponse(new Response('
    ')); + $crawler = $client->request('GET', 'http://www.example.com/foo/foobar'); + + $client->submit($crawler->filter('input')->form()); + + $this->assertEquals('http://www.example.com/foo', $client->getRequest()->getUri(), '->submit() submit forms'); + } + + public function testFollowRedirect() + { + $client = new TestClient(); + $client->followRedirects(false); + $client->request('GET', 'http://www.example.com/foo/foobar'); + + try { + $client->followRedirect(); + $this->fail('->followRedirect() throws a \LogicException if the request was not redirected'); + } catch (\Exception $e) { + $this->assertInstanceof('LogicException', $e, '->followRedirect() throws a \LogicException if the request was not redirected'); + } + + $client->setNextResponse(new Response('', 302, array('Location' => 'http://www.example.com/redirected'))); + $client->request('GET', 'http://www.example.com/foo/foobar'); + $client->followRedirect(); + + $this->assertEquals('http://www.example.com/redirected', $client->getRequest()->getUri(), '->followRedirect() follows a redirect if any'); + + $client = new TestClient(); + $client->setNextResponse(new Response('', 302, array('Location' => 'http://www.example.com/redirected'))); + $client->request('GET', 'http://www.example.com/foo/foobar'); + + $this->assertEquals('http://www.example.com/redirected', $client->getRequest()->getUri(), '->followRedirect() automatically follows redirects if followRedirects is true'); + } + + public function testFollowRedirectWithCookies() + { + $client = new TestClient(); + $client->followRedirects(false); + $client->setNextResponse(new Response('', 302, array( + 'Location' => 'http://www.example.com/redirected', + 'Set-Cookie' => 'foo=bar', + ))); + $client->request('GET', 'http://www.example.com/'); + $this->assertEquals(array(), $client->getRequest()->getCookies()); + $client->followRedirect(); + $this->assertEquals(array('foo' => 'bar'), $client->getRequest()->getCookies()); + } + + public function testBack() + { + $client = new TestClient(); + + $parameters = array('foo' => 'bar'); + $files = array('myfile.foo' => 'baz'); + $server = array('X_TEST_FOO' => 'bazbar'); + $content = 'foobarbaz'; + + $client->request('GET', 'http://www.example.com/foo/foobar', $parameters, $files, $server, $content); + $client->request('GET', 'http://www.example.com/foo'); + $client->back(); + + $this->assertEquals('http://www.example.com/foo/foobar', $client->getRequest()->getUri(), '->back() goes back in the history'); + $this->assertArrayHasKey('foo', $client->getRequest()->getParameters(), '->back() keeps parameters'); + $this->assertArrayHasKey('myfile.foo', $client->getRequest()->getFiles(), '->back() keeps files'); + $this->assertArrayHasKey('X_TEST_FOO', $client->getRequest()->getServer(), '->back() keeps $_SERVER'); + $this->assertEquals($content, $client->getRequest()->getContent(), '->back() keeps content'); + } + + public function testForward() + { + $client = new TestClient(); + + $parameters = array('foo' => 'bar'); + $files = array('myfile.foo' => 'baz'); + $server = array('X_TEST_FOO' => 'bazbar'); + $content = 'foobarbaz'; + + $client->request('GET', 'http://www.example.com/foo/foobar'); + $client->request('GET', 'http://www.example.com/foo', $parameters, $files, $server, $content); + $client->back(); + $client->forward(); + + $this->assertEquals('http://www.example.com/foo', $client->getRequest()->getUri(), '->forward() goes forward in the history'); + $this->assertArrayHasKey('foo', $client->getRequest()->getParameters(), '->forward() keeps parameters'); + $this->assertArrayHasKey('myfile.foo', $client->getRequest()->getFiles(), '->forward() keeps files'); + $this->assertArrayHasKey('X_TEST_FOO', $client->getRequest()->getServer(), '->forward() keeps $_SERVER'); + $this->assertEquals($content, $client->getRequest()->getContent(), '->forward() keeps content'); + } + + public function testReload() + { + $client = new TestClient(); + + $parameters = array('foo' => 'bar'); + $files = array('myfile.foo' => 'baz'); + $server = array('X_TEST_FOO' => 'bazbar'); + $content = 'foobarbaz'; + + $client->request('GET', 'http://www.example.com/foo/foobar', $parameters, $files, $server, $content); + $client->reload(); + + $this->assertEquals('http://www.example.com/foo/foobar', $client->getRequest()->getUri(), '->reload() reloads the current page'); + $this->assertArrayHasKey('foo', $client->getRequest()->getParameters(), '->reload() keeps parameters'); + $this->assertArrayHasKey('myfile.foo', $client->getRequest()->getFiles(), '->reload() keeps files'); + $this->assertArrayHasKey('X_TEST_FOO', $client->getRequest()->getServer(), '->reload() keeps $_SERVER'); + $this->assertEquals($content, $client->getRequest()->getContent(), '->reload() keeps content'); + } + + public function testRestart() + { + $client = new TestClient(); + $client->request('GET', 'http://www.example.com/foo/foobar'); + $client->restart(); + + $this->assertTrue($client->getHistory()->isEmpty(), '->restart() clears the history'); + $this->assertEquals(array(), $client->getCookieJar()->all(), '->restart() clears the cookies'); + } + + public function testInsulatedRequests() + { + if (!class_exists('Symfony\Component\Process\Process')) { + $this->markTestSkipped('The "Process" component is not available'); + } + + $client = new TestClient(); + $client->insulate(); + $client->setNextScript("new Symfony\Component\BrowserKit\Response('foobar')"); + $client->request('GET', 'http://www.example.com/foo/foobar'); + + $this->assertEquals('foobar', $client->getResponse()->getContent(), '->insulate() process the request in a forked process'); + + $client->setNextScript("new Symfony\Component\BrowserKit\Response('foobar)"); + + try { + $client->request('GET', 'http://www.example.com/foo/foobar'); + $this->fail('->request() throws a \RuntimeException if the script has an error'); + } catch (\Exception $e) { + $this->assertInstanceof('RuntimeException', $e, '->request() throws a \RuntimeException if the script has an error'); + } + } + + public function testGetServerParameter() + { + $client = new TestClient(); + $this->assertEquals('localhost', $client->getServerParameter('HTTP_HOST')); + $this->assertEquals('Symfony2 BrowserKit', $client->getServerParameter('HTTP_USER_AGENT')); + $this->assertEquals('testvalue', $client->getServerParameter('testkey', 'testvalue')); + } + + public function testSetServerParameter() + { + $client = new TestClient(); + + $this->assertEquals('localhost', $client->getServerParameter('HTTP_HOST')); + $this->assertEquals('Symfony2 BrowserKit', $client->getServerParameter('HTTP_USER_AGENT')); + + $client->setServerParameter('HTTP_HOST', 'testhost'); + $this->assertEquals('testhost', $client->getServerParameter('HTTP_HOST')); + + $client->setServerParameter('HTTP_USER_AGENT', 'testua'); + $this->assertEquals('testua', $client->getServerParameter('HTTP_USER_AGENT')); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/CookieJarTest.php b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/CookieJarTest.php new file mode 100644 index 0000000..218c688 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/CookieJarTest.php @@ -0,0 +1,168 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Tests\BrowserKit; + +use Symfony\Component\BrowserKit\CookieJar; +use Symfony\Component\BrowserKit\Cookie; +use Symfony\Component\BrowserKit\Response; + +class CookieJarTest extends \PHPUnit_Framework_TestCase +{ + public function testSetGet() + { + $cookieJar = new CookieJar(); + $cookieJar->set($cookie = new Cookie('foo', 'bar')); + + $this->assertEquals($cookie, $cookieJar->get('foo'), '->set() sets a cookie'); + + $this->assertNull($cookieJar->get('foobar'), '->get() returns null if the cookie does not exist'); + + $cookieJar->set($cookie = new Cookie('foo', 'bar', time() - 86400)); + $this->assertNull($cookieJar->get('foo'), '->get() returns null if the cookie is expired'); + } + + public function testExpire() + { + $cookieJar = new CookieJar(); + $cookieJar->set($cookie = new Cookie('foo', 'bar')); + $cookieJar->expire('foo'); + $this->assertNull($cookieJar->get('foo'), '->get() returns null if the cookie is expired'); + } + + public function testAll() + { + $cookieJar = new CookieJar(); + $cookieJar->set($cookie1 = new Cookie('foo', 'bar')); + $cookieJar->set($cookie2 = new Cookie('bar', 'foo')); + + $this->assertEquals(array($cookie1, $cookie2), $cookieJar->all(), '->all() returns all cookies in the jar'); + } + + public function testClear() + { + $cookieJar = new CookieJar(); + $cookieJar->set($cookie1 = new Cookie('foo', 'bar')); + $cookieJar->set($cookie2 = new Cookie('bar', 'foo')); + + $cookieJar->clear(); + + $this->assertEquals(array(), $cookieJar->all(), '->clear() expires all cookies'); + } + + public function testUpdateFromResponse() + { + $response = new Response('', 200, array('Set-Cookie' => 'foo=foo')); + + $cookieJar = new CookieJar(); + $cookieJar->updateFromResponse($response); + + $this->assertEquals('foo', $cookieJar->get('foo')->getValue(), '->updateFromResponse() updates cookies from a Response objects'); + } + + public function testUpdateFromSetCookie() + { + $setCookies = array('foo=foo'); + + $cookieJar = new CookieJar(); + $cookieJar->set(new Cookie('bar', 'bar')); + $cookieJar->updateFromSetCookie($setCookies); + + $this->assertInstanceOf('Symfony\Component\BrowserKit\Cookie', $cookieJar->get('foo')); + $this->assertInstanceOf('Symfony\Component\BrowserKit\Cookie', $cookieJar->get('bar')); + $this->assertEquals('foo', $cookieJar->get('foo')->getValue(), '->updateFromSetCookie() updates cookies from a Set-Cookie header'); + $this->assertEquals('bar', $cookieJar->get('bar')->getValue(), '->updateFromSetCookie() keeps existing cookies'); + } + + public function testUpdateFromSetCookieWithMultipleCookies() + { + $timestamp = time() + 3600; + $date = gmdate('D, d M Y H:i:s \G\M\T', $timestamp); + $setCookies = array(sprintf('foo=foo; expires=%s; domain=.symfony.com; path=/, bar=bar; domain=.blog.symfony.com, PHPSESSID=id; expires=%s', $date, $date)); + + $cookieJar = new CookieJar(); + $cookieJar->updateFromSetCookie($setCookies); + + $fooCookie = $cookieJar->get('foo', '/', '.symfony.com'); + $barCookie = $cookieJar->get('bar', '/', '.blog.symfony.com'); + $phpCookie = $cookieJar->get('PHPSESSID'); + + $this->assertInstanceOf('Symfony\Component\BrowserKit\Cookie', $fooCookie); + $this->assertInstanceOf('Symfony\Component\BrowserKit\Cookie', $barCookie); + $this->assertInstanceOf('Symfony\Component\BrowserKit\Cookie', $phpCookie); + $this->assertEquals('foo', $fooCookie->getValue()); + $this->assertEquals('bar', $barCookie->getValue()); + $this->assertEquals('id', $phpCookie->getValue()); + $this->assertEquals($timestamp, $fooCookie->getExpiresTime()); + $this->assertNull($barCookie->getExpiresTime()); + $this->assertEquals($timestamp, $phpCookie->getExpiresTime()); + } + + /** + * @dataProvider provideAllValuesValues + */ + public function testAllValues($uri, $values) + { + $cookieJar = new CookieJar(); + $cookieJar->set($cookie1 = new Cookie('foo_nothing', 'foo')); + $cookieJar->set($cookie2 = new Cookie('foo_expired', 'foo', time() - 86400)); + $cookieJar->set($cookie3 = new Cookie('foo_path', 'foo', null, '/foo')); + $cookieJar->set($cookie4 = new Cookie('foo_domain', 'foo', null, '/', '.example.com')); + $cookieJar->set($cookie4 = new Cookie('foo_strict_domain', 'foo', null, '/', '.www4.example.com')); + $cookieJar->set($cookie5 = new Cookie('foo_secure', 'foo', null, '/', '', true)); + + $this->assertEquals($values, array_keys($cookieJar->allValues($uri)), '->allValues() returns the cookie for a given URI'); + } + + public function provideAllValuesValues() + { + return array( + array('http://www.example.com', array('foo_nothing', 'foo_domain')), + array('http://www.example.com/', array('foo_nothing', 'foo_domain')), + array('http://foo.example.com/', array('foo_nothing', 'foo_domain')), + array('http://foo.example1.com/', array('foo_nothing')), + array('https://foo.example.com/', array('foo_nothing', 'foo_secure', 'foo_domain')), + array('http://www.example.com/foo/bar', array('foo_nothing', 'foo_path', 'foo_domain')), + array('http://www4.example.com/', array('foo_nothing', 'foo_domain', 'foo_strict_domain')), + ); + } + + public function testEncodedValues() + { + $cookieJar = new CookieJar(); + $cookieJar->set($cookie = new Cookie('foo', 'bar%3Dbaz', null, '/', '', false, true, true)); + + $this->assertEquals(array('foo' => 'bar=baz'), $cookieJar->allValues('/')); + $this->assertEquals(array('foo' => 'bar%3Dbaz'), $cookieJar->allRawValues('/')); + } + + public function testCookieWithSameNameButDifferentPaths() + { + $cookieJar = new CookieJar(); + $cookieJar->set($cookie1 = new Cookie('foo', 'bar1', null, '/foo')); + $cookieJar->set($cookie2 = new Cookie('foo', 'bar2', null, '/bar')); + + $this->assertEquals(array(), array_keys($cookieJar->allValues('http://example.com/'))); + $this->assertEquals(array('foo' => 'bar1'), $cookieJar->allValues('http://example.com/foo')); + $this->assertEquals(array('foo' => 'bar2'), $cookieJar->allValues('http://example.com/bar')); + } + + public function testCookieWithSameNameButDifferentDomains() + { + $cookieJar = new CookieJar(); + $cookieJar->set($cookie1 = new Cookie('foo', 'bar1', null, '/', 'foo.example.com')); + $cookieJar->set($cookie2 = new Cookie('foo', 'bar2', null, '/', 'bar.example.com')); + + $this->assertEquals(array(), array_keys($cookieJar->allValues('http://example.com/'))); + $this->assertEquals(array('foo' => 'bar1'), $cookieJar->allValues('http://foo.example.com/')); + $this->assertEquals(array('foo' => 'bar2'), $cookieJar->allValues('http://bar.example.com/')); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/CookieTest.php b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/CookieTest.php new file mode 100644 index 0000000..fbc493a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/CookieTest.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\Tests\BrowserKit; + +use Symfony\Component\BrowserKit\Cookie; + +class CookieTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getTestsForToFromString + */ + public function testToFromString($cookie, $url = null) + { + $this->assertEquals($cookie, (string) Cookie::fromString($cookie, $url)); + } + + public function getTestsForToFromString() + { + return array( + array('foo=bar'), + array('foo=bar; path=/foo'), + array('foo=bar; domain=google.com'), + array('foo=bar; domain=example.com; secure', 'https://example.com/'), + array('foo=bar; httponly'), + array('foo=bar; domain=google.com; path=/foo; secure; httponly', 'https://google.com/'), + array('foo=bar=baz'), + array('foo=bar%3Dbaz'), + ); + } + + public function testFromStringIgnoreSecureFlag() + { + $this->assertFalse(Cookie::fromString('foo=bar; secure')->isSecure()); + $this->assertFalse(Cookie::fromString('foo=bar; secure', 'http://example.com/')->isSecure()); + } + + /** + * @dataProvider getExpireCookieStrings + */ + public function testFromStringAcceptsSeveralExpiresDateFormats($cookie) + { + $this->assertEquals(1596185377, Cookie::fromString($cookie)->getExpiresTime()); + } + + public function getExpireCookieStrings() + { + return array( + array('foo=bar; expires=Fri, 31-Jul-2020 08:49:37 GMT'), + array('foo=bar; expires=Fri, 31 Jul 2020 08:49:37 GMT'), + array('foo=bar; expires=Friday, 31-Jul-20 08:49:37 GMT'), + array('foo=bar; expires=Fri Jul 31 08:49:37 2020'), + ); + } + + public function testFromStringWithCapitalization() + { + $this->assertEquals('Foo=Bar', (string) Cookie::fromString('Foo=Bar')); + $this->assertEquals('foo=bar; expires=Fri, 31 Dec 2010 23:59:59 GMT', (string) Cookie::fromString('foo=bar; Expires=Fri, 31 Dec 2010 23:59:59 GMT')); + $this->assertEquals('foo=bar; domain=www.example.org; httponly', (string) Cookie::fromString('foo=bar; DOMAIN=www.example.org; HttpOnly')); + } + + public function testFromStringWithUrl() + { + $this->assertEquals('foo=bar; domain=www.example.com', (string) Cookie::FromString('foo=bar', 'http://www.example.com/')); + $this->assertEquals('foo=bar; domain=www.example.com; path=/foo', (string) Cookie::FromString('foo=bar', 'http://www.example.com/foo/bar')); + $this->assertEquals('foo=bar; domain=www.example.com', (string) Cookie::FromString('foo=bar; path=/', 'http://www.example.com/foo/bar')); + $this->assertEquals('foo=bar; domain=www.myotherexample.com', (string) Cookie::FromString('foo=bar; domain=www.myotherexample.com', 'http://www.example.com/')); + } + + public function testFromStringThrowsAnExceptionIfCookieIsNotValid() + { + $this->setExpectedException('InvalidArgumentException'); + Cookie::FromString('foo'); + } + + public function testFromStringThrowsAnExceptionIfCookieDateIsNotValid() + { + $this->setExpectedException('InvalidArgumentException'); + Cookie::FromString('foo=bar; expires=foo'); + } + + public function testFromStringThrowsAnExceptionIfUrlIsNotValid() + { + $this->setExpectedException('InvalidArgumentException'); + Cookie::FromString('foo=bar', 'foobar'); + } + + public function testGetName() + { + $cookie = new Cookie('foo', 'bar'); + $this->assertEquals('foo', $cookie->getName(), '->getName() returns the cookie name'); + } + + public function testGetValue() + { + $cookie = new Cookie('foo', 'bar'); + $this->assertEquals('bar', $cookie->getValue(), '->getValue() returns the cookie value'); + + $cookie = new Cookie('foo', 'bar%3Dbaz', null, '/', '', false, true, true); // raw value + $this->assertEquals('bar=baz', $cookie->getValue(), '->getValue() returns the urldecoded cookie value'); + } + + public function testGetRawValue() + { + $cookie = new Cookie('foo', 'bar=baz'); // decoded value + $this->assertEquals('bar%3Dbaz', $cookie->getRawValue(), '->getRawValue() returns the urlencoded cookie value'); + $cookie = new Cookie('foo', 'bar%3Dbaz', null, '/', '', false, true, true); // raw value + $this->assertEquals('bar%3Dbaz', $cookie->getRawValue(), '->getRawValue() returns the non-urldecoded cookie value'); + } + + public function testGetPath() + { + $cookie = new Cookie('foo', 'bar', 0); + $this->assertEquals('/', $cookie->getPath(), '->getPath() returns / is no path is defined'); + + $cookie = new Cookie('foo', 'bar', 0, '/foo'); + $this->assertEquals('/foo', $cookie->getPath(), '->getPath() returns the cookie path'); + } + + public function testGetDomain() + { + $cookie = new Cookie('foo', 'bar', 0, '/', 'foo.com'); + $this->assertEquals('foo.com', $cookie->getDomain(), '->getDomain() returns the cookie domain'); + } + + public function testIsSecure() + { + $cookie = new Cookie('foo', 'bar'); + $this->assertFalse($cookie->isSecure(), '->isSecure() returns false if not defined'); + + $cookie = new Cookie('foo', 'bar', 0, '/', 'foo.com', true); + $this->assertTrue($cookie->isSecure(), '->isSecure() returns the cookie secure flag'); + } + + public function testIsHttponly() + { + $cookie = new Cookie('foo', 'bar'); + $this->assertTrue($cookie->isHttpOnly(), '->isHttpOnly() returns false if not defined'); + + $cookie = new Cookie('foo', 'bar', 0, '/', 'foo.com', false, true); + $this->assertTrue($cookie->isHttpOnly(), '->isHttpOnly() returns the cookie httponly flag'); + } + + public function testGetExpiresTime() + { + $cookie = new Cookie('foo', 'bar'); + $this->assertNull($cookie->getExpiresTime(), '->getExpiresTime() returns the expires time'); + + $cookie = new Cookie('foo', 'bar', $time = time() - 86400); + $this->assertEquals($time, $cookie->getExpiresTime(), '->getExpiresTime() returns the expires time'); + } + + public function testIsExpired() + { + $cookie = new Cookie('foo', 'bar'); + $this->assertFalse($cookie->isExpired(), '->isExpired() returns false when the cookie never expires (null as expires time)'); + + $cookie = new Cookie('foo', 'bar', time() - 86400); + $this->assertTrue($cookie->isExpired(), '->isExpired() returns true when the cookie is expired'); + + $cookie = new Cookie('foo', 'bar', 0); + $this->assertFalse($cookie->isExpired()); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/HistoryTest.php b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/HistoryTest.php new file mode 100644 index 0000000..6794f31 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/HistoryTest.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\Tests\BrowserKit; + +use Symfony\Component\BrowserKit\History; +use Symfony\Component\BrowserKit\Request; + +class HistoryTest extends \PHPUnit_Framework_TestCase +{ + public function testAdd() + { + $history = new History(); + $history->add(new Request('http://www.example1.com/', 'get')); + $this->assertSame('http://www.example1.com/', $history->current()->getUri(), '->add() adds a request to the history'); + + $history->add(new Request('http://www.example2.com/', 'get')); + $this->assertSame('http://www.example2.com/', $history->current()->getUri(), '->add() adds a request to the history'); + + $history->add(new Request('http://www.example3.com/', 'get')); + $history->back(); + $history->add(new Request('http://www.example4.com/', 'get')); + $this->assertSame('http://www.example4.com/', $history->current()->getUri(), '->add() adds a request to the history'); + + $history->back(); + $this->assertSame('http://www.example2.com/', $history->current()->getUri(), '->add() adds a request to the history'); + } + + public function testClearIsEmpty() + { + $history = new History(); + $history->add(new Request('http://www.example.com/', 'get')); + + $this->assertFalse($history->isEmpty(), '->isEmpty() returns false if the history is not empty'); + + $history->clear(); + + $this->assertTrue($history->isEmpty(), '->isEmpty() true if the history is empty'); + } + + public function testCurrent() + { + $history = new History(); + + try { + $history->current(); + $this->fail('->current() throws a \LogicException if the history is empty'); + } catch (\Exception $e) { + $this->assertInstanceof('LogicException', $e, '->current() throws a \LogicException if the history is empty'); + } + + $history->add(new Request('http://www.example.com/', 'get')); + + $this->assertSame('http://www.example.com/', $history->current()->getUri(), '->current() returns the current request in the history'); + } + + public function testBack() + { + $history = new History(); + $history->add(new Request('http://www.example.com/', 'get')); + + try { + $history->back(); + $this->fail('->back() throws a \LogicException if the history is already on the first page'); + } catch (\Exception $e) { + $this->assertInstanceof('LogicException', $e, '->current() throws a \LogicException if the history is already on the first page'); + } + + $history->add(new Request('http://www.example1.com/', 'get')); + $history->back(); + + $this->assertSame('http://www.example.com/', $history->current()->getUri(), '->back() returns the previous request in the history'); + } + + public function testForward() + { + $history = new History(); + $history->add(new Request('http://www.example.com/', 'get')); + $history->add(new Request('http://www.example1.com/', 'get')); + + try { + $history->forward(); + $this->fail('->forward() throws a \LogicException if the history is already on the last page'); + } catch (\Exception $e) { + $this->assertInstanceof('LogicException', $e, '->forward() throws a \LogicException if the history is already on the last page'); + } + + $history->back(); + $history->forward(); + + $this->assertSame('http://www.example1.com/', $history->current()->getUri(), '->forward() returns the next request in the history'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/RequestTest.php b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/RequestTest.php new file mode 100644 index 0000000..c567fad --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/RequestTest.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\Tests\BrowserKit; + +use Symfony\Component\BrowserKit\Request; + +class RequestTest extends \PHPUnit_Framework_TestCase +{ + public function testGetUri() + { + $request = new Request('http://www.example.com/', 'get'); + $this->assertEquals('http://www.example.com/', $request->getUri(), '->getUri() returns the URI of the request'); + } + + public function testGetMethod() + { + $request = new Request('http://www.example.com/', 'get'); + $this->assertEquals('get', $request->getMethod(), '->getMethod() returns the method of the request'); + } + + public function testGetParameters() + { + $request = new Request('http://www.example.com/', 'get', array('foo' => 'bar')); + $this->assertEquals(array('foo' => 'bar'), $request->getParameters(), '->getParameters() returns the parameters of the request'); + } + + public function testGetFiles() + { + $request = new Request('http://www.example.com/', 'get', array(), array('foo' => 'bar')); + $this->assertEquals(array('foo' => 'bar'), $request->getFiles(), '->getFiles() returns the uploaded files of the request'); + } + + public function testGetCookies() + { + $request = new Request('http://www.example.com/', 'get', array(), array(), array('foo' => 'bar')); + $this->assertEquals(array('foo' => 'bar'), $request->getCookies(), '->getCookies() returns the cookies of the request'); + } + + public function testGetServer() + { + $request = new Request('http://www.example.com/', 'get', array(), array(), array(), array('foo' => 'bar')); + $this->assertEquals(array('foo' => 'bar'), $request->getServer(), '->getServer() returns the server parameters of the request'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/ResponseTest.php b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/ResponseTest.php new file mode 100644 index 0000000..1e8c638 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/ResponseTest.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\Tests\BrowserKit; + +use Symfony\Component\BrowserKit\Response; + +class ResponseTest extends \PHPUnit_Framework_TestCase +{ + public function testGetUri() + { + $response = new Response('foo'); + $this->assertEquals('foo', $response->getContent(), '->getContent() returns the content of the response'); + } + + public function testGetStatus() + { + $response = new Response('foo', 304); + $this->assertEquals('304', $response->getStatus(), '->getStatus() returns the status of the response'); + } + + public function testGetHeaders() + { + $response = new Response('foo', 200, array('foo' => 'bar')); + $this->assertEquals(array('foo' => 'bar'), $response->getHeaders(), '->getHeaders() returns the headers of the response'); + } + + public function testGetHeader() + { + $response = new Response('foo', 200, array( + 'Content-Type' => 'text/html', + 'Set-Cookie' => array('foo=bar', 'bar=foo'), + )); + + $this->assertEquals('text/html', $response->getHeader('Content-Type'), '->getHeader() returns a header of the response'); + $this->assertEquals('text/html', $response->getHeader('content-type'), '->getHeader() returns a header of the response'); + $this->assertEquals('text/html', $response->getHeader('content_type'), '->getHeader() returns a header of the response'); + $this->assertEquals('foo=bar', $response->getHeader('Set-Cookie'), '->getHeader() returns the first header value'); + $this->assertEquals(array('foo=bar', 'bar=foo'), $response->getHeader('Set-Cookie', false), '->getHeader() returns all header values if first is false'); + + $this->assertNull($response->getHeader('foo'), '->getHeader() returns null if the header is not defined'); + $this->assertEquals(array(), $response->getHeader('foo', false), '->getHeader() returns an empty array if the header is not defined and first is set to false'); + } + + public function testMagicToString() + { + $response = new Response('foo', 304, array('foo' => 'bar')); + + $this->assertEquals("foo: bar\n\nfoo", $response->__toString(), '->__toString() returns the headers and the content as a string'); + } + + public function testMagicToStringWithMultipleSetCookieHeader() + { + $headers = array( + 'content-type' => 'text/html; charset=utf-8', + 'set-cookie' => array('foo=bar', 'bar=foo') + ); + + $expected = 'content-type: text/html; charset=utf-8'."\n"; + $expected.= 'set-cookie: foo=bar'."\n"; + $expected.= 'set-cookie: bar=foo'."\n\n"; + $expected.= 'foo'; + + $response = new Response('foo', 304, $headers); + + $this->assertEquals($expected, $response->__toString(), '->__toString() returns the headers and the content as a string'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/bootstrap.php b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/bootstrap.php new file mode 100644 index 0000000..1b326ff --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Tests/bootstrap.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +spl_autoload_register(function ($class) { + if (0 === strpos(ltrim($class, '/'), 'Symfony\Component\BrowserKit')) { + if (file_exists($file = __DIR__.'/../'.substr(str_replace('\\', '/', $class), strlen('Symfony\Component\BrowserKit')).'.php')) { + require_once $file; + } + } +}); + +if (file_exists($loader = __DIR__.'/../vendor/autoload.php')) { + require_once $loader; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/composer.json b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/composer.json new file mode 100644 index 0000000..c5f208a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/composer.json @@ -0,0 +1,38 @@ +{ + "name": "symfony/browser-kit", + "type": "library", + "description": "Symfony BrowserKit 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/dom-crawler": "2.1.*" + }, + "require-dev": { + "symfony/process": "2.1.*", + "symfony/css-selector": "2.1.*" + }, + "suggest": { + "symfony/process": "self.version" + }, + "autoload": { + "psr-0": { "Symfony\\Component\\BrowserKit": "" } + }, + "target-dir": "Symfony/Component/BrowserKit", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/phpunit.xml.dist b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/phpunit.xml.dist new file mode 100644 index 0000000..0ddabed --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/phpunit.xml.dist @@ -0,0 +1,30 @@ + + + + + + ./Tests/ + + + + + + ./ + + ./Resources + ./Tests + ./vendor + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/ApcClassLoader.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/ApcClassLoader.php new file mode 100644 index 0000000..04104a1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/ApcClassLoader.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\ClassLoader; + +/** + * ApcClassLoader implements a wrapping autoloader cached in APC for PHP 5.3. + * + * It expects an object implementing a findFile method to find the file. This + * allow using it as a wrapper around the other loaders of the component (the + * ClassLoader and the UniversalClassLoader for instance) but also around any + * other autoloader following this convention (the Composer one for instance) + * + * $loader = new ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * $cachedLoader = new ApcClassLoader('my_prefix', $loader); + * + * // activate the cached autoloader + * $cachedLoader->register(); + * + * // eventually deactivate the non-cached loader if it was registered previously + * // to be sure to use the cached one. + * $loader->unregister(); + * + * @author Fabien Potencier + * @author Kris Wallsmith + * + * @api + */ +class ApcClassLoader +{ + private $prefix; + private $classFinder; + + /** + * Constructor. + * + * @param string $prefix A prefix to create a namespace in APC + * @param object $classFinder An object that implements findFile() method. + * + * @api + */ + public function __construct($prefix, $classFinder) + { + if (!extension_loaded('apc')) { + throw new \RuntimeException('Unable to use ApcUniversalClassLoader as APC is not enabled.'); + } + + if (!method_exists($classFinder, 'findFile')) { + throw new \InvalidArgumentException('The class finder must implement a "findFile" method.'); + } + + $this->prefix = $prefix; + $this->classFinder = $classFinder; + } + + /** + * Registers this instance as an autoloader. + * + * @param Boolean $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 Boolean|null True, if loaded + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + require $file; + + return true; + } + } + + /** + * Finds a file by class name while caching lookups to APC. + * + * @param string $class A class name to resolve to file + * + * @return string|null + */ + public function findFile($class) + { + if (false === $file = apc_fetch($this->prefix.$class)) { + apc_store($this->prefix.$class, $file = $this->classFinder->findFile($class)); + } + + return $file; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php new file mode 100644 index 0000000..379fbe4 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/ApcUniversalClassLoader.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\ClassLoader; + +/** + * ApcUniversalClassLoader implements a "universal" autoloader cached in APC for PHP 5.3. + * + * It is able to load classes that use either: + * + * * The technical interoperability standards for PHP 5.3 namespaces and + * class names (https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md); + * + * * The PEAR naming convention for classes (http://pear.php.net/). + * + * Classes from a sub-namespace or a sub-hierarchy of PEAR classes can be + * looked for in a list of locations to ease the vendoring of a sub-set of + * classes for large projects. + * + * Example usage: + * + * require 'vendor/symfony/src/Symfony/Component/ClassLoader/UniversalClassLoader.php'; + * require 'vendor/symfony/src/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php'; + * + * use Symfony\Component\ClassLoader\ApcUniversalClassLoader; + * + * $loader = new ApcUniversalClassLoader('apc.prefix.'); + * + * // register classes with namespaces + * $loader->registerNamespaces(array( + * 'Symfony\Component' => __DIR__.'/component', + * 'Symfony' => __DIR__.'/framework', + * 'Sensio' => array(__DIR__.'/src', __DIR__.'/vendor'), + * )); + * + * // register a library using the PEAR naming convention + * $loader->registerPrefixes(array( + * 'Swift_' => __DIR__.'/Swift', + * )); + * + * // activate the autoloader + * $loader->register(); + * + * 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. + * + * @author Fabien Potencier + * @author Kris Wallsmith + * + * @api + */ +class ApcUniversalClassLoader extends UniversalClassLoader +{ + private $prefix; + + /** + * Constructor. + * + * @param string $prefix A prefix to create a namespace in APC + * + * @api + */ + public function __construct($prefix) + { + if (!extension_loaded('apc')) { + throw new \RuntimeException('Unable to use ApcUniversalClassLoader as APC is not enabled.'); + } + + $this->prefix = $prefix; + } + + /** + * Finds a file by class name while caching lookups to APC. + * + * @param string $class A class name to resolve to file + * + * @return string|null The path, if found + */ + public function findFile($class) + { + if (false === $file = apc_fetch($this->prefix.$class)) { + apc_store($this->prefix.$class, $file = parent::findFile($class)); + } + + return $file; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/CHANGELOG.md b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/CHANGELOG.md new file mode 100644 index 0000000..694e713 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/CHANGELOG.md @@ -0,0 +1,15 @@ +CHANGELOG +========= + +2.1.0 +----- + + * added a DebugClassLoader able to wrap any autoloader providing a findFile + method + * added a new ApcClassLoader and XcacheClassLoader using composition to wrap + other loaders + * added a new ClassLoader which does not distinguish between namespaced and + pear-like classes (as the PEAR convention is a subset of PSR-0) and + supports using Composer's namespace maps + * added a class map generator + * added support for loading globally-installed PEAR packages diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php new file mode 100644 index 0000000..47588f7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php @@ -0,0 +1,223 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ClassLoader; + +/** + * ClassCollectionLoader. + * + * @author Fabien Potencier + */ +class ClassCollectionLoader +{ + static private $loaded; + + /** + * Loads a list of classes and caches them in one big file. + * + * @param array $classes An array of classes to load + * @param string $cacheDir A cache directory + * @param string $name The cache name prefix + * @param Boolean $autoReload Whether to flush the cache when the cache is stale or not + * @param Boolean $adaptive Whether to remove already declared classes or not + * @param string $extension File extension of the resulting file + * + * @throws \InvalidArgumentException When class can't be loaded + */ + static public function load($classes, $cacheDir, $name, $autoReload, $adaptive = false, $extension = '.php') + { + // each $name can only be loaded once per PHP process + if (isset(self::$loaded[$name])) { + return; + } + + self::$loaded[$name] = true; + + if ($adaptive) { + // don't include already declared classes + $classes = array_diff($classes, get_declared_classes(), get_declared_interfaces()); + + // the cache is different depending on which classes are already declared + $name = $name.'-'.substr(md5(implode('|', $classes)), 0, 5); + } + + $cache = $cacheDir.'/'.$name.$extension; + + // auto-reload + $reload = false; + if ($autoReload) { + $metadata = $cacheDir.'/'.$name.$extension.'.meta'; + if (!is_file($metadata) || !is_file($cache)) { + $reload = true; + } else { + $time = filemtime($cache); + $meta = unserialize(file_get_contents($metadata)); + + if ($meta[1] != $classes) { + $reload = true; + } else { + foreach ($meta[0] as $resource) { + if (!is_file($resource) || filemtime($resource) > $time) { + $reload = true; + + break; + } + } + } + } + } + + if (!$reload && is_file($cache)) { + require_once $cache; + + return; + } + + $files = array(); + $content = ''; + foreach ($classes as $class) { + if (!class_exists($class) && !interface_exists($class) && (!function_exists('trait_exists') || !trait_exists($class))) { + throw new \InvalidArgumentException(sprintf('Unable to load class "%s"', $class)); + } + + $r = new \ReflectionClass($class); + $files[] = $r->getFileName(); + + $c = preg_replace(array('/^\s*<\?php/', '/\?>\s*$/'), '', file_get_contents($r->getFileName())); + + // add namespace declaration for global code + if (!$r->inNamespace()) { + $c = "\nnamespace\n{\n".self::stripComments($c)."\n}\n"; + } else { + $c = self::fixNamespaceDeclarations(' + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ClassLoader; + +/** + * ClassLoader implements an PSR-0 class loader + * + * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md + * + * $loader = new ClassLoader(); + * + * // register classes with namespaces + * $loader->addPrefix('Symfony\Component', __DIR__.'/component'); + * $loader->addPrefix('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (e.g. 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. + * + * @author Fabien Potencier + * @author Jordi Boggiano + */ +class ClassLoader +{ + private $prefixes = array(); + private $fallbackDirs = array(); + private $useIncludePath = false; + + /** + * Returns prefixes. + * + * @return array + */ + public function getPrefixes() + { + return $this->prefixes; + } + + /** + * Returns fallback directories. + * + * @return array + */ + public function getFallbackDirs() + { + return $this->fallbackDirs; + } + + /** + * Adds prefixes. + * + * @param array $prefixes Prefixes to add + */ + public function addPrefixes(array $prefixes) + { + foreach ($prefixes as $prefix => $path) { + $this->addPrefix($prefix, $path); + } + } + + /** + * Registers a set of classes + * + * @param string $prefix The classes prefix + * @param array|string $paths The location(s) of the classes + */ + public function addPrefix($prefix, $paths) + { + if (!$prefix) { + foreach ((array) $paths as $path) { + $this->fallbackDirs[] = $path; + } + + return; + } + if (isset($this->prefixes[$prefix])) { + $this->prefixes[$prefix] = array_merge( + $this->prefixes[$prefix], + (array) $paths + ); + } else { + $this->prefixes[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include for class files. + * + * @param Boolean $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 Boolean + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Registers this instance as an autoloader. + * + * @param Boolean $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 Boolean|null True, if loaded + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + require $file; + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|null The path, if found + */ + public function findFile($class) + { + if ('\\' == $class[0]) { + $class = substr($class, 1); + } + + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $classPath = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 0, $pos)) . DIRECTORY_SEPARATOR; + $className = substr($class, $pos + 1); + } else { + // PEAR-like class name + $classPath = null; + $className = $class; + } + + $classPath .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; + + foreach ($this->prefixes as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) { + return $dir . DIRECTORY_SEPARATOR . $classPath; + } + } + } + } + + foreach ($this->fallbackDirs as $dir) { + if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) { + return $dir . DIRECTORY_SEPARATOR . $classPath; + } + } + + if ($this->useIncludePath && $file = stream_resolve_include_path($classPath)) { + return $file; + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/ClassMapGenerator.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/ClassMapGenerator.php new file mode 100644 index 0000000..91ea9af --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/ClassMapGenerator.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\ClassLoader; + +/** + * ClassMapGenerator + * + * @author Gyula Sallai + */ +class ClassMapGenerator +{ + /** + * Generate a class map file + * + * @param array|string $dirs Directories or a single path to search in + * @param string $file The name of the class map file + */ + static public function dump($dirs, $file) + { + $dirs = (array) $dirs; + $maps = array(); + + foreach ($dirs as $dir) { + $maps = array_merge($maps, static::createMap($dir)); + } + + file_put_contents($file, sprintf('isFile()) { + continue; + } + + $path = $file->getRealPath(); + + if (pathinfo($path, PATHINFO_EXTENSION) !== 'php') { + continue; + } + + $classes = self::findClasses($path); + + foreach ($classes as $class) { + $map[$class] = $path; + } + + } + + return $map; + } + + /** + * Extract the classes in the given file + * + * @param string $path The file to check + * + * @return array The found classes + */ + static private function findClasses($path) + { + $contents = file_get_contents($path); + $tokens = token_get_all($contents); + $T_TRAIT = version_compare(PHP_VERSION, '5.4', '<') ? -1 : T_TRAIT; + + $classes = array(); + + $namespace = ''; + for ($i = 0, $max = count($tokens); $i < $max; $i++) { + $token = $tokens[$i]; + + if (is_string($token)) { + continue; + } + + $class = ''; + + switch ($token[0]) { + case T_NAMESPACE: + $namespace = ''; + // If there is a namespace, extract it + while (($t = $tokens[++$i]) && is_array($t)) { + if (in_array($t[0], array(T_STRING, T_NS_SEPARATOR))) { + $namespace .= $t[1]; + } + } + $namespace .= '\\'; + break; + case T_CLASS: + case T_INTERFACE: + case $T_TRAIT: + // Find the classname + while (($t = $tokens[++$i]) && is_array($t)) { + if (T_STRING === $t[0]) { + $class .= $t[1]; + } elseif ($class !== '' && T_WHITESPACE == $t[0]) { + break; + } + } + + $classes[] = ltrim($namespace . $class, '\\'); + break; + default: + break; + } + } + + return $classes; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/DebugClassLoader.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/DebugClassLoader.php new file mode 100644 index 0000000..da7d289 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/DebugClassLoader.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\ClassLoader; + +/** + * Autoloader checking if the class is really defined in the file found. + * + * The DebugClassLoader will wrap all registered autoloaders providing a + * findFile method and will throw an exception if a file is found but does + * not declare the class. + * + * @author Fabien Potencier + * @author Christophe Coevoet + * + * @api + */ +class DebugClassLoader +{ + private $classFinder; + + /** + * Constructor. + * + * @param object $classFinder + * + * @api + */ + public function __construct($classFinder) + { + $this->classFinder = $classFinder; + } + + /** + * Replaces all autoloaders implementing a findFile method by a DebugClassLoader wrapper. + */ + static public function enable() + { + if (!is_array($functions = spl_autoload_functions())) { + return; + } + + foreach ($functions as $function) { + spl_autoload_unregister($function); + } + + foreach ($functions as $function) { + if (is_array($function) && method_exists($function[0], 'findFile')) { + $function = array(new static($function[0]), 'loadClass'); + } + + spl_autoload_register($function); + } + } + + /** + * 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 Boolean|null True, if loaded + */ + public function loadClass($class) + { + if ($file = $this->classFinder->findFile($class)) { + require $file; + + if (!class_exists($class, false) && !interface_exists($class, false) && (!function_exists('trait_exists') || !trait_exists($class, false))) { + throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file)); + } + + return true; + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/DebugUniversalClassLoader.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/DebugUniversalClassLoader.php new file mode 100644 index 0000000..8cc6747 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/DebugUniversalClassLoader.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\ClassLoader; + +/** + * Checks that the class is actually declared in the included file. + * + * @author Fabien Potencier + */ +class DebugUniversalClassLoader extends UniversalClassLoader +{ + /** + * Replaces all regular UniversalClassLoader instances by a DebugUniversalClassLoader ones. + */ + static public function enable() + { + if (!is_array($functions = spl_autoload_functions())) { + return; + } + + foreach ($functions as $function) { + spl_autoload_unregister($function); + } + + foreach ($functions as $function) { + if (is_array($function) && $function[0] instanceof UniversalClassLoader) { + $loader = new static(); + $loader->registerNamespaceFallbacks($function[0]->getNamespaceFallbacks()); + $loader->registerPrefixFallbacks($function[0]->getPrefixFallbacks()); + $loader->registerNamespaces($function[0]->getNamespaces()); + $loader->registerPrefixes($function[0]->getPrefixes()); + $loader->useIncludePath($function[0]->getUseIncludePath()); + + $function[0] = $loader; + } + + spl_autoload_register($function); + } + } + + /** + * {@inheritDoc} + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + require $file; + + if (!class_exists($class, false) && !interface_exists($class, false) && (!function_exists('trait_exists') || !trait_exists($class, false))) { + throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file)); + } + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/LICENSE b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/LICENSE new file mode 100644 index 0000000..cdffe7a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 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/symfony/src/Symfony/Component/ClassLoader/MapClassLoader.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/MapClassLoader.php new file mode 100644 index 0000000..cf17d42 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/MapClassLoader.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\ClassLoader; + +/** + * A class loader that uses a mapping file to look up paths. + * + * @author Fabien Potencier + */ +class MapClassLoader +{ + private $map = array(); + + /** + * Constructor. + * + * @param array $map A map where keys are classes and values the absolute file path + */ + public function __construct(array $map) + { + $this->map = $map; + } + + /** + * Registers this instance as an autoloader. + * + * @param Boolean $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + */ + public function loadClass($class) + { + if ('\\' === $class[0]) { + $class = substr($class, 1); + } + + if (isset($this->map[$class])) { + require $this->map[$class]; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|null The path, if found + */ + public function findFile($class) + { + if ('\\' === $class[0]) { + $class = substr($class, 1); + } + + if (isset($this->map[$class])) { + return $this->map[$class]; + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/README.md b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/README.md new file mode 100644 index 0000000..64dffe9 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/README.md @@ -0,0 +1,72 @@ +ClassLoader Component +===================== + +ClassLoader loads your project classes automatically if they follow some +standard PHP conventions. + +The Universal ClassLoader is able to autoload classes that implement the PSR-0 +standard or the PEAR naming convention. + +First, register the autoloader: + + require_once __DIR__.'/src/Symfony/Component/ClassLoader/UniversalClassLoader.php'; + + use Symfony\Component\ClassLoader\UniversalClassLoader; + + $loader = new UniversalClassLoader(); + $loader->register(); + +Then, register some namespaces with the `registerNamespace()` method: + + $loader->registerNamespace('Symfony', __DIR__.'/src'); + $loader->registerNamespace('Monolog', __DIR__.'/vendor/monolog/src'); + +The `registerNamespace()` method takes a namespace prefix and a path where to +look for the classes as arguments. + +You can also register a sub-namespaces: + + $loader->registerNamespace('Doctrine\\Common', __DIR__.'/vendor/doctrine-common/lib'); + +The order of registration is significant and the first registered namespace +takes precedence over later registered one. + +You can also register more than one path for a given namespace: + + $loader->registerNamespace('Symfony', array(__DIR__.'/src', __DIR__.'/symfony/src')); + +Alternatively, you can use the `registerNamespaces()` method to register more +than one namespace at once: + + $loader->registerNamespaces(array( + 'Symfony' => array(__DIR__.'/src', __DIR__.'/symfony/src'), + 'Doctrine\\Common' => __DIR__.'/vendor/doctrine-common/lib', + 'Doctrine' => __DIR__.'/vendor/doctrine/lib', + 'Monolog' => __DIR__.'/vendor/monolog/src', + )); + +For better performance, you can use the APC based version of the universal +class loader: + + require_once __DIR__.'/src/Symfony/Component/ClassLoader/UniversalClassLoader.php'; + require_once __DIR__.'/src/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php'; + + use Symfony\Component\ClassLoader\ApcUniversalClassLoader; + + $loader = new ApcUniversalClassLoader('apc.prefix.'); + +Furthermore, the component provides tools to aggregate classes into a single +file, which is especially useful to improve performance on servers that do not +provide byte caches. + +Resources +--------- + +You can run the unit tests with the following command: + + phpunit + +If you also want to run the unit tests that depend on other Symfony +Components, install dev dependencies before running PHPUnit: + + php composer.phar install --dev diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/ApcUniversalClassLoaderTest.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/ApcUniversalClassLoaderTest.php new file mode 100644 index 0000000..9a7acfd --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/ApcUniversalClassLoaderTest.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\ClassLoader\Tests; + +use Symfony\Component\ClassLoader\ApcUniversalClassLoader; + +class ApcUniversalClassLoaderTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!extension_loaded('apc')) { + $this->markTestSkipped('The apc extension is not available.'); + } + + if (!(ini_get('apc.enabled') && ini_get('apc.enable_cli'))) { + $this->markTestSkipped('The apc extension is available, but not enabled.'); + } else { + apc_clear_cache('user'); + } + } + + protected function tearDown() + { + if (ini_get('apc.enabled') && ini_get('apc.enable_cli')) { + apc_clear_cache('user'); + } + } + + public function testConstructor() + { + $loader = new ApcUniversalClassLoader('test.prefix.'); + $loader->registerNamespace('Apc\Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + + $this->assertEquals($loader->findFile('\Apc\Namespaced\FooBar'), apc_fetch('test.prefix.\Apc\Namespaced\FooBar'), '__construct() takes a prefix as its first argument'); + } + + /** + * @dataProvider getLoadClassTests + */ + public function testLoadClass($className, $testClassName, $message) + { + $loader = new ApcUniversalClassLoader('test.prefix.'); + $loader->registerNamespace('Apc\Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $loader->registerPrefix('Apc_Pearlike_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $loader->loadClass($testClassName); + $this->assertTrue(class_exists($className), $message); + } + + public function getLoadClassTests() + { + return array( + array('\\Apc\\Namespaced\\Foo', '\\Apc\\Namespaced\\Foo', '->loadClass() loads Apc\Namespaced\Foo class'), + array('Apc_Pearlike_Foo', 'Apc_Pearlike_Foo', '->loadClass() loads Apc_Pearlike_Foo class'), + array('\\Apc\\Namespaced\\Bar', '\\Apc\\Namespaced\\Bar', '->loadClass() loads Apc\Namespaced\Bar class with a leading slash'), + array('Apc_Pearlike_Bar', '\\Apc_Pearlike_Bar', '->loadClass() loads Apc_Pearlike_Bar class with a leading slash'), + ); + } + + /** + * @dataProvider getLoadClassFromFallbackTests + */ + public function testLoadClassFromFallback($className, $testClassName, $message) + { + $loader = new ApcUniversalClassLoader('test.prefix.fallback'); + $loader->registerNamespace('Apc\Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $loader->registerPrefix('Apc_Pearlike_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $loader->registerNamespaceFallbacks(array(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/fallback')); + $loader->registerPrefixFallbacks(array(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/fallback')); + $loader->loadClass($testClassName); + $this->assertTrue(class_exists($className), $message); + } + + public function getLoadClassFromFallbackTests() + { + return array( + array('\\Apc\\Namespaced\\Baz', '\\Apc\\Namespaced\\Baz', '->loadClass() loads Apc\Namespaced\Baz class'), + array('Apc_Pearlike_Baz', 'Apc_Pearlike_Baz', '->loadClass() loads Apc_Pearlike_Baz class'), + array('\\Apc\\Namespaced\\FooBar', '\\Apc\\Namespaced\\FooBar', '->loadClass() loads Apc\Namespaced\Baz class from fallback dir'), + array('Apc_Pearlike_FooBar', 'Apc_Pearlike_FooBar', '->loadClass() loads Apc_Pearlike_Baz class from fallback dir'), + ); + } + + /** + * @dataProvider getLoadClassNamespaceCollisionTests + */ + public function testLoadClassNamespaceCollision($namespaces, $className, $message) + { + $loader = new ApcUniversalClassLoader('test.prefix.collision.'); + $loader->registerNamespaces($namespaces); + + $loader->loadClass($className); + + $this->assertTrue(class_exists($className), $message); + } + + public function getLoadClassNamespaceCollisionTests() + { + return array( + array( + array( + 'Apc\\NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/alpha', + 'Apc\\NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/beta', + ), + '\Apc\NamespaceCollision\A\Foo', + '->loadClass() loads NamespaceCollision\A\Foo from alpha.', + ), + array( + array( + 'Apc\\NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/beta', + 'Apc\\NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/alpha', + ), + '\Apc\NamespaceCollision\A\Bar', + '->loadClass() loads NamespaceCollision\A\Bar from alpha.', + ), + array( + array( + 'Apc\\NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/alpha', + 'Apc\\NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/beta', + ), + '\Apc\NamespaceCollision\A\B\Foo', + '->loadClass() loads NamespaceCollision\A\B\Foo from beta.', + ), + array( + array( + 'Apc\\NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/beta', + 'Apc\\NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/alpha', + ), + '\Apc\NamespaceCollision\A\B\Bar', + '->loadClass() loads NamespaceCollision\A\B\Bar from beta.', + ), + ); + } + + /** + * @dataProvider getLoadClassPrefixCollisionTests + */ + public function testLoadClassPrefixCollision($prefixes, $className, $message) + { + $loader = new ApcUniversalClassLoader('test.prefix.collision.'); + $loader->registerPrefixes($prefixes); + + $loader->loadClass($className); + $this->assertTrue(class_exists($className), $message); + } + + public function getLoadClassPrefixCollisionTests() + { + return array( + array( + array( + 'ApcPrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/alpha/Apc', + 'ApcPrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/beta/Apc', + ), + 'ApcPrefixCollision_A_Foo', + '->loadClass() loads ApcPrefixCollision_A_Foo from alpha.', + ), + array( + array( + 'ApcPrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/beta/Apc', + 'ApcPrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/alpha/Apc', + ), + 'ApcPrefixCollision_A_Bar', + '->loadClass() loads ApcPrefixCollision_A_Bar from alpha.', + ), + array( + array( + 'ApcPrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/alpha/Apc', + 'ApcPrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/beta/Apc', + ), + 'ApcPrefixCollision_A_B_Foo', + '->loadClass() loads ApcPrefixCollision_A_B_Foo from beta.', + ), + array( + array( + 'ApcPrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/beta/Apc', + 'ApcPrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/alpha/Apc', + ), + 'ApcPrefixCollision_A_B_Bar', + '->loadClass() loads ApcPrefixCollision_A_B_Bar from beta.', + ), + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/ClassCollectionLoaderTest.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/ClassCollectionLoaderTest.php new file mode 100644 index 0000000..5f4db1f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/ClassCollectionLoaderTest.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\ClassLoader\Tests; + +use Symfony\Component\ClassLoader\ClassCollectionLoader; + +class ClassCollectionLoaderTest extends \PHPUnit_Framework_TestCase +{ + public function testFixNamespaceDeclarations() + { + $source = <<assertEquals($expected, ClassCollectionLoader::fixNamespaceDeclarations($source)); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testUnableToLoadClassException() + { + ClassCollectionLoader::load(array('SomeNotExistingClass'), '', 'foo', false); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/ClassLoaderTest.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/ClassLoaderTest.php new file mode 100644 index 0000000..c9fe382 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/ClassLoaderTest.php @@ -0,0 +1,163 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ClassLoader\Tests; + +use Symfony\Component\ClassLoader\ClassLoader; + +class ClassLoaderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getLoadClassTests + */ + public function testLoadClass($className, $testClassName, $message) + { + $loader = new ClassLoader(); + $loader->addPrefix('Namespaced2\\', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $loader->addPrefix('Pearlike2_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $loader->loadClass($testClassName); + $this->assertTrue(class_exists($className), $message); + } + + public function getLoadClassTests() + { + return array( + array('\\Namespaced2\\Foo', 'Namespaced2\\Foo', '->loadClass() loads Namespaced2\Foo class'), + array('\\Pearlike2_Foo', 'Pearlike2_Foo', '->loadClass() loads Pearlike2_Foo class'), + array('\\Namespaced2\\Bar', '\\Namespaced2\\Bar', '->loadClass() loads Namespaced2\Bar class with a leading slash'), + array('\\Pearlike2_Bar', '\\Pearlike2_Bar', '->loadClass() loads Pearlike2_Bar class with a leading slash'), + ); + } + + public function testUseIncludePath() + { + $loader = new ClassLoader(); + $this->assertFalse($loader->getUseIncludePath()); + + $this->assertNull($loader->findFile('Foo')); + + $includePath = get_include_path(); + + $loader->setUseIncludePath(true); + $this->assertTrue($loader->getUseIncludePath()); + + set_include_path(__DIR__.'/Fixtures/includepath' . PATH_SEPARATOR . $includePath); + + $this->assertEquals(__DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'includepath'.DIRECTORY_SEPARATOR.'Foo.php', $loader->findFile('Foo')); + + set_include_path($includePath); + } + + /** + * @dataProvider getLoadClassFromFallbackTests + */ + public function testLoadClassFromFallback($className, $testClassName, $message) + { + $loader = new ClassLoader(); + $loader->addPrefix('Namespaced2\\', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $loader->addPrefix('Pearlike2_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $loader->addPrefix('', array(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/fallback')); + $loader->loadClass($testClassName); + $this->assertTrue(class_exists($className), $message); + } + + public function getLoadClassFromFallbackTests() + { + return array( + array('\\Namespaced2\\Baz', 'Namespaced2\\Baz', '->loadClass() loads Namespaced2\Baz class'), + array('\\Pearlike2_Baz', 'Pearlike2_Baz', '->loadClass() loads Pearlike2_Baz class'), + array('\\Namespaced2\\FooBar', 'Namespaced2\\FooBar', '->loadClass() loads Namespaced2\Baz class from fallback dir'), + array('\\Pearlike2_FooBar', 'Pearlike2_FooBar', '->loadClass() loads Pearlike2_Baz class from fallback dir'), + ); + } + + /** + * @dataProvider getLoadClassNamespaceCollisionTests + */ + public function testLoadClassNamespaceCollision($namespaces, $className, $message) + { + $loader = new ClassLoader(); + $loader->addPrefixes($namespaces); + + $loader->loadClass($className); + $this->assertTrue(class_exists($className), $message); + } + + public function getLoadClassNamespaceCollisionTests() + { + return array( + array( + array( + 'NamespaceCollision\\C' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + 'NamespaceCollision\\C\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + ), + 'NamespaceCollision\C\Foo', + '->loadClass() loads NamespaceCollision\C\Foo from alpha.', + ), + array( + array( + 'NamespaceCollision\\C\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + 'NamespaceCollision\\C' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + ), + 'NamespaceCollision\C\Bar', + '->loadClass() loads NamespaceCollision\C\Bar from alpha.', + ), + array( + array( + 'NamespaceCollision\\C' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + 'NamespaceCollision\\C\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + ), + 'NamespaceCollision\C\B\Foo', + '->loadClass() loads NamespaceCollision\C\B\Foo from beta.', + ), + array( + array( + 'NamespaceCollision\\C\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + 'NamespaceCollision\\C' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + ), + 'NamespaceCollision\C\B\Bar', + '->loadClass() loads NamespaceCollision\C\B\Bar from beta.', + ), + array( + array( + 'PrefixCollision_C_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + 'PrefixCollision_C_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + ), + 'PrefixCollision_C_Foo', + '->loadClass() loads PrefixCollision_C_Foo from alpha.', + ), + array( + array( + 'PrefixCollision_C_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + 'PrefixCollision_C_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + ), + 'PrefixCollision_C_Bar', + '->loadClass() loads PrefixCollision_C_Bar from alpha.', + ), + array( + array( + 'PrefixCollision_C_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + 'PrefixCollision_C_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + ), + 'PrefixCollision_C_B_Foo', + '->loadClass() loads PrefixCollision_C_B_Foo from beta.', + ), + array( + array( + 'PrefixCollision_C_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + 'PrefixCollision_C_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + ), + 'PrefixCollision_C_B_Bar', + '->loadClass() loads PrefixCollision_C_B_Bar from beta.', + ), + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/ClassMapGeneratorTest.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/ClassMapGeneratorTest.php new file mode 100644 index 0000000..6cebd38 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/ClassMapGeneratorTest.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\ClassLoader\Tests; + +use Symfony\Component\ClassLoader\ClassMapGenerator; + +class ClassMapGeneratorTest extends \PHPUnit_Framework_TestCase +{ + + /** + * @dataProvider getTestCreateMapTests + */ + public function testCreateMap($directory, $expected) + { + $this->assertEqualsNormalized($expected, ClassMapGenerator::createMap($directory)); + } + + public function getTestCreateMapTests() + { + $data = array( + array(__DIR__.'/Fixtures/Namespaced', array( + 'Namespaced\\Bar' => realpath(__DIR__).'/Fixtures/Namespaced/Bar.php', + 'Namespaced\\Foo' => realpath(__DIR__).'/Fixtures/Namespaced/Foo.php', + 'Namespaced\\Baz' => realpath(__DIR__).'/Fixtures/Namespaced/Baz.php', + ) + ), + array(__DIR__.'/Fixtures/beta/NamespaceCollision', array( + 'NamespaceCollision\\A\\B\\Bar' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/A/B/Bar.php', + 'NamespaceCollision\\A\\B\\Foo' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/A/B/Foo.php', + 'NamespaceCollision\\C\\B\\Bar' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/C/B/Bar.php', + 'NamespaceCollision\\C\\B\\Foo' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/C/B/Foo.php', + )), + array(__DIR__.'/Fixtures/Pearlike', array( + 'Pearlike_Foo' => realpath(__DIR__).'/Fixtures/Pearlike/Foo.php', + 'Pearlike_Bar' => realpath(__DIR__).'/Fixtures/Pearlike/Bar.php', + 'Pearlike_Baz' => realpath(__DIR__).'/Fixtures/Pearlike/Baz.php', + )), + array(__DIR__.'/Fixtures/classmap', array( + 'Foo\\Bar\\A' => realpath(__DIR__).'/Fixtures/classmap/sameNsMultipleClasses.php', + 'Foo\\Bar\\B' => realpath(__DIR__).'/Fixtures/classmap/sameNsMultipleClasses.php', + 'A' => realpath(__DIR__).'/Fixtures/classmap/multipleNs.php', + 'Alpha\\A' => realpath(__DIR__).'/Fixtures/classmap/multipleNs.php', + 'Alpha\\B' => realpath(__DIR__).'/Fixtures/classmap/multipleNs.php', + 'Beta\\A' => realpath(__DIR__).'/Fixtures/classmap/multipleNs.php', + 'Beta\\B' => realpath(__DIR__).'/Fixtures/classmap/multipleNs.php', + 'ClassMap\\SomeInterface' => realpath(__DIR__).'/Fixtures/classmap/SomeInterface.php', + 'ClassMap\\SomeParent' => realpath(__DIR__).'/Fixtures/classmap/SomeParent.php', + 'ClassMap\\SomeClass' => realpath(__DIR__).'/Fixtures/classmap/SomeClass.php', + )), + ); + + if (version_compare(PHP_VERSION, '5.4', '>=')) { + $data[] = array(__DIR__.'/Fixtures/php5.4', array( + 'TFoo' => __DIR__.'/Fixtures/php5.4/traits.php', + 'CFoo' => __DIR__.'/Fixtures/php5.4/traits.php', + 'Foo\\TBar' => __DIR__.'/Fixtures/php5.4/traits.php', + 'Foo\\IBar' => __DIR__.'/Fixtures/php5.4/traits.php', + 'Foo\\TFooBar' => __DIR__.'/Fixtures/php5.4/traits.php', + 'Foo\\CBar' => __DIR__.'/Fixtures/php5.4/traits.php', + )); + } + + return $data; + } + + public function testCreateMapFinderSupport() + { + if (!class_exists('Symfony\\Component\\Finder\\Finder')) { + $this->markTestSkipped('Finder component is not available'); + } + + $finder = new \Symfony\Component\Finder\Finder(); + $finder->files()->in(__DIR__ . '/Fixtures/beta/NamespaceCollision'); + + $this->assertEqualsNormalized(array( + 'NamespaceCollision\\A\\B\\Bar' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/A/B/Bar.php', + 'NamespaceCollision\\A\\B\\Foo' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/A/B/Foo.php', + 'NamespaceCollision\\C\\B\\Bar' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/C/B/Bar.php', + 'NamespaceCollision\\C\\B\\Foo' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/C/B/Foo.php', + ), ClassMapGenerator::createMap($finder)); + } + + protected function assertEqualsNormalized($expected, $actual, $message = null) + { + foreach ($expected as $ns => $path) { + $expected[$ns] = strtr($path, '\\', '/'); + } + foreach ($actual as $ns => $path) { + $actual[$ns] = strtr($path, '\\', '/'); + } + $this->assertEquals($expected, $actual, $message); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Namespaced/Bar.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Namespaced/Bar.php new file mode 100644 index 0000000..4259f14 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Namespaced/Bar.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Apc\Namespaced; + +class Bar +{ + public static $loaded = true; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Namespaced/Baz.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Namespaced/Baz.php new file mode 100644 index 0000000..3ddb595 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Namespaced/Baz.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Apc\Namespaced; + +class Baz +{ + public static $loaded = true; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Namespaced/Foo.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Namespaced/Foo.php new file mode 100644 index 0000000..cf0a4b7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Namespaced/Foo.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Apc\Namespaced; + +class Foo +{ + public static $loaded = true; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Namespaced/FooBar.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Namespaced/FooBar.php new file mode 100644 index 0000000..bbbc815 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Namespaced/FooBar.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Apc\Namespaced; + +class FooBar +{ + public static $loaded = true; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Pearlike/Bar.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Pearlike/Bar.php new file mode 100644 index 0000000..e774cb9 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/Pearlike/Bar.php @@ -0,0 +1,6 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Apc\NamespaceCollision\A; + +class Bar +{ + public static $loaded = true; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/alpha/Apc/NamespaceCollision/A/Foo.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/alpha/Apc/NamespaceCollision/A/Foo.php new file mode 100644 index 0000000..184a1b1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/alpha/Apc/NamespaceCollision/A/Foo.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Apc\NamespaceCollision\A; + +class Foo +{ + public static $loaded = true; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/beta/Apc/ApcPrefixCollision/A/B/Bar.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/beta/Apc/ApcPrefixCollision/A/B/Bar.php new file mode 100644 index 0000000..3892f70 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/beta/Apc/ApcPrefixCollision/A/B/Bar.php @@ -0,0 +1,6 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Apc\NamespaceCollision\A\B; + +class Bar +{ + public static $loaded = true; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/beta/Apc/NamespaceCollision/A/B/Foo.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/beta/Apc/NamespaceCollision/A/B/Foo.php new file mode 100644 index 0000000..450eeb5 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/beta/Apc/NamespaceCollision/A/B/Foo.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Apc\NamespaceCollision\A\B; + +class Foo +{ + public static $loaded = true; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/fallback/Apc/Pearlike/FooBar.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/fallback/Apc/Pearlike/FooBar.php new file mode 100644 index 0000000..96f2f76 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Apc/fallback/Apc/Pearlike/FooBar.php @@ -0,0 +1,6 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Apc\Namespaced; + +class FooBar +{ + public static $loaded = true; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced/Bar.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced/Bar.php new file mode 100644 index 0000000..02b589d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced/Bar.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Namespaced; + +class Bar +{ + public static $loaded = true; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced/Baz.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced/Baz.php new file mode 100644 index 0000000..0b0bbd0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced/Baz.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Namespaced; + +class Baz +{ + public static $loaded = true; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced/Foo.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced/Foo.php new file mode 100644 index 0000000..df5e1f4 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced/Foo.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Namespaced; + +class Foo +{ + public static $loaded = true; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced2/Bar.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced2/Bar.php new file mode 100644 index 0000000..7bf42ab --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced2/Bar.php @@ -0,0 +1,8 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace NamespaceCollision\A; + +class Bar +{ + public static $loaded = true; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/alpha/NamespaceCollision/A/Foo.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/alpha/NamespaceCollision/A/Foo.php new file mode 100644 index 0000000..aee6a08 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/alpha/NamespaceCollision/A/Foo.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace NamespaceCollision\A; + +class Foo +{ + public static $loaded = true; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/alpha/NamespaceCollision/C/Bar.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/alpha/NamespaceCollision/C/Bar.php new file mode 100644 index 0000000..c1b8dd6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/alpha/NamespaceCollision/C/Bar.php @@ -0,0 +1,8 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace NamespaceCollision\A\B; + +class Bar +{ + public static $loaded = true; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/beta/NamespaceCollision/A/B/Foo.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/beta/NamespaceCollision/A/B/Foo.php new file mode 100644 index 0000000..f5f2d72 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/beta/NamespaceCollision/A/B/Foo.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace NamespaceCollision\A\B; + +class Foo +{ + public static $loaded = true; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/beta/NamespaceCollision/C/B/Bar.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/beta/NamespaceCollision/C/B/Bar.php new file mode 100644 index 0000000..4bb03dc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/beta/NamespaceCollision/C/B/Bar.php @@ -0,0 +1,8 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace ClassMap; + +class SomeClass extends SomeParent implements SomeInterface +{ + +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/classmap/SomeInterface.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/classmap/SomeInterface.php new file mode 100644 index 0000000..09d7a8f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/classmap/SomeInterface.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace ClassMap; + +interface SomeInterface +{ + +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/classmap/SomeParent.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/classmap/SomeParent.php new file mode 100644 index 0000000..5a859a9 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/classmap/SomeParent.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace ClassMap; + +abstract class SomeParent +{ + +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/classmap/multipleNs.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/classmap/multipleNs.php new file mode 100644 index 0000000..d19e07f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/classmap/multipleNs.php @@ -0,0 +1,14 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Foo\Bar; + +class A {} +class B {} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/fallback/Namespaced/FooBar.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/fallback/Namespaced/FooBar.php new file mode 100644 index 0000000..0fd29ef --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/fallback/Namespaced/FooBar.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Namespaced; + +class FooBar +{ + public static $loaded = true; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/fallback/Namespaced2/FooBar.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/fallback/Namespaced2/FooBar.php new file mode 100644 index 0000000..1036d43 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/Fixtures/fallback/Namespaced2/FooBar.php @@ -0,0 +1,8 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ClassLoader\Tests; + +use Symfony\Component\ClassLoader\UniversalClassLoader; + +class UniversalClassLoaderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getLoadClassTests + */ + public function testLoadClass($className, $testClassName, $message) + { + $loader = new UniversalClassLoader(); + $loader->registerNamespace('Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $loader->registerPrefix('Pearlike_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $loader->loadClass($testClassName); + $this->assertTrue(class_exists($className), $message); + } + + public function getLoadClassTests() + { + return array( + array('\\Namespaced\\Foo', 'Namespaced\\Foo', '->loadClass() loads Namespaced\Foo class'), + array('\\Pearlike_Foo', 'Pearlike_Foo', '->loadClass() loads Pearlike_Foo class'), + array('\\Namespaced\\Bar', '\\Namespaced\\Bar', '->loadClass() loads Namespaced\Bar class with a leading slash'), + array('\\Pearlike_Bar', '\\Pearlike_Bar', '->loadClass() loads Pearlike_Bar class with a leading slash'), + ); + } + + public function testUseIncludePath() + { + $loader = new UniversalClassLoader(); + $this->assertFalse($loader->getUseIncludePath()); + + $this->assertNull($loader->findFile('Foo')); + + $includePath = get_include_path(); + + $loader->useIncludePath(true); + $this->assertTrue($loader->getUseIncludePath()); + + set_include_path(__DIR__.'/Fixtures/includepath' . PATH_SEPARATOR . $includePath); + + $this->assertEquals(__DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'includepath'.DIRECTORY_SEPARATOR.'Foo.php', $loader->findFile('Foo')); + + set_include_path($includePath); + } + + /** + * @dataProvider getLoadClassFromFallbackTests + */ + public function testLoadClassFromFallback($className, $testClassName, $message) + { + $loader = new UniversalClassLoader(); + $loader->registerNamespace('Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $loader->registerPrefix('Pearlike_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $loader->registerNamespaceFallbacks(array(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/fallback')); + $loader->registerPrefixFallbacks(array(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/fallback')); + $loader->loadClass($testClassName); + $this->assertTrue(class_exists($className), $message); + } + + public function getLoadClassFromFallbackTests() + { + return array( + array('\\Namespaced\\Baz', 'Namespaced\\Baz', '->loadClass() loads Namespaced\Baz class'), + array('\\Pearlike_Baz', 'Pearlike_Baz', '->loadClass() loads Pearlike_Baz class'), + array('\\Namespaced\\FooBar', 'Namespaced\\FooBar', '->loadClass() loads Namespaced\Baz class from fallback dir'), + array('\\Pearlike_FooBar', 'Pearlike_FooBar', '->loadClass() loads Pearlike_Baz class from fallback dir'), + ); + } + + public function testRegisterPrefixFallback() + { + $loader = new UniversalClassLoader(); + $loader->registerPrefixFallback(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/fallback'); + $this->assertEquals(array(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/fallback'), $loader->getPrefixFallbacks()); + } + + public function testRegisterNamespaceFallback() + { + $loader = new UniversalClassLoader(); + $loader->registerNamespaceFallback(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/Namespaced/fallback'); + $this->assertEquals(array(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/Namespaced/fallback'), $loader->getNamespaceFallbacks()); + } + + /** + * @dataProvider getLoadClassNamespaceCollisionTests + */ + public function testLoadClassNamespaceCollision($namespaces, $className, $message) + { + $loader = new UniversalClassLoader(); + $loader->registerNamespaces($namespaces); + + $loader->loadClass($className); + $this->assertTrue(class_exists($className), $message); + } + + public function getLoadClassNamespaceCollisionTests() + { + return array( + array( + array( + 'NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + 'NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + ), + 'NamespaceCollision\A\Foo', + '->loadClass() loads NamespaceCollision\A\Foo from alpha.', + ), + array( + array( + 'NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + 'NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + ), + 'NamespaceCollision\A\Bar', + '->loadClass() loads NamespaceCollision\A\Bar from alpha.', + ), + array( + array( + 'NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + 'NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + ), + 'NamespaceCollision\A\B\Foo', + '->loadClass() loads NamespaceCollision\A\B\Foo from beta.', + ), + array( + array( + 'NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + 'NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + ), + 'NamespaceCollision\A\B\Bar', + '->loadClass() loads NamespaceCollision\A\B\Bar from beta.', + ), + ); + } + + /** + * @dataProvider getLoadClassPrefixCollisionTests + */ + public function testLoadClassPrefixCollision($prefixes, $className, $message) + { + $loader = new UniversalClassLoader(); + $loader->registerPrefixes($prefixes); + + $loader->loadClass($className); + $this->assertTrue(class_exists($className), $message); + } + + public function getLoadClassPrefixCollisionTests() + { + return array( + array( + array( + 'PrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + 'PrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + ), + 'PrefixCollision_A_Foo', + '->loadClass() loads PrefixCollision_A_Foo from alpha.', + ), + array( + array( + 'PrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + 'PrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + ), + 'PrefixCollision_A_Bar', + '->loadClass() loads PrefixCollision_A_Bar from alpha.', + ), + array( + array( + 'PrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + 'PrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + ), + 'PrefixCollision_A_B_Foo', + '->loadClass() loads PrefixCollision_A_B_Foo from beta.', + ), + array( + array( + 'PrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + 'PrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + ), + 'PrefixCollision_A_B_Bar', + '->loadClass() loads PrefixCollision_A_B_Bar from beta.', + ), + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/bootstrap.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/bootstrap.php new file mode 100644 index 0000000..54dac3f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/Tests/bootstrap.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +spl_autoload_register(function ($class) { + if (0 === strpos(ltrim($class, '/'), 'Symfony\Component\ClassLoader')) { + if (file_exists($file = __DIR__.'/../'.substr(str_replace('\\', '/', $class), strlen('Symfony\Component\ClassLoader')).'.php')) { + require_once $file; + } + } +}); + +if (file_exists($loader = __DIR__.'/../vendor/autoload.php')) { + require_once $loader; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/UniversalClassLoader.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/UniversalClassLoader.php new file mode 100644 index 0000000..b6128ad --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/UniversalClassLoader.php @@ -0,0 +1,319 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ClassLoader; + +/** + * UniversalClassLoader implements a "universal" autoloader for PHP 5.3. + * + * It is able to load classes that use either: + * + * * The technical interoperability standards for PHP 5.3 namespaces and + * class names (https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md); + * + * * The PEAR naming convention for classes (http://pear.php.net/). + * + * Classes from a sub-namespace or a sub-hierarchy of PEAR classes can be + * looked for in a list of locations to ease the vendoring of a sub-set of + * classes for large projects. + * + * Example usage: + * + * $loader = new UniversalClassLoader(); + * + * // register classes with namespaces + * $loader->registerNamespaces(array( + * 'Symfony\Component' => __DIR__.'/component', + * 'Symfony' => __DIR__.'/framework', + * 'Sensio' => array(__DIR__.'/src', __DIR__.'/vendor'), + * )); + * + * // register a library using the PEAR naming convention + * $loader->registerPrefixes(array( + * 'Swift_' => __DIR__.'/Swift', + * )); + * + * + * // to enable searching the include path (e.g. for PEAR packages) + * $loader->useIncludePath(true); + * + * // activate the autoloader + * $loader->register(); + * + * 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. + * + * @author Fabien Potencier + * + * @api + */ +class UniversalClassLoader +{ + private $namespaces = array(); + private $prefixes = array(); + private $namespaceFallbacks = array(); + private $prefixFallbacks = array(); + private $useIncludePath = false; + + /** + * Turns on searching the include for class files. Allows easy loading + * of installed PEAR packages + * + * @param Boolean $useIncludePath + */ + public function useIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return Boolean + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Gets the configured namespaces. + * + * @return array A hash with namespaces as keys and directories as values + */ + public function getNamespaces() + { + return $this->namespaces; + } + + /** + * Gets the configured class prefixes. + * + * @return array A hash with class prefixes as keys and directories as values + */ + public function getPrefixes() + { + return $this->prefixes; + } + + /** + * Gets the directory(ies) to use as a fallback for namespaces. + * + * @return array An array of directories + */ + public function getNamespaceFallbacks() + { + return $this->namespaceFallbacks; + } + + /** + * Gets the directory(ies) to use as a fallback for class prefixes. + * + * @return array An array of directories + */ + public function getPrefixFallbacks() + { + return $this->prefixFallbacks; + } + + /** + * Registers the directory to use as a fallback for namespaces. + * + * @param array $dirs An array of directories + * + * @api + */ + public function registerNamespaceFallbacks(array $dirs) + { + $this->namespaceFallbacks = $dirs; + } + + /** + * Registers a directory to use as a fallback for namespaces. + * + * @param string $dir A directory + */ + public function registerNamespaceFallback($dir) + { + $this->namespaceFallbacks[] = $dir; + } + + /** + * Registers directories to use as a fallback for class prefixes. + * + * @param array $dirs An array of directories + * + * @api + */ + public function registerPrefixFallbacks(array $dirs) + { + $this->prefixFallbacks = $dirs; + } + + /** + * Registers a directory to use as a fallback for class prefixes. + * + * @param string $dir A directory + */ + public function registerPrefixFallback($dir) + { + $this->prefixFallbacks[] = $dir; + } + + /** + * Registers an array of namespaces + * + * @param array $namespaces An array of namespaces (namespaces as keys and locations as values) + * + * @api + */ + public function registerNamespaces(array $namespaces) + { + foreach ($namespaces as $namespace => $locations) { + $this->namespaces[$namespace] = (array) $locations; + } + } + + /** + * Registers a namespace. + * + * @param string $namespace The namespace + * @param array|string $paths The location(s) of the namespace + * + * @api + */ + public function registerNamespace($namespace, $paths) + { + $this->namespaces[$namespace] = (array) $paths; + } + + /** + * Registers an array of classes using the PEAR naming convention. + * + * @param array $classes An array of classes (prefixes as keys and locations as values) + * + * @api + */ + public function registerPrefixes(array $classes) + { + foreach ($classes as $prefix => $locations) { + $this->prefixes[$prefix] = (array) $locations; + } + } + + /** + * Registers a set of classes using the PEAR naming convention. + * + * @param string $prefix The classes prefix + * @param array|string $paths The location(s) of the classes + * + * @api + */ + public function registerPrefix($prefix, $paths) + { + $this->prefixes[$prefix] = (array) $paths; + } + + /** + * Registers this instance as an autoloader. + * + * @param Boolean $prepend Whether to prepend the autoloader or not + * + * @api + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + require $file; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|null The path, if found + */ + public function findFile($class) + { + if ('\\' == $class[0]) { + $class = substr($class, 1); + } + + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $namespace = substr($class, 0, $pos); + $className = substr($class, $pos + 1); + $normalizedClass = str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $className).'.php'; + foreach ($this->namespaces as $ns => $dirs) { + if (0 !== strpos($namespace, $ns)) { + continue; + } + + foreach ($dirs as $dir) { + $file = $dir.DIRECTORY_SEPARATOR.$normalizedClass; + if (is_file($file)) { + return $file; + } + } + } + + foreach ($this->namespaceFallbacks as $dir) { + $file = $dir.DIRECTORY_SEPARATOR.$normalizedClass; + if (is_file($file)) { + return $file; + } + } + + } else { + // PEAR-like class name + $normalizedClass = str_replace('_', DIRECTORY_SEPARATOR, $class).'.php'; + foreach ($this->prefixes as $prefix => $dirs) { + if (0 !== strpos($class, $prefix)) { + continue; + } + + foreach ($dirs as $dir) { + $file = $dir.DIRECTORY_SEPARATOR.$normalizedClass; + if (is_file($file)) { + return $file; + } + } + } + + foreach ($this->prefixFallbacks as $dir) { + $file = $dir.DIRECTORY_SEPARATOR.$normalizedClass; + if (is_file($file)) { + return $file; + } + } + } + + if ($this->useIncludePath && $file = stream_resolve_include_path($normalizedClass)) { + return $file; + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/XcacheClassLoader.php b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/XcacheClassLoader.php new file mode 100644 index 0000000..2decbce --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/XcacheClassLoader.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\ClassLoader; + +/** + * XcacheClassLoader implements a wrapping autoloader cached in Xcache for PHP 5.3. + * + * It expects an object implementing a findFile method to find the file. This + * allows using it as a wrapper around the other loaders of the component (the + * ClassLoader and the UniversalClassLoader for instance) but also around any + * other autoloader following this convention (the Composer one for instance) + * + * $loader = new ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * $cachedLoader = new XcacheClassLoader('my_prefix', $loader); + * + * // activate the cached autoloader + * $cachedLoader->register(); + * + * // eventually deactivate the non-cached loader if it was registered previously + * // to be sure to use the cached one. + * $loader->unregister(); + * + * @author Fabien Potencier + * @author Kris Wallsmith + * @author Kim Hemsø Rasmussen + * + * @api + */ +class XcacheClassLoader +{ + private $prefix; + private $classFinder; + + /** + * Constructor. + * + * @param string $prefix A prefix to create a namespace in Xcache + * @param object $classFinder An object that implements findFile() method. + * + * @api + */ + public function __construct($prefix, $classFinder) + { + if (!extension_loaded('Xcache')) { + throw new \RuntimeException('Unable to use XcacheClassLoader as Xcache is not enabled.'); + } + + if (!method_exists($classFinder, 'findFile')) { + throw new \InvalidArgumentException('The class finder must implement a "findFile" method.'); + } + + $this->prefix = $prefix; + $this->classFinder = $classFinder; + } + + /** + * Registers this instance as an autoloader. + * + * @param Boolean $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 Boolean|null True, if loaded + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + require $file; + + return true; + } + } + + /** + * Finds a file by class name while caching lookups to Xcache. + * + * @param string $class A class name to resolve to file + * + * @return string|null + */ + public function findFile($class) + { + if (xcache_isset($this->prefix.$class)) { + $file = xcache_get($this->prefix.$class); + } else { + xcache_set($this->prefix.$class, $file = $this->classFinder->findFile($class)); + } + + return $file; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/composer.json b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/composer.json new file mode 100644 index 0000000..a4b32ec --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/composer.json @@ -0,0 +1,33 @@ +{ + "name": "symfony/class-loader", + "type": "library", + "description": "Symfony ClassLoader 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/finder": "2.1.*" + }, + "autoload": { + "psr-0": { "Symfony\\Component\\ClassLoader": "" } + }, + "target-dir": "Symfony/Component/ClassLoader", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/phpunit.xml.dist b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/phpunit.xml.dist new file mode 100644 index 0000000..ae7e2ad --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/ClassLoader/phpunit.xml.dist @@ -0,0 +1,30 @@ + + + + + + ./Tests/ + + + + + + ./ + + ./Resources + ./Tests + ./vendor + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/CHANGELOG.md b/vendor/symfony/symfony/src/Symfony/Component/Config/CHANGELOG.md new file mode 100644 index 0000000..27dd931 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/CHANGELOG.md @@ -0,0 +1,10 @@ +CHANGELOG +========= + +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/symfony/src/Symfony/Component/Config/ConfigCache.php b/vendor/symfony/symfony/src/Symfony/Component/Config/ConfigCache.php new file mode 100644 index 0000000..1a96bdd --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/ConfigCache.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; + +/** + * 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 Boolean $debug Whether debugging is enabled or not + */ + public function __construct($file, $debug) + { + $this->file = $file; + $this->debug = (Boolean) $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 Boolean 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->file.'.meta'; + 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 array $metadata An array of ResourceInterface instances + * + * @throws \RuntimeException When cache file can't be wrote + */ + public function write($content, array $metadata = null) + { + $dir = dirname($this->file); + if (!is_dir($dir)) { + if (false === @mkdir($dir, 0777, true)) { + throw new \RuntimeException(sprintf('Unable to create the %s directory', $dir)); + } + } elseif (!is_writable($dir)) { + throw new \RuntimeException(sprintf('Unable to write in the %s directory', $dir)); + } + + $tmpFile = tempnam(dirname($this->file), basename($this->file)); + if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $this->file)) { + @chmod($this->file, 0666 & ~umask()); + } else { + throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $this->file)); + } + + if (null !== $metadata && true === $this->debug) { + $file = $this->file.'.meta'; + $tmpFile = tempnam(dirname($file), basename($file)); + if (false !== @file_put_contents($tmpFile, serialize($metadata)) && @rename($tmpFile, $file)) { + @chmod($file, 0666 & ~umask()); + } + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/ArrayNode.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/ArrayNode.php new file mode 100644 index 0000000..2c422c8 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/ArrayNode.php @@ -0,0 +1,363 @@ + + * + * 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; + protected $children; + protected $allowFalse; + protected $allowNewKeys; + protected $addIfNotSet; + protected $performDeepMerging; + protected $ignoreExtraKeys; + + /** + * Constructor. + * + * @param string $name The Node's name + * @param NodeInterface $parent The node parent + */ + public function __construct($name, NodeInterface $parent = null) + { + parent::__construct($name, $parent); + + $this->children = array(); + $this->xmlRemappings = array(); + $this->removeKeyAttribute = true; + $this->allowFalse = false; + $this->addIfNotSet = false; + $this->allowNewKeys = true; + $this->performDeepMerging = true; + } + + /** + * 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; + } + + /** + * Sets whether to add default values for this array if it has not been + * defined in any of the configuration files. + * + * @param Boolean $boolean + */ + public function setAddIfNotSet($boolean) + { + $this->addIfNotSet = (Boolean) $boolean; + } + + /** + * Sets whether false is allowed as value indicating that the array should be unset. + * + * @param Boolean $allow + */ + public function setAllowFalse($allow) + { + $this->allowFalse = (Boolean) $allow; + } + + /** + * Sets whether new keys can be defined in subsequent configurations. + * + * @param Boolean $allow + */ + public function setAllowNewKeys($allow) + { + $this->allowNewKeys = (Boolean) $allow; + } + + /** + * Sets if deep merging should occur. + * + * @param Boolean $boolean + */ + public function setPerformDeepMerging($boolean) + { + $this->performDeepMerging = (Boolean) $boolean; + } + + /** + * Whether extra keys should just be ignore without an exception. + * + * @param Boolean $boolean To allow extra keys + */ + public function setIgnoreExtraKeys($boolean) + { + $this->ignoreExtraKeys = (Boolean) $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 Boolean + */ + 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 (empty($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) + )); + $ex->setPath($this->getPath()); + + throw $ex; + } + } + + /** + * Normalizes the value. + * + * @param mixed $value The value to normalize + * + * @return mixed The normalized value + */ + protected function normalizeValue($value) + { + if (false === $value) { + return $value; + } + + $value = $this->remapXml($value); + + $normalized = array(); + foreach ($this->children as $name => $child) { + if (array_key_exists($name, $value)) { + $normalized[$name] = $child->normalize($value[$name]); + unset($value[$name]); + } + } + + // if extra fields are present, throw exception + if (count($value) && !$this->ignoreExtraKeys) { + $msg = sprintf('Unrecognized options "%s" under "%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/symfony/src/Symfony/Component/Config/Definition/BaseNode.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/BaseNode.php new file mode 100644 index 0000000..91d5175 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/BaseNode.php @@ -0,0 +1,337 @@ + + * + * 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; + +/** + * The base node class + * + * @author Johannes M. Schmitt + */ +abstract class BaseNode implements NodeInterface +{ + protected $name; + protected $parent; + protected $normalizationClosures; + protected $finalValidationClosures; + protected $allowOverwrite; + protected $required; + protected $equivalentValues; + 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; + $this->normalizationClosures = array(); + $this->finalValidationClosures = array(); + $this->allowOverwrite = true; + $this->required = false; + $this->equivalentValues = array(); + } + + 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 Boolean $boolean Required node + */ + public function setRequired($boolean) + { + $this->required = (Boolean) $boolean; + } + + /** + * Sets if this node can be overridden. + * + * @param Boolean $allow + */ + public function setAllowOverwrite($allow) + { + $this->allowOverwrite = (Boolean) $allow; + } + + /** + * Sets the closures used for normalization. + * + * @param array $closures An array of Closures used for normalization + */ + public function setNormalizationClosures(array $closures) + { + $this->normalizationClosures = $closures; + } + + /** + * Sets the closures used for final validation. + * + * @param array $closures An array of Closures used for final validation + */ + public function setFinalValidationClosures(array $closures) + { + $this->finalValidationClosures = $closures; + } + + /** + * Checks if this node is required. + * + * @return Boolean + */ + 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 + */ + public final 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. + */ + public final function normalize($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); + } + + /** + * Finalizes a value, applying all finalization closures. + * + * @param mixed $value The value to finalize + * + * @return mixed The finalized value + */ + public final 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/symfony/src/Symfony/Component/Config/Definition/BooleanNode.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/BooleanNode.php new file mode 100644 index 0000000..fb37d62 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/BooleanNode.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\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) + )); + $ex->setPath($this->getPath()); + + throw $ex; + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php new file mode 100644 index 0000000..15c289e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php @@ -0,0 +1,419 @@ + + * + * 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; + protected $ignoreExtraKeys; + protected $children; + protected $prototype; + protected $atLeastOne; + protected $allowNewKeys; + protected $key; + protected $removeKeyItem; + protected $addDefaults; + protected $addDefaultChildren; + protected $nodeBuilder; + + /** + * {@inheritDoc} + */ + public function __construct($name, NodeParentInterface $parent = null) + { + parent::__construct($name, $parent); + + $this->children = array(); + $this->addDefaults = false; + $this->addDefaultChildren = false; + $this->allowNewKeys = true; + $this->atLeastOne = false; + $this->allowEmptyValue = true; + $this->performDeepMerging = true; + $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 integer|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 Boolean $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 Boolean $allow + * + * @return ArrayNodeDefinition + */ + public function canBeUnset($allow = true) + { + $this->merge()->allowUnset($allow); + + 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. 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; + } + + /** + * 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); + + 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 confifuration of a concrete node. + * + * @param NodeInterface $node The related node + * + * @throws InvalidDefinitionException When an error is detected in the configuration + */ + 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 NodeInterface $node The related node + * + * @throws InvalidDefinitionException When an error is detected in the configuration + */ + 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_integer($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/symfony/src/Symfony/Component/Config/Definition/Builder/BooleanNodeDefinition.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/BooleanNodeDefinition.php new file mode 100644 index 0000000..7ee4d4d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/BooleanNodeDefinition.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\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/symfony/src/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php new file mode 100755 index 0000000..ff47958 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php @@ -0,0 +1,41 @@ + + */ +class EnumNodeDefinition extends ScalarNodeDefinition +{ + private $values; + + 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; + } + + /** + * Instantiate a Node + * + * @return EnumNode The node + */ + 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); + } +} \ No newline at end of file diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/ExprBuilder.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/ExprBuilder.php new file mode 100644 index 0000000..28474fd --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/ExprBuilder.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\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 + */ + 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 + */ + public function thenUnset() + { + $this->thenPart = function ($v) { throw new UnsetKeyException('Unsetting key'); }; + + return $this; + } + + /** + * Returns the related node + * + * @return NodeDefinition + */ + 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 array $expressions An array of ExprBuilder instances to build + * + * @return array + */ + static public function buildExpressions(array $expressions) + { + foreach ($expressions as $k => $expr) { + if ($expr instanceof ExprBuilder) { + $expressions[$k] = function($v) use($expr) { + return call_user_func($expr->ifPart, $v) ? call_user_func($expr->thenPart, $v) : $v; + }; + } + } + + return $expressions; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/MergeBuilder.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/MergeBuilder.php new file mode 100644 index 0000000..5e09ff5 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/MergeBuilder.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\Config\Definition\Builder; + +/** + * This class builds merge conditions. + * + * @author Johannes M. Schmitt + */ +class MergeBuilder +{ + protected $node; + public $allowFalse; + public $allowOverwrite; + + /** + * Constructor + * + * @param NodeDefinition $node The related node + */ + public function __construct(NodeDefinition $node) + { + $this->node = $node; + $this->allowFalse = false; + $this->allowOverwrite = true; + } + + /** + * Sets whether the node can be unset. + * + * @param Boolean $allow + * + * @return MergeBuilder + */ + public function allowUnset($allow = true) + { + $this->allowFalse = $allow; + + return $this; + } + + /** + * Sets whether the node can be overwritten. + * + * @param Boolean $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/symfony/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php new file mode 100644 index 0000000..c960ac4 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.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\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', + '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 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() + * ; + * + * @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/symfony/src/Symfony/Component/Config/Definition/Builder/NodeDefinition.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/NodeDefinition.php new file mode 100644 index 0000000..614ceff --- /dev/null +++ b/vendor/symfony/symfony/src/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; + +/** + * 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; + protected $required; + protected $merge; + protected $allowEmptyValue; + protected $nullEquivalent; + protected $trueEquivalent; + protected $falseEquivalent; + protected $parent; + protected $attributes = array(); + + /** + * Constructor + * + * @param string $name The name of the node + * @param NodeParentInterface $parent The parent + */ + public function __construct($name, NodeParentInterface $parent = null) + { + $this->parent = $parent; + $this->name = $name; + $this->default = false; + $this->required = false; + $this->trueEquivalent = true; + $this->falseEquivalent = false; + } + + /** + * Sets the parent node. + * + * @param NodeParentInterface $parent The parent + * + * @return NodeDefinition + */ + public function setParent(NodeParentInterface $parent) + { + $this->parent = $parent; + + return $this; + } + + /** + * Sets info message. + * + * @param string $info The info text + * + * @return NodeDefinition + */ + public function info($info) + { + return $this->attribute('info', $info); + } + + /** + * Sets example configuration. + * + * @param string|array $example + * + * @return NodeDefinition + */ + public function example($example) + { + return $this->attribute('example', $example); + } + + /** + * Sets an attribute on the node. + * + * @param string $key + * @param mixed $value + * + * @return NodeDefinition + */ + public function attribute($key, $value) + { + $this->attributes[$key] = $value; + + return $this; + } + + /** + * Returns the parent node. + * + * @return NodeParentInterface The builder of the parent node + */ + public function end() + { + return $this->parent; + } + + /** + * Creates the node. + * + * @param Boolean $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 + */ + public function defaultValue($value) + { + $this->default = true; + $this->defaultValue = $value; + + return $this; + } + + /** + * Sets the node as required. + * + * @return NodeDefinition + */ + public function isRequired() + { + $this->required = true; + + return $this; + } + + /** + * Sets the equivalent value used when the node contains null. + * + * @param mixed $value + * + * @return NodeDefinition + */ + public function treatNullLike($value) + { + $this->nullEquivalent = $value; + + return $this; + } + + /** + * Sets the equivalent value used when the node contains true. + * + * @param mixed $value + * + * @return NodeDefinition + */ + public function treatTrueLike($value) + { + $this->trueEquivalent = $value; + + return $this; + } + + /** + * Sets the equivalent value used when the node contains false. + * + * @param mixed $value + * + * @return NodeDefinition + */ + public function treatFalseLike($value) + { + $this->falseEquivalent = $value; + + return $this; + } + + /** + * Sets null as the default value. + * + * @return NodeDefinition + */ + public function defaultNull() + { + return $this->defaultValue(null); + } + + /** + * Sets true as the default value. + * + * @return NodeDefinition + */ + public function defaultTrue() + { + return $this->defaultValue(true); + } + + /** + * Sets false as the default value. + * + * @return NodeDefinition + */ + 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 + */ + 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 Boolean $deny Whether the overwriting is forbidden or not + * + * @return NodeDefinition + */ + 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 Symfony\Component\Config\Definition\Exception\InvalidDefinitionException When the definition is invalid + */ + abstract protected function createNode(); + +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/NodeParentInterface.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/NodeParentInterface.php new file mode 100644 index 0000000..24f3971 --- /dev/null +++ b/vendor/symfony/symfony/src/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/symfony/src/Symfony/Component/Config/Definition/Builder/NormalizationBuilder.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/NormalizationBuilder.php new file mode 100644 index 0000000..87f25b7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/NormalizationBuilder.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\Config\Definition\Builder; + +/** + * This class builds normalization conditions. + * + * @author Johannes M. Schmitt + */ +class NormalizationBuilder +{ + protected $node; + public $before; + public $remappings; + + /** + * Constructor + * + * @param NodeDefinition $node The related node + */ + public function __construct(NodeDefinition $node) + { + $this->node = $node; + $this->keys = false; + $this->remappings = array(); + $this->before = array(); + } + + /** + * 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/symfony/src/Symfony/Component/Config/Definition/Builder/ParentNodeDefinitionInterface.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/ParentNodeDefinitionInterface.php new file mode 100644 index 0000000..2d95954 --- /dev/null +++ b/vendor/symfony/symfony/src/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 +{ + function children(); + + function append(NodeDefinition $node); + + function setBuilder(NodeBuilder $builder); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/ScalarNodeDefinition.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/ScalarNodeDefinition.php new file mode 100644 index 0000000..6a115fe --- /dev/null +++ b/vendor/symfony/symfony/src/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/symfony/src/Symfony/Component/Config/Definition/Builder/TreeBuilder.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/TreeBuilder.php new file mode 100644 index 0000000..1070fd7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/TreeBuilder.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\Config\Definition\Builder; + +/** + * 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 + */ + 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/symfony/src/Symfony/Component/Config/Definition/Builder/ValidationBuilder.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/ValidationBuilder.php new file mode 100644 index 0000000..22f54a1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/ValidationBuilder.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\Config\Definition\Builder; + +/** + * This class builds validation conditions. + * + * @author Christophe Coevoet + */ +class ValidationBuilder +{ + protected $node; + public $rules; + + /** + * Constructor + * + * @param NodeDefinition $node The related node + */ + public function __construct(NodeDefinition $node) + { + $this->node = $node; + + $this->rules = array(); + } + + /** + * 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/symfony/src/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.php new file mode 100644 index 0000000..75da3ab --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.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\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); + } + + if (false === $this->allowEmptyValue) { + $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/symfony/src/Symfony/Component/Config/Definition/ConfigurationInterface.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/ConfigurationInterface.php new file mode 100644 index 0000000..dc189e2 --- /dev/null +++ b/vendor/symfony/symfony/src/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 + */ + function getConfigTreeBuilder(); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/EnumNode.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/EnumNode.php new file mode 100755 index 0000000..301dfd7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/EnumNode.php @@ -0,0 +1,50 @@ + + */ +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; + } +} \ No newline at end of file diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Exception/DuplicateKeyException.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Exception/DuplicateKeyException.php new file mode 100644 index 0000000..48dd932 --- /dev/null +++ b/vendor/symfony/symfony/src/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/symfony/src/Symfony/Component/Config/Definition/Exception/Exception.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Exception/Exception.php new file mode 100644 index 0000000..1fda6c2 --- /dev/null +++ b/vendor/symfony/symfony/src/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/symfony/src/Symfony/Component/Config/Definition/Exception/ForbiddenOverwriteException.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Exception/ForbiddenOverwriteException.php new file mode 100644 index 0000000..726c07f --- /dev/null +++ b/vendor/symfony/symfony/src/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/symfony/src/Symfony/Component/Config/Definition/Exception/InvalidConfigurationException.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Exception/InvalidConfigurationException.php new file mode 100644 index 0000000..840e3f3 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Exception/InvalidConfigurationException.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\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; + + public function setPath($path) + { + $this->path = $path; + } + + public function getPath() + { + return $this->path; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Exception/InvalidDefinitionException.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Exception/InvalidDefinitionException.php new file mode 100644 index 0000000..98310da --- /dev/null +++ b/vendor/symfony/symfony/src/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/symfony/src/Symfony/Component/Config/Definition/Exception/InvalidTypeException.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Exception/InvalidTypeException.php new file mode 100644 index 0000000..d7ca8c9 --- /dev/null +++ b/vendor/symfony/symfony/src/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/symfony/src/Symfony/Component/Config/Definition/Exception/UnsetKeyException.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Exception/UnsetKeyException.php new file mode 100644 index 0000000..863181a --- /dev/null +++ b/vendor/symfony/symfony/src/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/symfony/src/Symfony/Component/Config/Definition/NodeInterface.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/NodeInterface.php new file mode 100644 index 0000000..89c4360 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/NodeInterface.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\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 + */ + function getName(); + + /** + * Returns the path of the node. + * + * @return string The node path + */ + function getPath(); + + /** + * Returns true when the node is required. + * + * @return Boolean If the node is required + */ + function isRequired(); + + /** + * Returns true when the node has a default value. + * + * @return Boolean If the node has a default value + */ + function hasDefaultValue(); + + /** + * Returns the default value of the node. + * + * @return mixed The default value + * @throws \RuntimeException if the node has no default value + */ + function getDefaultValue(); + + /** + * Normalizes the supplied value. + * + * @param mixed $value The value to normalize + * + * @return mixed The normalized value + */ + function normalize($value); + + /** + * Merges two values together. + * + * @param mixed $leftSide + * @param mixed $rightSide + * + * @return mixed The merged values + */ + function merge($leftSide, $rightSide); + + /** + * Finalizes a value. + * + * @param mixed $value The value to finalize + * + * @return mixed The finalized value + */ + function finalize($value); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Processor.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Processor.php new file mode 100644 index 0000000..a6c3181 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Processor.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\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) + { + $configs = self::normalizeKeys($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); + } + + /** + * This method 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 array $config + * + * @return array the config with normalized keys + */ + static public function normalizeKeys(array $config) + { + foreach ($config as $key => $value) { + if (is_array($value)) { + $config[$key] = self::normalizeKeys($value); + } + + if (false !== strpos($key, '-') && false === strpos($key, '_') && !array_key_exists($normalizedKey = str_replace('-', '_', $key), $config)) { + $config[$normalizedKey] = $config[$key]; + unset($config[$key]); + } + } + + return $config; + } + + /** + * 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 is XML: + * + * + * + * + * And the same configuration in YAML: + * + * twig.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 + */ + static public function normalizeConfig($config, $key, $plural = null) + { + if (null === $plural) { + $plural = $key.'s'; + } + + $values = array(); + if (isset($config[$plural])) { + $values = $config[$plural]; + } elseif (isset($config[$key])) { + if (is_string($config[$key]) || !is_int(key($config[$key]))) { + // only one + $values = array($config[$key]); + } else { + $values = $config[$key]; + } + } + + return $values; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/PrototypeNodeInterface.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/PrototypeNodeInterface.php new file mode 100644 index 0000000..8f08c98 --- /dev/null +++ b/vendor/symfony/symfony/src/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 + */ + function setName($name); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/PrototypedArrayNode.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/PrototypedArrayNode.php new file mode 100644 index 0000000..a2f8fba --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/PrototypedArrayNode.php @@ -0,0 +1,342 @@ + + * + * 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; + protected $minNumberOfElements; + protected $defaultValue; + protected $defaultChildren; + + /** + * Constructor. + * + * @param string $name The Node's name + * @param NodeInterface $parent The node parent + */ + public function __construct($name, NodeInterface $parent = null) + { + parent::__construct($name, $parent); + + $this->minNumberOfElements = 0; + $this->defaultValue = array(); + } + + /** + * Sets the minimum number of elements that a prototype based node must + * contain. By default this is zero, meaning no elements. + * + * @param integer $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 Boolean $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 Boolean + */ + public function hasDefaultValue() + { + return true; + } + + /** + * Adds default children when none are set. + * + * @param integer|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_integer($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 \RuntimeException Prototyped array nodes can't have concrete children. + */ + 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 + */ + 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) { + $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/symfony/src/Symfony/Component/Config/Definition/ScalarNode.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/ScalarNode.php new file mode 100644 index 0000000..51141c4 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/ScalarNode.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\Config\Definition; + +use Symfony\Component\Config\Definition\VariableNode; +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) + )); + $ex->setPath($this->getPath()); + + throw $ex; + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/VariableNode.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/VariableNode.php new file mode 100644 index 0000000..69dfea6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/VariableNode.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\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() + { + return $this->defaultValue instanceof \Closure ? call_user_func($this->defaultValue) : $this->defaultValue; + } + + /** + * Sets if this node is allowed to have an empty value. + * + * @param Boolean $boolean True if this entity will accept empty values. + */ + public function setAllowEmptyValue($boolean) + { + $this->allowEmptyValue = (Boolean) $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) + )); + $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/symfony/src/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php new file mode 100644 index 0000000..b1ad442 --- /dev/null +++ b/vendor/symfony/symfony/src/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]); + + call_user_func('Exception::__construct', $message, $code, $previous); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Exception/FileLoaderLoadException.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Exception/FileLoaderLoadException.php new file mode 100644 index 0000000..fcf61db --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Exception/FileLoaderLoadException.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\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 integer $code The error code + * @param Exception $previous A previous exception + */ + public function __construct($resource, $sourceResource = null, $code = null, $previous = null) + { + if (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/symfony/src/Symfony/Component/Config/FileLocator.php b/vendor/symfony/symfony/src/Symfony/Component/Config/FileLocator.php new file mode 100644 index 0000000..7f9dadc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/FileLocator.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; + +/** + * 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; + } + + /** + * Returns a full path for a given file name. + * + * @param mixed $name The file name to locate + * @param string $currentPath The current path + * @param Boolean $first Whether to return the first occurrence or an array of filenames + * + * @return string|array The full path to the file|An array of file paths + * + * @throws \InvalidArgumentException When file is not found + */ + public function locate($name, $currentPath = null, $first = true) + { + 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 Boolean + */ + 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/symfony/src/Symfony/Component/Config/FileLocatorInterface.php b/vendor/symfony/symfony/src/Symfony/Component/Config/FileLocatorInterface.php new file mode 100644 index 0000000..d756b83 --- /dev/null +++ b/vendor/symfony/symfony/src/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 mixed $name The file name to locate + * @param string $currentPath The current path + * @param Boolean $first Whether to return the first occurrence or an array of filenames + * + * @return string|array The full path to the file|An array of file paths + * + * @throws \InvalidArgumentException When file is not found + */ + function locate($name, $currentPath = null, $first = true); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/LICENSE b/vendor/symfony/symfony/src/Symfony/Component/Config/LICENSE new file mode 100644 index 0000000..cdffe7a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 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/symfony/src/Symfony/Component/Config/Loader/DelegatingLoader.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Loader/DelegatingLoader.php new file mode 100644 index 0000000..775946b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Loader/DelegatingLoader.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\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; + } + + /** + * Loads a resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return mixed + * + * @throws FileLoaderLoadException if no loader is found. + */ + 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) ? false : true; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Loader/FileLoader.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Loader/FileLoader.php new file mode 100644 index 0000000..39c36b4 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Loader/FileLoader.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\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 +{ + static protected $loading = array(); + + protected $locator; + + private $currentDir; + + /** + * Constructor. + * + * @param FileLocatorInterface $locator A FileLocatorInterface instance + */ + public function __construct(FileLocatorInterface $locator) + { + $this->locator = $locator; + } + + public function setCurrentDir($dir) + { + $this->currentDir = $dir; + } + + public function getLocator() + { + return $this->locator; + } + + /** + * Imports a resource. + * + * @param mixed $resource A Resource + * @param string $type The resource type + * @param Boolean $ignoreErrors Whether to ignore import errors or not + * @param string $sourceResource The original resource importing the new resource + * + * @return mixed + */ + public function import($resource, $type = null, $ignoreErrors = false, $sourceResource = null) + { + try { + $loader = $this->resolve($resource, $type); + + if ($loader instanceof FileLoader && null !== $this->currentDir) { + $resource = $this->locator->locate($resource, $this->currentDir); + } + + if (isset(self::$loading[$resource])) { + throw new FileLoaderImportCircularReferenceException(array_keys(self::$loading)); + } + self::$loading[$resource] = true; + + $ret = $loader->load($resource); + + 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/symfony/src/Symfony/Component/Config/Loader/Loader.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Loader/Loader.php new file mode 100644 index 0000000..b9c174f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Loader/Loader.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\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; + + /** + * Gets the loader resolver. + * + * @return LoaderResolverInterface A LoaderResolverInterface instance + */ + public function getResolver() + { + return $this->resolver; + } + + /** + * Sets the loader resolver. + * + * @param LoaderResolverInterface $resolver A LoaderResolverInterface instance + */ + public function setResolver(LoaderResolverInterface $resolver) + { + $this->resolver = $resolver; + } + + /** + * Imports a resource. + * + * @param mixed $resource A Resource + * @param string $type The resource type + */ + public function import($resource, $type = null) + { + $this->resolve($resource)->load($resource, $type); + } + + /** + * Finds a loader able to load an imported resource. + * + * @param mixed $resource A Resource + * @param string $type The resource type + * + * @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/symfony/src/Symfony/Component/Config/Loader/LoaderInterface.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Loader/LoaderInterface.php new file mode 100644 index 0000000..10bfefc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Loader/LoaderInterface.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\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 $type The resource type + */ + function load($resource, $type = null); + + /** + * Returns true if this class supports the given resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return Boolean true if this class supports the given resource, false otherwise + */ + function supports($resource, $type = null); + + /** + * Gets the loader resolver. + * + * @return LoaderResolverInterface A LoaderResolverInterface instance + */ + function getResolver(); + + /** + * Sets the loader resolver. + * + * @param LoaderResolverInterface $resolver A LoaderResolverInterface instance + */ + function setResolver(LoaderResolverInterface $resolver); + +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Loader/LoaderResolver.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Loader/LoaderResolver.php new file mode 100644 index 0000000..2340fe0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Loader/LoaderResolver.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\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; + + /** + * Constructor. + * + * @param LoaderInterface[] $loaders An array of loaders + */ + public function __construct(array $loaders = array()) + { + $this->loaders = array(); + foreach ($loaders as $loader) { + $this->addLoader($loader); + } + } + + /** + * Returns a loader able to load the resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return LoaderInterface|false A LoaderInterface instance + */ + 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/symfony/src/Symfony/Component/Config/Loader/LoaderResolverInterface.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Loader/LoaderResolverInterface.php new file mode 100644 index 0000000..f660401 --- /dev/null +++ b/vendor/symfony/symfony/src/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 $type The resource type + * + * @return LoaderInterface A LoaderInterface instance + */ + function resolve($resource, $type = null); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/README.md b/vendor/symfony/symfony/src/Symfony/Component/Config/README.md new file mode 100644 index 0000000..e87363d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/README.md @@ -0,0 +1,14 @@ +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: + + phpunit diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Resource/DirectoryResource.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Resource/DirectoryResource.php new file mode 100644 index 0000000..5ccd204 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Resource/DirectoryResource.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\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 $pattern A pattern to restrict monitored files + */ + public function __construct($resource, $pattern = null) + { + $this->resource = $resource; + $this->pattern = $pattern; + } + + /** + * Returns a string representation of the Resource. + * + * @return string A string representation of the Resource + */ + public function __toString() + { + return (string) $this->resource; + } + + /** + * Returns the resource tied to this Resource. + * + * @return mixed The resource + */ + public function getResource() + { + return $this->resource; + } + + public function getPattern() + { + return $this->pattern; + } + + /** + * Returns true if the resource has not been updated since the given timestamp. + * + * @param integer $timestamp The last time the resource was loaded + * + * @return Boolean true if the resource has not been updated, false otherwise + */ + 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/symfony/src/Symfony/Component/Config/Resource/FileResource.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Resource/FileResource.php new file mode 100644 index 0000000..619f84b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Resource/FileResource.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\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 +{ + private $resource; + + /** + * Constructor. + * + * @param string $resource The file path to the resource + */ + public function __construct($resource) + { + $this->resource = realpath($resource); + } + + /** + * Returns a string representation of the Resource. + * + * @return string A string representation of the Resource + */ + public function __toString() + { + return (string) $this->resource; + } + + /** + * Returns the resource tied to this Resource. + * + * @return mixed The resource + */ + public function getResource() + { + return $this->resource; + } + + /** + * Returns true if the resource has not been updated since the given timestamp. + * + * @param integer $timestamp The last time the resource was loaded + * + * @return Boolean true if the resource has not been updated, false otherwise + */ + public function isFresh($timestamp) + { + if (!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/symfony/src/Symfony/Component/Config/Resource/ResourceInterface.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Resource/ResourceInterface.php new file mode 100644 index 0000000..024f2e9 --- /dev/null +++ b/vendor/symfony/symfony/src/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 + */ + function __toString(); + + /** + * Returns true if the resource has not been updated since the given timestamp. + * + * @param integer $timestamp The last time the resource was loaded + * + * @return Boolean true if the resource has not been updated, false otherwise + */ + function isFresh($timestamp); + + /** + * Returns the resource tied to this Resource. + * + * @return mixed The resource + */ + function getResource(); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php new file mode 100644 index 0000000..ef45ba8 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.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\Config\Tests\Definition; + +use Symfony\Component\Config\Definition\ArrayNode; + +class ArrayNodeTest extends \PHPUnit_Framework_TestCase +{ + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidTypeException + */ + public function testNormalizeThrowsExceptionWhenFalseIsNotAllowed() + { + $node = new ArrayNode('root'); + $node->normalize(false); + } + + /** + * normalize() should protect against child values with no corresponding node + */ + public function testExceptionThrownOnUnrecognizedChild() + { + $node = new ArrayNode('root'); + + try { + $node->normalize(array('foo' => 'bar')); + $this->fail('An exception should have been throw for a bad child node'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Config\Definition\Exception\InvalidConfigurationException', $e); + $this->assertEquals('Unrecognized options "foo" under "root"', $e->getMessage()); + } + } + + /** + * 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'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php new file mode 100644 index 0000000..8369f71 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.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\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/symfony/src/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php new file mode 100644 index 0000000..3c298a4 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.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\Config\Tests\Definition\Builder; + +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +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 testPrototypeNodesCantHaveADefaultValueWhenUsingDefaulChildren() + { + $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(); + } + + protected function getField($object, $field) + { + $reflection = new \ReflectionProperty($object, $field); + $reflection->setAccessible(true); + + return $reflection->getValue($object); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/Builder/EnumNodeDefinitionTest.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/Builder/EnumNodeDefinitionTest.php new file mode 100755 index 0000000..9f1955e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/Builder/EnumNodeDefinitionTest.php @@ -0,0 +1,37 @@ +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()); + } +} \ No newline at end of file diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/Builder/NodeBuilderTest.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/Builder/NodeBuilderTest.php new file mode 100644 index 0000000..c829591 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/Builder/NodeBuilderTest.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\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->assertEquals(get_class($node), $class); + } + + public function testOverridingAnExistingNodeType() + { + $class = __NAMESPACE__.'\\SomeNodeDefinition'; + + $builder = new BaseNodeBuilder(); + $node = $builder + ->setNodeClass('variable', $class) + ->node('', 'variable'); + + $this->assertEquals(get_class($node), $class); + } + + public function testNodeTypesAreNotCaseSensitive() + { + $builder = new BaseNodeBuilder(); + + $node1 = $builder->node('', 'VaRiAbLe'); + $node2 = $builder->node('', 'variable'); + + $this->assertEquals(get_class($node1), get_class($node2)); + + $builder->setNodeClass('CuStOm', __NAMESPACE__.'\\SomeNodeDefinition'); + + $node1 = $builder->node('', 'CUSTOM'); + $node2 = $builder->node('', 'custom'); + + $this->assertEquals(get_class($node1), get_class($node2)); + } +} + +class SomeNodeDefinition extends BaseVariableNodeDefinition +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/Builder/TreeBuilderTest.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/Builder/TreeBuilderTest.php new file mode 100644 index 0000000..ca2b0e6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/Builder/TreeBuilderTest.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\Config\Tests\Definition\Builder; + +use Symfony\Component\Config\Tests\Definition\Builder\NodeBuilder as CustomNodeBuilder; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; + +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->assertEquals(get_class($nodeBuilder), 'Symfony\Component\Config\Tests\Definition\Builder\NodeBuilder'); + + $nodeBuilder = $nodeBuilder->arrayNode('deeper')->children(); + + $this->assertEquals(get_class($nodeBuilder), 'Symfony\Component\Config\Tests\Definition\Builder\NodeBuilder'); + } + + public function testOverrideABuiltInNodeType() + { + $builder = new TreeBuilder(); + $root = $builder->root('override', 'array', new CustomNodeBuilder()); + + $definition = $root->children()->variableNode('variable'); + + $this->assertEquals(get_class($definition), 'Symfony\Component\Config\Tests\Definition\Builder\VariableNodeDefinition'); + } + + public function testAddANodeType() + { + $builder = new TreeBuilder(); + $root = $builder->root('override', 'array', new CustomNodeBuilder()); + + $definition = $root->children()->barNode('variable'); + + $this->assertEquals(get_class($definition), 'Symfony\Component\Config\Tests\Definition\Builder\BarNodeDefinition'); + } + + public function testCreateABuiltInNodeTypeWithACustomNodeBuilder() + { + $builder = new TreeBuilder(); + $root = $builder->root('builtin', 'array', new CustomNodeBuilder()); + + $definition = $root->children()->booleanNode('boolean'); + + $this->assertEquals(get_class($definition), 'Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition'); + } + + 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 testDefinitionInfoGetsTransferedToNode() + { + $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 testDefinitionExampleGetsTransferedToNode() + { + $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/symfony/src/Symfony/Component/Config/Tests/Definition/EnumNodeTest.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/EnumNodeTest.php new file mode 100755 index 0000000..9c18da6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/EnumNodeTest.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\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'); + } +} \ No newline at end of file diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/FinalizationTest.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/FinalizationTest.php new file mode 100644 index 0000000..19fc347 --- /dev/null +++ b/vendor/symfony/symfony/src/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/symfony/src/Symfony/Component/Config/Tests/Definition/MergeTest.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/MergeTest.php new file mode 100644 index 0000000..d90a3a9 --- /dev/null +++ b/vendor/symfony/symfony/src/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/symfony/src/Symfony/Component/Config/Tests/Definition/NormalizationTest.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/NormalizationTest.php new file mode 100644 index 0000000..ee49154 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/NormalizationTest.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\Config\Tests\Definition; + +use Symfony\Component\Config\Definition\NodeInterface; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; + +class NormalizerTest 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 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/symfony/src/Symfony/Component/Config/Tests/Definition/ProcessorTest.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/ProcessorTest.php new file mode 100644 index 0000000..56368ac --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/ProcessorTest.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\Tests\Definition; + +use Symfony\Component\Config\Definition\Processor; + +class ProcessorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getKeyNormalizationTests + */ + public function testNormalizeKeys($denormalized, $normalized) + { + $this->assertSame($normalized, Processor::normalizeKeys($denormalized)); + } + + public function getKeyNormalizationTests() + { + 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'), + ), + array( + array('foo-bar' => array('foo-bar' => 'foo')), + array('foo_bar' => array('foo_bar' => 'foo')), + ), + array( + array('foo_bar' => array('foo-bar' => 'foo')), + array('foo_bar' => array('foo_bar' => 'foo')), + ) + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php new file mode 100644 index 0000000..31d3c89 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php @@ -0,0 +1,181 @@ + + * + * 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/symfony/src/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php new file mode 100644 index 0000000..91e47ef --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.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\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()), + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/FileLocatorTest.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/FileLocatorTest.php new file mode 100644 index 0000000..8e8f442 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/FileLocatorTest.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\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 + */ + 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__); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Fixtures/Again/foo.xml b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Fixtures/Again/foo.xml new file mode 100644 index 0000000..e69de29 diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Fixtures/Builder/BarNodeDefinition.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Fixtures/Builder/BarNodeDefinition.php new file mode 100644 index 0000000..47701c1 --- /dev/null +++ b/vendor/symfony/symfony/src/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/symfony/src/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php new file mode 100644 index 0000000..aa59863 --- /dev/null +++ b/vendor/symfony/symfony/src/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/symfony/src/Symfony/Component/Config/Tests/Fixtures/Builder/VariableNodeDefinition.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Fixtures/Builder/VariableNodeDefinition.php new file mode 100644 index 0000000..1017880 --- /dev/null +++ b/vendor/symfony/symfony/src/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/symfony/src/Symfony/Component/Config/Tests/Fixtures/foo.xml b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Fixtures/foo.xml new file mode 100644 index 0000000..e69de29 diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Loader/DelegatingLoaderTest.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Loader/DelegatingLoaderTest.php new file mode 100644 index 0000000..3b04a01 --- /dev/null +++ b/vendor/symfony/symfony/src/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/symfony/src/Symfony/Component/Config/Tests/Loader/LoaderResolverTest.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Loader/LoaderResolverTest.php new file mode 100644 index 0000000..8ee276b --- /dev/null +++ b/vendor/symfony/symfony/src/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/symfony/src/Symfony/Component/Config/Tests/Loader/LoaderTest.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Loader/LoaderTest.php new file mode 100644 index 0000000..5b14e19 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Loader/LoaderTest.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\Config\Tests\Loader; + +use Symfony\Component\Config\Loader\LoaderResolver; +use Symfony\Component\Config\Loader\Loader; +use Symfony\Component\Config\Exception\FileLoaderLoadException; + +class LoaderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Symfony\Component\Config\Loader\Loader::getResolver + * @covers Symfony\Component\Config\Loader\Loader::setResolver + */ + public function testGetSetResolver() + { + $resolver = new LoaderResolver(); + $loader = new ProjectLoader1(); + $loader->setResolver($resolver); + $this->assertSame($resolver, $loader->getResolver(), '->setResolver() sets the resolver loader'); + } + + /** + * @covers Symfony\Component\Config\Loader\Loader::resolve + */ + public function testResolve() + { + $loader1 = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface'); + $loader1->expects($this->once())->method('supports')->will($this->returnValue(true)); + $resolver = new LoaderResolver(array($loader1)); + $loader = new ProjectLoader1(); + $loader->setResolver($resolver); + + $this->assertSame($loader, $loader->resolve('foo.foo'), '->resolve() finds a loader'); + $this->assertSame($loader1, $loader->resolve('foo.xml'), '->resolve() finds a loader'); + + $loader1 = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface'); + $loader1->expects($this->once())->method('supports')->will($this->returnValue(false)); + $resolver = new LoaderResolver(array($loader1)); + $loader = new ProjectLoader1(); + $loader->setResolver($resolver); + try { + $loader->resolve('FOOBAR'); + $this->fail('->resolve() throws a FileLoaderLoadException if the resource cannot be loaded'); + } catch (FileLoaderLoadException $e) { + $this->assertInstanceOf('Symfony\Component\Config\Exception\FileLoaderLoadException', $e, '->resolve() throws a FileLoaderLoadException if the resource cannot be loaded'); + } + } +} + +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/symfony/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php new file mode 100644 index 0000000..c626ec6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php @@ -0,0 +1,171 @@ + + * + * 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); + } + + /** + * @covers Symfony\Component\Config\Resource\DirectoryResource::getResource + */ + public function testGetResource() + { + $resource = new DirectoryResource($this->directory); + $this->assertEquals($this->directory, $resource->getResource(), '->getResource() returns the path to the resource'); + } + + public function testGetPattern() + { + $resource = new DirectoryResource('foo', 'bar'); + $this->assertEquals('bar', $resource->getPattern()); + } + + /** + * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh + */ + 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'); + } + + /** + * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh + */ + 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'); + } + + /** + * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh + */ + 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'); + } + + /** + * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh + */ + 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'); + } + + /** + * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh + */ + 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'); + } + + /** + * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh + */ + 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'); + } + + /** + * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh + */ + 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)'); + } + + /** + * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh + */ + 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'); + } + + /** + * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh + */ + 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 '); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php new file mode 100644 index 0000000..83c403b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Resource; + +use Symfony\Component\Config\Resource\FileResource; + +class FileResourceTest extends \PHPUnit_Framework_TestCase +{ + protected $resource; + protected $file; + + protected function setUp() + { + $this->file = sys_get_temp_dir().'/tmp.xml'; + touch($this->file); + $this->resource = new FileResource($this->file); + } + + protected function tearDown() + { + unlink($this->file); + } + + /** + * @covers Symfony\Component\Config\Resource\FileResource::getResource + */ + public function testGetResource() + { + $this->assertEquals(realpath($this->file), $this->resource->getResource(), '->getResource() returns the path to the resource'); + } + + /** + * @covers Symfony\Component\Config\Resource\FileResource::isFresh + */ + public function testIsFresh() + { + $this->assertTrue($this->resource->isFresh(time() + 10), '->isFresh() returns true if the resource has not changed'); + $this->assertFalse($this->resource->isFresh(time() - 86400), '->isFresh() returns false if the resource has been updated'); + + $resource = new FileResource('/____foo/foobar'.rand(1, 999999)); + $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the resource does not exist'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/bootstrap.php b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/bootstrap.php new file mode 100644 index 0000000..3a61b6d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/Tests/bootstrap.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +spl_autoload_register(function ($class) { + if (0 === strpos(ltrim($class, '/'), 'Symfony\Component\Config')) { + if (file_exists($file = __DIR__.'/../'.substr(str_replace('\\', '/', $class), strlen('Symfony\Component\Config')).'.php')) { + require_once $file; + } + } +}); diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/composer.json b/vendor/symfony/symfony/src/Symfony/Component/Config/composer.json new file mode 100644 index 0000000..41f08cb --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/composer.json @@ -0,0 +1,30 @@ +{ + "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" + }, + "autoload": { + "psr-0": { "Symfony\\Component\\Config": "" } + }, + "target-dir": "Symfony/Component/Config", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Config/phpunit.xml.dist b/vendor/symfony/symfony/src/Symfony/Component/Config/phpunit.xml.dist new file mode 100644 index 0000000..e019519 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Config/phpunit.xml.dist @@ -0,0 +1,30 @@ + + + + + + ./Tests/ + + + + + + ./ + + ./Resources + ./Tests + ./vendor + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php new file mode 100644 index 0000000..0c49df8 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php @@ -0,0 +1,1080 @@ + + * + * 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\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\Output\OutputInterface; +use Symfony\Component\Console\Output\Output; +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; + +/** + * 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; + private $wantHelps = false; + private $runningCommand; + private $name; + private $version; + private $catchExceptions; + private $autoExit; + private $definition; + private $helperSet; + + /** + * 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->catchExceptions = true; + $this->autoExit = true; + $this->commands = array(); + $this->helperSet = $this->getDefaultHelperSet(); + $this->definition = $this->getDefaultInputDefinition(); + + foreach ($this->getDefaultCommands() as $command) { + $this->add($command); + } + } + + /** + * Runs the current application. + * + * @param InputInterface $input An Input instance + * @param OutputInterface $output An Output instance + * + * @return integer 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(); + } + + try { + $statusCode = $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); + } + $statusCode = $e->getCode(); + + $statusCode = is_numeric($statusCode) && $statusCode ? $statusCode : 1; + } + + if ($this->autoExit) { + if ($statusCode > 255) { + $statusCode = 255; + } + // @codeCoverageIgnoreStart + exit($statusCode); + // @codeCoverageIgnoreEnd + } + + return $statusCode; + } + + /** + * Runs the current application. + * + * @param InputInterface $input An Input instance + * @param OutputInterface $output An Output instance + * + * @return integer 0 if everything went fine, or an error code + */ + public function doRun(InputInterface $input, OutputInterface $output) + { + $name = $this->getCommandName($input); + + if (true === $input->hasParameterOption(array('--ansi'))) { + $output->setDecorated(true); + } elseif (true === $input->hasParameterOption(array('--no-ansi'))) { + $output->setDecorated(false); + } + + if (true === $input->hasParameterOption(array('--help', '-h'))) { + if (!$name) { + $name = 'help'; + $input = new ArrayInput(array('command' => 'help')); + } else { + $this->wantHelps = true; + } + } + + if (true === $input->hasParameterOption(array('--no-interaction', '-n'))) { + $input->setInteractive(false); + } + + if (function_exists('posix_isatty') && $this->getHelperSet()->has('dialog')) { + $inputStream = $this->getHelperSet()->get('dialog')->getInputStream(); + if (!posix_isatty($inputStream)) { + $input->setInteractive(false); + } + } + + if (true === $input->hasParameterOption(array('--quiet', '-q'))) { + $output->setVerbosity(OutputInterface::VERBOSITY_QUIET); + } elseif (true === $input->hasParameterOption(array('--verbose', '-v'))) { + $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE); + } + + if (true === $input->hasParameterOption(array('--version', '-V'))) { + $output->writeln($this->getLongVersion()); + + return 0; + } + + if (!$name) { + $name = 'list'; + $input = new ArrayInput(array('command' => 'list')); + } + + // the command name MUST be the first element of the input + $command = $this->find($name); + + $this->runningCommand = $command; + $statusCode = $command->run($input, $output); + $this->runningCommand = null; + + return is_numeric($statusCode) ? $statusCode : 0; + } + + /** + * 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; + } + + /** + * 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() + { + $messages = array( + $this->getLongVersion(), + '', + 'Usage:', + sprintf(" [options] command [arguments]\n"), + 'Options:', + ); + + foreach ($this->getDefinition()->getOptions() as $option) { + $messages[] = sprintf(' %-29s %s %s', + '--'.$option->getName().'', + $option->getShortcut() ? '-'.$option->getShortcut().'' : ' ', + $option->getDescription() + ); + } + + return implode(PHP_EOL, $messages); + } + + /** + * Sets whether to catch exceptions or not during commands execution. + * + * @param Boolean $boolean Whether to catch exceptions or not during commands execution + * + * @api + */ + public function setCatchExceptions($boolean) + { + $this->catchExceptions = (Boolean) $boolean; + } + + /** + * Sets whether to automatically exit after a command execution or not. + * + * @param Boolean $boolean Whether to automatically exit after a command execution or not + * + * @api + */ + public function setAutoExit($boolean) + { + $this->autoExit = (Boolean) $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; + } + + $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 Boolean 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[] = $this->extractNamespace($command->getName()); + + foreach ($command->getAliases() as $alias) { + $namespaces[] = $this->extractNamespace($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 = array(); + foreach ($this->getNamespaces() as $n) { + $allNamespaces[$n] = explode(':', $n); + } + + $found = array(); + foreach (explode(':', $namespace) as $i => $part) { + $abbrevs = static::getAbbreviations(array_unique(array_values(array_filter(array_map(function ($p) use ($i) { return isset($p[$i]) ? $p[$i] : ''; }, $allNamespaces))))); + + if (!isset($abbrevs[$part])) { + $message = sprintf('There are no commands defined in the "%s" namespace.', $namespace); + + if (1 <= $i) { + $part = implode(':', $found).':'.$part; + } + + if ($alternatives = $this->findAlternativeNamespace($part, $abbrevs)) { + $message .= "\n\nDid you mean one of these?\n "; + $message .= implode("\n ", $alternatives); + } + + throw new \InvalidArgumentException($message); + } + + if (count($abbrevs[$part]) > 1) { + throw new \InvalidArgumentException(sprintf('The namespace "%s" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions($abbrevs[$part]))); + } + + $found[] = $abbrevs[$part][0]; + } + + return implode(':', $found); + } + + /** + * 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) + { + // namespace + $namespace = ''; + $searchName = $name; + if (false !== $pos = strrpos($name, ':')) { + $namespace = $this->findNamespace(substr($name, 0, $pos)); + $searchName = $namespace.substr($name, $pos); + } + + // name + $commands = array(); + foreach ($this->commands as $command) { + if ($this->extractNamespace($command->getName()) == $namespace) { + $commands[] = $command->getName(); + } + } + + $abbrevs = static::getAbbreviations(array_unique($commands)); + if (isset($abbrevs[$searchName]) && 1 == count($abbrevs[$searchName])) { + return $this->get($abbrevs[$searchName][0]); + } + + if (isset($abbrevs[$searchName]) && count($abbrevs[$searchName]) > 1) { + $suggestions = $this->getAbbreviationSuggestions($abbrevs[$searchName]); + + throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions)); + } + + // aliases + $aliases = array(); + foreach ($this->commands as $command) { + foreach ($command->getAliases() as $alias) { + if ($this->extractNamespace($alias) == $namespace) { + $aliases[] = $alias; + } + } + } + + $aliases = static::getAbbreviations(array_unique($aliases)); + if (!isset($aliases[$searchName])) { + $message = sprintf('Command "%s" is not defined.', $name); + + if ($alternatives = $this->findAlternativeCommands($searchName, $abbrevs)) { + $message .= "\n\nDid you mean one of these?\n "; + $message .= implode("\n ", $alternatives); + } + + throw new \InvalidArgumentException($message); + } + + if (count($aliases[$searchName]) > 1) { + throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $this->getAbbreviationSuggestions($aliases[$searchName]))); + } + + return $this->get($aliases[$searchName][0]); + } + + /** + * 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 array 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 + */ + static public function getAbbreviations($names) + { + $abbrevs = array(); + foreach ($names as $name) { + for ($len = strlen($name) - 1; $len > 0; --$len) { + $abbrev = substr($name, 0, $len); + if (!isset($abbrevs[$abbrev])) { + $abbrevs[$abbrev] = array($name); + } else { + $abbrevs[$abbrev][] = $name; + } + } + } + + // Non-abbreviations always get entered, even if they aren't unique + foreach ($names as $name) { + $abbrevs[$name] = array($name); + } + + return $abbrevs; + } + + /** + * Returns a text representation of the Application. + * + * @param string $namespace An optional namespace name + * @param boolean $raw Whether to return raw command list + * + * @return string A string representing the Application + */ + public function asText($namespace = null, $raw = false) + { + $commands = $namespace ? $this->all($this->findNamespace($namespace)) : $this->commands; + + $width = 0; + foreach ($commands as $command) { + $width = strlen($command->getName()) > $width ? strlen($command->getName()) : $width; + } + $width += 2; + + if ($raw) { + $messages = array(); + foreach ($this->sortCommands($commands) as $space => $commands) { + foreach ($commands as $name => $command) { + $messages[] = sprintf("%-${width}s %s", $name, $command->getDescription()); + } + } + + return implode(PHP_EOL, $messages); + } + + $messages = array($this->getHelp(), ''); + if ($namespace) { + $messages[] = sprintf("Available commands for the \"%s\" namespace:", $namespace); + } else { + $messages[] = 'Available commands:'; + } + + // add commands by namespace + foreach ($this->sortCommands($commands) as $space => $commands) { + if (!$namespace && '_global' !== $space) { + $messages[] = ''.$space.''; + } + + foreach ($commands as $name => $command) { + $messages[] = sprintf(" %-${width}s %s", $name, $command->getDescription()); + } + } + + return implode(PHP_EOL, $messages); + } + + /** + * Returns an XML representation of the Application. + * + * @param string $namespace An optional namespace name + * @param Boolean $asDom Whether to return a DOM or an XML string + * + * @return string|DOMDocument An XML string representing the Application + */ + public function asXml($namespace = null, $asDom = false) + { + $commands = $namespace ? $this->all($this->findNamespace($namespace)) : $this->commands; + + $dom = new \DOMDocument('1.0', 'UTF-8'); + $dom->formatOutput = true; + $dom->appendChild($xml = $dom->createElement('symfony')); + + $xml->appendChild($commandsXML = $dom->createElement('commands')); + + if ($namespace) { + $commandsXML->setAttribute('namespace', $namespace); + } else { + $namespacesXML = $dom->createElement('namespaces'); + $xml->appendChild($namespacesXML); + } + + // add commands by namespace + foreach ($this->sortCommands($commands) as $space => $commands) { + if (!$namespace) { + $namespaceArrayXML = $dom->createElement('namespace'); + $namespacesXML->appendChild($namespaceArrayXML); + $namespaceArrayXML->setAttribute('id', $space); + } + + foreach ($commands as $name => $command) { + if ($name !== $command->getName()) { + continue; + } + + if (!$namespace) { + $commandXML = $dom->createElement('command'); + $namespaceArrayXML->appendChild($commandXML); + $commandXML->appendChild($dom->createTextNode($name)); + } + + $node = $command->asXml(true)->getElementsByTagName('command')->item(0); + $node = $dom->importNode($node, true); + + $commandsXML->appendChild($node); + } + } + + return $asDom ? $dom : $dom->saveXml(); + } + + /** + * Renders a caught exception. + * + * @param Exception $e An exception instance + * @param OutputInterface $output An OutputInterface instance + */ + public function renderException($e, $output) + { + $strlen = function ($string) { + if (!function_exists('mb_strlen')) { + return strlen($string); + } + + if (false === $encoding = mb_detect_encoding($string)) { + return strlen($string); + } + + return mb_strlen($string, $encoding); + }; + + do { + $title = sprintf(' [%s] ', get_class($e)); + $len = $strlen($title); + $width = $this->getTerminalWidth() ? $this->getTerminalWidth() - 1 : PHP_INT_MAX; + $lines = array(); + foreach (preg_split("{\r?\n}", $e->getMessage()) as $line) { + foreach (str_split($line, $width - 4) as $line) { + $lines[] = sprintf(' %s ', $line); + $len = max($strlen($line) + 4, $len); + } + } + + $messages = array(str_repeat(' ', $len), $title.str_repeat(' ', max(0, $len - $strlen($title)))); + + foreach ($lines as $line) { + $messages[] = $line.str_repeat(' ', $len - $strlen($line)); + } + + $messages[] = str_repeat(' ', $len); + + $output->writeln(""); + $output->writeln(""); + foreach ($messages as $message) { + $output->writeln(''.$message.''); + } + $output->writeln(""); + $output->writeln(""); + + 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() + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + if ($ansicon = getenv('ANSICON')) { + return preg_replace('{^(\d+)x.*$}', '$1', $ansicon); + } + + exec('mode CON', $execData); + if (preg_match('{columns:\s*(\d+)}i', $execData[4], $matches)) { + return $matches[1]; + } + } + + if (preg_match("{rows.(\d+);.columns.(\d+);}i", $this->getSttyColumns(), $match)) { + return $match[2]; + } + } + + /** + * Tries to figure out the terminal height in which this application runs + * + * @return int|null + */ + protected function getTerminalHeight() + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + if ($ansicon = getenv('ANSICON')) { + return preg_replace('{^\d+x\d+ \(\d+x(\d+)\)$}', '$1', trim($ansicon)); + } + + exec('mode CON', $execData); + if (preg_match('{lines:\s*(\d+)}i', $execData[3], $matches)) { + return $matches[1]; + } + } + + if (preg_match("{rows.(\d+);.columns.(\d+);}i", $this->getSttyColumns(), $match)) { + return $match[1]; + } + } + + /** + * 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('command'); + } + + /** + * 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', InputOption::VALUE_NONE, 'Increase verbosity of messages.'), + 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 array 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(), + )); + } + + /** + * 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; + } + } + + /** + * Sorts commands in alphabetical order. + * + * @param array $commands An associative array of commands to sort + * + * @return array A sorted array of commands + */ + private function sortCommands($commands) + { + $namespacedCommands = array(); + foreach ($commands as $name => $command) { + $key = $this->extractNamespace($name, 1); + if (!$key) { + $key = '_global'; + } + + $namespacedCommands[$key][$name] = $command; + } + ksort($namespacedCommands); + + foreach ($namespacedCommands as &$commands) { + ksort($commands); + } + + return $namespacedCommands; + } + + /** + * 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. + * + * @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 + */ + private function extractNamespace($name, $limit = null) + { + $parts = explode(':', $name); + array_pop($parts); + + return implode(':', null === $limit ? $parts : array_slice($parts, 0, $limit)); + } + + /** + * Finds alternative commands of $name + * + * @param string $name The full name of the command + * @param array $abbrevs The abbreviations + * + * @return array A sorted array of similar commands + */ + private function findAlternativeCommands($name, $abbrevs) + { + $callback = function($item) { + return $item->getName(); + }; + + return $this->findAlternatives($name, $this->commands, $abbrevs, $callback); + } + + /** + * Finds alternative namespace of $name + * + * @param string $name The full name of the namespace + * @param array $abbrevs The abbreviations + * + * @return array A sorted array of similar namespace + */ + private function findAlternativeNamespace($name, $abbrevs) + { + return $this->findAlternatives($name, $this->getNamespaces(), $abbrevs); + } + + /** + * 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 collecion + * @param array $abbrevs The abbreviations + * @param Closure|string|array $callback The callable to transform collection item before comparison + * + * @return array A sorted array of similar string + */ + private function findAlternatives($name, $collection, $abbrevs, $callback = null) + { + $alternatives = array(); + + foreach ($collection as $item) { + if (null !== $callback) { + $item = call_user_func($callback, $item); + } + + $lev = levenshtein($name, $item); + if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) { + $alternatives[$item] = $lev; + } + } + + if (!$alternatives) { + foreach ($abbrevs as $key => $values) { + $lev = levenshtein($name, $key); + if ($lev <= strlen($name) / 3 || false !== strpos($key, $name)) { + foreach ($values as $value) { + $alternatives[$value] = $lev; + } + } + } + } + + asort($alternatives); + + return array_keys($alternatives); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/CHANGELOG.md b/vendor/symfony/symfony/src/Symfony/Component/Console/CHANGELOG.md new file mode 100644 index 0000000..79449d8 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/CHANGELOG.md @@ -0,0 +1,19 @@ +CHANGELOG +========= + +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/symfony/src/Symfony/Component/Console/Command/Command.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php new file mode 100644 index 0000000..001e364 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php @@ -0,0 +1,614 @@ + + * + * 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\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\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 $aliases; + private $definition; + private $help; + private $description; + private $ignoreValidationErrors; + private $applicationDefinitionMerged; + private $code; + private $synopsis; + private $helperSet; + + /** + * Constructor. + * + * @param string $name The name of the command + * + * @throws \LogicException When the command name is empty + * + * @api + */ + public function __construct($name = null) + { + $this->definition = new InputDefinition(); + $this->ignoreValidationErrors = false; + $this->applicationDefinitionMerged = false; + $this->aliases = array(); + + if (null !== $name) { + $this->setName($name); + } + + $this->configure(); + + if (!$this->name) { + throw new \LogicException('The command name cannot be empty.'); + } + } + + /** + * 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 Boolean + */ + 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 integer 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. + * + * @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 integer The command exit code + * + * @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 ($input->isInteractive()) { + $this->interact($input, $output); + } + + $input->validate(); + + if ($this->code) { + return call_user_func($this->code, $input, $output); + } + + return $this->execute($input, $output); + } + + /** + * Sets the code to execute when running this command. + * + * If this method is used, it overrides the code defined + * in the execute() method. + * + * @param \Closure $code A \Closure + * + * @return Command The current instance + * + * @see execute() + * + * @api + */ + public function setCode(\Closure $code) + { + $this->code = $code; + + return $this; + } + + /** + * Merges the application definition with the command definition. + */ + private function mergeApplicationDefinition() + { + if (null === $this->application || true === $this->applicationDefinitionMerged) { + return; + } + + $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; + } + + /** + * 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. + * + * @return InputDefinition An InputDefinition instance + */ + protected function getNativeDefinition() + { + return $this->getDefinition(); + } + + /** + * Adds an argument. + * + * @param string $name The argument name + * @param integer $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 integer $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 command name given is empty + * + * @api + */ + public function setName($name) + { + $this->validateName($name); + + $this->name = $name; + + 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 array $aliases An array of aliases for the command + * + * @return Command The current instance + * + * @api + */ + public function setAliases($aliases) + { + 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 + */ + public function asText() + { + $messages = array( + 'Usage:', + ' '.$this->getSynopsis(), + '', + ); + + if ($this->getAliases()) { + $messages[] = 'Aliases: '.implode(', ', $this->getAliases()).''; + } + + $messages[] = $this->getNativeDefinition()->asText(); + + if ($help = $this->getProcessedHelp()) { + $messages[] = 'Help:'; + $messages[] = ' '.str_replace("\n", "\n ", $help)."\n"; + } + + return implode("\n", $messages); + } + + /** + * Returns an XML representation of the command. + * + * @param Boolean $asDom Whether to return a DOM or an XML string + * + * @return string|DOMDocument An XML string representing the command + */ + public function asXml($asDom = false) + { + $dom = new \DOMDocument('1.0', 'UTF-8'); + $dom->formatOutput = true; + $dom->appendChild($commandXML = $dom->createElement('command')); + $commandXML->setAttribute('id', $this->name); + $commandXML->setAttribute('name', $this->name); + + $commandXML->appendChild($usageXML = $dom->createElement('usage')); + $usageXML->appendChild($dom->createTextNode(sprintf($this->getSynopsis(), ''))); + + $commandXML->appendChild($descriptionXML = $dom->createElement('description')); + $descriptionXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $this->getDescription()))); + + $commandXML->appendChild($helpXML = $dom->createElement('help')); + $helpXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $this->getProcessedHelp()))); + + $commandXML->appendChild($aliasesXML = $dom->createElement('aliases')); + foreach ($this->getAliases() as $alias) { + $aliasesXML->appendChild($aliasXML = $dom->createElement('alias')); + $aliasXML->appendChild($dom->createTextNode($alias)); + } + + $definition = $this->getNativeDefinition()->asXml(true); + $commandXML->appendChild($dom->importNode($definition->getElementsByTagName('arguments')->item(0), true)); + $commandXML->appendChild($dom->importNode($definition->getElementsByTagName('options')->item(0), true)); + + return $asDom ? $dom : $dom->saveXml(); + } + + private function validateName($name) + { + if (!preg_match('/^[^\:]+(\:[^\:]+)*$/', $name)) { + throw new \InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name)); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Command/HelpCommand.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Command/HelpCommand.php new file mode 100644 index 0000000..93c8104 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Command/HelpCommand.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\Command; + +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\Output\Output; +use Symfony\Component\Console\Command\Command; + +/** + * 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'), + )) + ->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 as XML by using the --xml option: + + php %command.full_name% --xml list +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()->get($input->getArgument('command_name')); + } + + if ($input->getOption('xml')) { + $output->writeln($this->command->asXml(), OutputInterface::OUTPUT_RAW); + } else { + $output->writeln($this->command->asText()); + } + + $this->command = null; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Command/ListCommand.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Command/ListCommand.php new file mode 100644 index 0000000..032de16 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Command/ListCommand.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\Console\Command; + +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\Output\Output; +use Symfony\Component\Console\Command\Command; +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 as XML by using the --xml option: + + php %command.full_name% --xml + +It's also possible to get raw list of commands (useful for embedding command runner): + + php %command.full_name% --raw +EOF + ) + ; + } + + /** + * {@inheritdoc} + */ + protected function getNativeDefinition() + { + return $this->createDefinition(); + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + if ($input->getOption('xml')) { + $output->writeln($this->getApplication()->asXml($input->getArgument('namespace')), OutputInterface::OUTPUT_RAW); + } else { + $output->writeln($this->getApplication()->asText($input->getArgument('namespace'), $input->getOption('raw'))); + } + } + + private function createDefinition() + { + return new InputDefinition(array( + new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'), + new InputOption('xml', null, InputOption::VALUE_NONE, 'To output help as XML'), + new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list'), + )); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Formatter/OutputFormatter.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Formatter/OutputFormatter.php new file mode 100644 index 0000000..62e0754 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Formatter/OutputFormatter.php @@ -0,0 +1,230 @@ + + * + * 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 +{ + /** + * The pattern to phrase the format. + */ + const FORMAT_PATTERN = '#<(/?)([a-z][a-z0-9_=;-]+)?>([^<]*)#is'; + + private $decorated; + private $styles = array(); + private $styleStack; + + /** + * Initializes console output formatter. + * + * @param Boolean $decorated Whether this formatter should actually decorate strings + * @param array $styles Array of "name => FormatterStyle" instances + * + * @api + */ + public function __construct($decorated = null, array $styles = array()) + { + $this->decorated = (Boolean) $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 Boolean $decorated Whether to decorate the messages or not + * + * @api + */ + public function setDecorated($decorated) + { + $this->decorated = (Boolean) $decorated; + } + + /** + * Gets the decorated flag. + * + * @return Boolean 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 Boolean + * + * @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('Undefined style: '.$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) + { + return preg_replace_callback(self::FORMAT_PATTERN, array($this, 'replaceStyle'), $message); + } + + /** + * @return OutputFormatterStyleStack + */ + public function getStyleStack() + { + return $this->styleStack; + } + + /** + * Replaces style of the output. + * + * @param array $match + * + * @return string The replaced style + */ + private function replaceStyle($match) + { + if ('' === $match[2]) { + if ('/' === $match[1]) { + // we got "" tag + $this->styleStack->pop(); + + return $this->applyStyle($this->styleStack->getCurrent(), $match[3]); + } + + // we got "<>" tag + return '<>'.$match[3]; + } + + if (isset($this->styles[strtolower($match[2])])) { + $style = $this->styles[strtolower($match[2])]; + } else { + $style = $this->createStyleFromString($match[2]); + + if (false === $style) { + return $match[0]; + } + } + + if ('/' === $match[1]) { + $this->styleStack->pop($style); + } else { + $this->styleStack->push($style); + } + + return $this->applyStyle($this->styleStack->getCurrent(), $match[3]); + } + + /** + * Tries to create new style instance from string. + * + * @param string $string + * + * @return OutputFormatterStyle|Boolean false if string is not format string + */ + private function createStyleFromString($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 { + $style->setOption($match[1]); + } + } + + return $style; + } + + /** + * Applies style to text if must be applied. + * + * @param OutputFormatterStyleInterface $style Style to apply + * @param string $text Input text + * + * @return string string Styled text + */ + private function applyStyle(OutputFormatterStyleInterface $style, $text) + { + return $this->isDecorated() && strlen($text) > 0 ? $style->apply($text) : $text; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Formatter/OutputFormatterInterface.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Formatter/OutputFormatterInterface.php new file mode 100644 index 0000000..ca9f9d0 --- /dev/null +++ b/vendor/symfony/symfony/src/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 Boolean $decorated Whether to decorate the messages or not + * + * @api + */ + function setDecorated($decorated); + + /** + * Gets the decorated flag. + * + * @return Boolean true if the output will decorate messages, false otherwise + * + * @api + */ + function isDecorated(); + + /** + * Sets a new style. + * + * @param string $name The style name + * @param OutputFormatterStyleInterface $style The style instance + * + * @api + */ + function setStyle($name, OutputFormatterStyleInterface $style); + + /** + * Checks if output formatter has style with specified name. + * + * @param string $name + * + * @return Boolean + * + * @api + */ + function hasStyle($name); + + /** + * Gets style options from style with specified name. + * + * @param string $name + * + * @return OutputFormatterStyleInterface + * + * @api + */ + function getStyle($name); + + /** + * Formats a message according to the given styles. + * + * @param string $message The message to style + * + * @return string The styled message + * + * @api + */ + function format($message); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Formatter/OutputFormatterStyle.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Formatter/OutputFormatterStyle.php new file mode 100644 index 0000000..ad02b94 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Formatter/OutputFormatterStyle.php @@ -0,0 +1,218 @@ + + * + * 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 +{ + static private $availableForegroundColors = array( + 'black' => 30, + 'red' => 31, + 'green' => 32, + 'yellow' => 33, + 'blue' => 34, + 'magenta' => 35, + 'cyan' => 36, + 'white' => 37 + ); + static private $availableBackgroundColors = array( + 'black' => 40, + 'red' => 41, + 'green' => 42, + 'yellow' => 43, + 'blue' => 44, + 'magenta' => 45, + 'cyan' => 46, + 'white' => 47 + ); + static private $availableOptions = array( + 'bold' => 1, + 'underscore' => 4, + 'blink' => 5, + 'reverse' => 7, + 'conceal' => 8 + ); + + private $foreground; + private $background; + private $options = array(); + + /** + * Initializes output formatter style. + * + * @param string $foreground The style foreground color name + * @param string $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 $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 $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 (false === array_search(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) + { + $codes = array(); + + if (null !== $this->foreground) { + $codes[] = $this->foreground; + } + if (null !== $this->background) { + $codes[] = $this->background; + } + if (count($this->options)) { + $codes = array_merge($codes, $this->options); + } + + return sprintf("\033[%sm%s\033[0m", implode(';', $codes), $text); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Formatter/OutputFormatterStyleInterface.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Formatter/OutputFormatterStyleInterface.php new file mode 100644 index 0000000..3d84d96 --- /dev/null +++ b/vendor/symfony/symfony/src/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 + */ + function setForeground($color = null); + + /** + * Sets style background color. + * + * @param string $color The color name + * + * @api + */ + function setBackground($color = null); + + /** + * Sets some specific style option. + * + * @param string $option The option name + * + * @api + */ + function setOption($option); + + /** + * Unsets some specific style option. + * + * @param string $option Theoption name + */ + function unsetOption($option); + + /** + * Sets multiple style options at once. + * + * @param array $options + */ + function setOptions(array $options); + + /** + * Applies the style to a given text. + * + * @param string $text The text to style + * + * @return string + */ + function apply($text); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Formatter/OutputFormatterStyleStack.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Formatter/OutputFormatterStyleStack.php new file mode 100644 index 0000000..5915023 --- /dev/null +++ b/vendor/symfony/symfony/src/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 $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 $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/symfony/src/Symfony/Component/Console/Helper/DialogHelper.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Helper/DialogHelper.php new file mode 100644 index 0000000..03daf8c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Helper/DialogHelper.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\Helper; + +use Symfony\Component\Console\Output\OutputInterface; + +/** + * The Dialog class provides helpers to interact with the user. + * + * @author Fabien Potencier + */ +class DialogHelper extends Helper +{ + private $inputStream; + + /** + * 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 + * + * @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) + { + $output->write($question); + + $ret = fgets($this->inputStream ?: STDIN, 4096); + if (false === $ret) { + throw new \RuntimeException('Aborted'); + } + $ret = trim($ret); + + 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 Boolean $default The default answer if the user enters nothing + * + * @return Boolean 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 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 callback $validator A PHP callback + * @param integer $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 + * + * @return mixed + * + * @throws \Exception When any of the validators return an error + */ + public function askAndValidate(OutputInterface $output, $question, $validator, $attempts = false, $default = null) + { + $error = null; + while (false === $attempts || $attempts--) { + if (null !== $error) { + $output->writeln($this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error')); + } + + $value = $this->ask($output, $question, $default); + + try { + return call_user_func($validator, $value); + } catch (\Exception $error) { + } + } + + throw $error; + } + + /** + * 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; + } + + /** + * Returns the helper's canonical name. + * + * @return string The helper name + */ + public function getName() + { + return 'dialog'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Helper/FormatterHelper.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Helper/FormatterHelper.php new file mode 100644 index 0000000..dd9615b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Helper/FormatterHelper.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\Helper; + +/** + * 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 Boolean $large Whether to return a large block + * + * @return string The formatter message + */ + public function formatBlock($messages, $style, $large = false) + { + $messages = (array) $messages; + + $len = 0; + $lines = array(); + foreach ($messages as $message) { + $lines[] = sprintf($large ? ' %s ' : ' %s ', $message); + $len = max($this->strlen($message) + ($large ? 4 : 2), $len); + } + + $messages = $large ? array(str_repeat(' ', $len)) : array(); + foreach ($lines as $line) { + $messages[] = $line.str_repeat(' ', $len - $this->strlen($line)); + } + if ($large) { + $messages[] = str_repeat(' ', $len); + } + + foreach ($messages as &$message) { + $message = sprintf('<%s>%s', $style, $message, $style); + } + + return implode("\n", $messages); + } + + /** + * Returns the length of a string, using mb_strlen if it is available. + * + * @param string $string The string to check its length + * + * @return integer The length of the string + */ + private function strlen($string) + { + if (!function_exists('mb_strlen')) { + return strlen($string); + } + + if (false === $encoding = mb_detect_encoding($string)) { + return strlen($string); + } + + return mb_strlen($string, $encoding); + } + + /** + * Returns the helper's canonical name. + * + * @return string The canonical name of the helper + */ + public function getName() + { + return 'formatter'; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Helper/Helper.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Helper/Helper.php new file mode 100644 index 0000000..28488ca --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Helper/Helper.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\Console\Helper; + +/** + * 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; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Helper/HelperInterface.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Helper/HelperInterface.php new file mode 100644 index 0000000..25ee513 --- /dev/null +++ b/vendor/symfony/symfony/src/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 + */ + function setHelperSet(HelperSet $helperSet = null); + + /** + * Gets the helper set associated with this helper. + * + * @return HelperSet A HelperSet instance + * + * @api + */ + function getHelperSet(); + + /** + * Returns the canonical name of this helper. + * + * @return string The canonical name + * + * @api + */ + function getName(); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Helper/HelperSet.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Helper/HelperSet.php new file mode 100644 index 0000000..d95c9a3 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Helper/HelperSet.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\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 +{ + private $helpers; + private $command; + + /** + * Constructor. + * + * @param Helper[] $helpers An array of helper. + */ + public function __construct(array $helpers = array()) + { + $this->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 Boolean 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; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php new file mode 100644 index 0000000..3ca9b05 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php @@ -0,0 +1,313 @@ + + * + * 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]) { + $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(), true); + } + } + } + + /** + * 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); + + if (null === $value && $option->acceptValue()) { + // if option accepts an optional or mandatory argument + // let's see if there is one provided + $next = array_shift($this->parsed); + if ('-' !== $next[0]) { + $value = $next; + } else { + array_unshift($this->parsed, $next); + } + } + + if (null === $value) { + if ($option->isValueRequired()) { + throw new \RuntimeException(sprintf('The "--%s" option requires a value.', $name)); + } + + $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 Boolean true if the value is contained in the raw parameters + */ + public function hasParameterOption($values) + { + $values = (array) $values; + + foreach ($this->tokens as $v) { + 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; + + $tokens = $this->tokens; + while ($token = array_shift($tokens)) { + foreach ($values as $value) { + if (0 === strpos($token, $value)) { + if (false !== $pos = strpos($token, '=')) { + return substr($token, $pos + 1); + } + + return array_shift($tokens); + } + } + } + + return $default; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArrayInput.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArrayInput.php new file mode 100644 index 0000000..9921fff --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArrayInput.php @@ -0,0 +1,190 @@ + + * + * 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 Boolean 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) && in_array($v, $values)) { + return true; + } elseif (in_array($k, $values)) { + return $v; + } + } + + return $default; + } + + /** + * 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/symfony/src/Symfony/Component/Console/Input/Input.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Input/Input.php new file mode 100644 index 0000000..70291be --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Input/Input.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; + +/** + * 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 +{ + protected $definition; + protected $options; + protected $arguments; + 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 Boolean Returns true if the input is interactive + */ + public function isInteractive() + { + return $this->interactive; + } + + /** + * Sets the input interactivity. + * + * @param Boolean $interactive If the input should be interactive + */ + public function setInteractive($interactive) + { + $this->interactive = (Boolean) $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|integer $name The InputArgument name or position + * + * @return Boolean 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 $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 Boolean true if the InputOption object exists, false otherwise + */ + public function hasOption($name) + { + return $this->definition->hasOption($name); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Input/InputArgument.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Input/InputArgument.php new file mode 100644 index 0000000..e7cc935 --- /dev/null +++ b/vendor/symfony/symfony/src/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 integer $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 Boolean 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 Boolean 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 Parameter::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/symfony/src/Symfony/Component/Console/Input/InputDefinition.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Input/InputDefinition.php new file mode 100644 index 0000000..9551e96 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Input/InputDefinition.php @@ -0,0 +1,535 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Input; + +/** + * 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 array $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|integer $name The InputArgument name or position + * + * @return InputArgument An InputArgument object + * + * @throws \InvalidArgumentException When argument given doesn't exist + * + * @api + */ + public function getArgument($name) + { + $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments; + + if (!$this->hasArgument($name)) { + throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); + } + + return $arguments[$name]; + } + + /** + * Returns true if an InputArgument object exists by name or position. + * + * @param string|integer $name The InputArgument name or position + * + * @return Boolean 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 array An array of InputArgument objects + * + * @api + */ + public function getArguments() + { + return $this->arguments; + } + + /** + * Returns the number of InputArguments. + * + * @return integer The number of InputArguments + */ + public function getArgumentCount() + { + return $this->hasAnArrayArgument ? PHP_INT_MAX : count($this->arguments); + } + + /** + * Returns the number of required InputArguments. + * + * @return integer 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 array $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())); + } elseif (isset($this->shortcuts[$option->getShortcut()]) && !$option->equals($this->options[$this->shortcuts[$option->getShortcut()]])) { + throw new \LogicException(sprintf('An option with shortcut "%s" already exists.', $option->getShortcut())); + } + + $this->options[$option->getName()] = $option; + if ($option->getShortcut()) { + $this->shortcuts[$option->getShortcut()] = $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 Boolean 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 array 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 Boolean 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 + */ + public function asText() + { + // find the largest option or argument name + $max = 0; + foreach ($this->getOptions() as $option) { + $nameLength = strlen($option->getName()) + 2; + if ($option->getShortcut()) { + $nameLength += strlen($option->getShortcut()) + 3; + } + + $max = max($max, $nameLength); + } + foreach ($this->getArguments() as $argument) { + $max = max($max, strlen($argument->getName())); + } + ++$max; + + $text = array(); + + if ($this->getArguments()) { + $text[] = 'Arguments:'; + foreach ($this->getArguments() as $argument) { + if (null !== $argument->getDefault() && (!is_array($argument->getDefault()) || count($argument->getDefault()))) { + $default = sprintf(' (default: %s)', $this->formatDefaultValue($argument->getDefault())); + } else { + $default = ''; + } + + $description = str_replace("\n", "\n".str_pad('', $max + 2, ' '), $argument->getDescription()); + + $text[] = sprintf(" %-${max}s %s%s", $argument->getName(), $description, $default); + } + + $text[] = ''; + } + + if ($this->getOptions()) { + $text[] = 'Options:'; + + foreach ($this->getOptions() as $option) { + if ($option->acceptValue() && null !== $option->getDefault() && (!is_array($option->getDefault()) || count($option->getDefault()))) { + $default = sprintf(' (default: %s)', $this->formatDefaultValue($option->getDefault())); + } else { + $default = ''; + } + + $multiple = $option->isArray() ? ' (multiple values allowed)' : ''; + $description = str_replace("\n", "\n".str_pad('', $max + 2, ' '), $option->getDescription()); + + $optionMax = $max - strlen($option->getName()) - 2; + $text[] = sprintf(" %s %-${optionMax}s%s%s%s", + '--'.$option->getName(), + $option->getShortcut() ? sprintf('(-%s) ', $option->getShortcut()) : '', + $description, + $default, + $multiple + ); + } + + $text[] = ''; + } + + return implode("\n", $text); + } + + /** + * Returns an XML representation of the InputDefinition. + * + * @param Boolean $asDom Whether to return a DOM or an XML string + * + * @return string|DOMDocument An XML string representing the InputDefinition + */ + public function asXml($asDom = false) + { + $dom = new \DOMDocument('1.0', 'UTF-8'); + $dom->formatOutput = true; + $dom->appendChild($definitionXML = $dom->createElement('definition')); + + $definitionXML->appendChild($argumentsXML = $dom->createElement('arguments')); + foreach ($this->getArguments() as $argument) { + $argumentsXML->appendChild($argumentXML = $dom->createElement('argument')); + $argumentXML->setAttribute('name', $argument->getName()); + $argumentXML->setAttribute('is_required', $argument->isRequired() ? 1 : 0); + $argumentXML->setAttribute('is_array', $argument->isArray() ? 1 : 0); + $argumentXML->appendChild($descriptionXML = $dom->createElement('description')); + $descriptionXML->appendChild($dom->createTextNode($argument->getDescription())); + + $argumentXML->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)); + } + } + + $definitionXML->appendChild($optionsXML = $dom->createElement('options')); + foreach ($this->getOptions() as $option) { + $optionsXML->appendChild($optionXML = $dom->createElement('option')); + $optionXML->setAttribute('name', '--'.$option->getName()); + $optionXML->setAttribute('shortcut', $option->getShortcut() ? '-'.$option->getShortcut() : ''); + $optionXML->setAttribute('accept_value', $option->acceptValue() ? 1 : 0); + $optionXML->setAttribute('is_value_required', $option->isValueRequired() ? 1 : 0); + $optionXML->setAttribute('is_multiple', $option->isArray() ? 1 : 0); + $optionXML->appendChild($descriptionXML = $dom->createElement('description')); + $descriptionXML->appendChild($dom->createTextNode($option->getDescription())); + + if ($option->acceptValue()) { + $optionXML->appendChild($defaultsXML = $dom->createElement('defaults')); + $defaults = is_array($option->getDefault()) ? $option->getDefault() : (is_bool($option->getDefault()) ? array(var_export($option->getDefault(), true)) : ($option->getDefault() ? array($option->getDefault()) : array())); + foreach ($defaults as $default) { + $defaultsXML->appendChild($defaultXML = $dom->createElement('default')); + $defaultXML->appendChild($dom->createTextNode($default)); + } + } + } + + return $asDom ? $dom : $dom->saveXml(); + } + + private function formatDefaultValue($default) + { + if (is_array($default) && $default === array_values($default)) { + return sprintf("array('%s')", implode("', '", $default)); + } + + return str_replace("\n", '', var_export($default, true)); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Input/InputInterface.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Input/InputInterface.php new file mode 100644 index 0000000..8a3d519 --- /dev/null +++ b/vendor/symfony/symfony/src/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 + */ + 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 Boolean true if the value is contained in the raw parameters + */ + 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 + */ + function getParameterOption($values, $default = false); + + /** + * Binds the current Input instance with the given arguments and options. + * + * @param InputDefinition $definition A InputDefinition instance + */ + function bind(InputDefinition $definition); + + /** + * Validates if arguments given are correct. + * + * Throws an exception when not enough arguments are given. + * + * @throws \RuntimeException + */ + function validate(); + + /** + * Returns all the given arguments merged with the default values. + * + * @return array + */ + function getArguments(); + + /** + * Gets argument by name. + * + * @param string $name The name of the argument + * + * @return mixed + */ + 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 + */ + function setArgument($name, $value); + + /** + * Returns true if an InputArgument object exists by name or position. + * + * @param string|integer $name The InputArgument name or position + * + * @return Boolean true if the InputArgument object exists, false otherwise + */ + function hasArgument($name); + + /** + * Returns all the given options merged with the default values. + * + * @return array + */ + function getOptions(); + + /** + * Gets an option by name. + * + * @param string $name The name of the option + * + * @return mixed + */ + function getOption($name); + + /** + * Sets an option value by name. + * + * @param string $name The option name + * @param string $value The option value + * + * @throws \InvalidArgumentException When option given doesn't exist + */ + function setOption($name, $value); + + /** + * Returns true if an InputOption object exists by name. + * + * @param string $name The InputOption name + * + * @return Boolean true if the InputOption object exists, false otherwise + */ + function hasOption($name); + + /** + * Is this input means interactive? + * + * @return Boolean + */ + function isInteractive(); + + /** + * Sets the input interactivity. + * + * @param Boolean $interactive If the input should be interactive + */ + function setInteractive($interactive); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Input/InputOption.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Input/InputOption.php new file mode 100644 index 0000000..e194b32 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Input/InputOption.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\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 $shortcut The shortcut (can be null) + * @param integer $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 ('-' === $shortcut[0]) { + $shortcut = substr($shortcut, 1); + } + + 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 Boolean 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 Boolean 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 Boolean 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 Boolean 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 Option::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 Boolean + */ + 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/symfony/src/Symfony/Component/Console/Input/StringInput.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Input/StringInput.php new file mode 100644 index 0000000..93b1b83 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Input/StringInput.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\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 = '([^ ]+?)(?: |(?setTokens($this->tokenize($input)); + } + + /** + * 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) + { + $input = preg_replace('/(\r\n|\r|\n|\t)/', ' ', $input); + + $tokens = array(); + $length = strlen($input); + $cursor = 0; + while ($cursor < $length) { + if (preg_match('/\s+/A', $input, $match, null, $cursor)) { + } elseif (preg_match('/([^="\' ]+?)(=?)('.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 + // @codeCoverageIgnoreStart + throw new \InvalidArgumentException(sprintf('Unable to parse input near "... %s ..."', substr($input, $cursor, 10))); + // @codeCoverageIgnoreEnd + } + + $cursor += strlen($match[0]); + } + + return $tokens; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/LICENSE b/vendor/symfony/symfony/src/Symfony/Component/Console/LICENSE new file mode 100644 index 0000000..cdffe7a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 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/symfony/src/Symfony/Component/Console/Output/ConsoleOutput.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Output/ConsoleOutput.php new file mode 100644 index 0000000..0b7e083 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Output/ConsoleOutput.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\Console\Output; + +use Symfony\Component\Console\Formatter\OutputFormatter; +use Symfony\Component\Console\Formatter\OutputFormatterInterface; +use Symfony\Component\Console\Output\ConsoleOutputInterface; + +/** + * 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 integer $verbosity The verbosity level (self::VERBOSITY_QUIET, self::VERBOSITY_NORMAL, + * self::VERBOSITY_VERBOSE) + * @param Boolean $decorated Whether to decorate messages or not (null for auto-guessing) + * @param OutputFormatter $formatter Output formatter instance + * + * @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, $formatter); + } + + public function setDecorated($decorated) + { + parent::setDecorated($decorated); + $this->stderr->setDecorated($decorated); + } + + public function setFormatter(OutputFormatterInterface $formatter) + { + parent::setFormatter($formatter); + $this->stderr->setFormatter($formatter); + } + + public function setVerbosity($level) + { + parent::setVerbosity($level); + $this->stderr->setVerbosity($level); + } + + /** + * @return OutputInterface + */ + public function getErrorOutput() + { + return $this->stderr; + } + + 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 boolean + */ + protected function hasStdoutSupport() + { + return ('OS400' != php_uname('s')); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Output/ConsoleOutputInterface.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Output/ConsoleOutputInterface.php new file mode 100644 index 0000000..5006b80 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Output/ConsoleOutputInterface.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\Output; + +use Symfony\Component\Console\Output\OutputInterface; + +/** + * ConsoleOutputInterface is the interface implemented by ConsoleOutput class. + * This adds information about stderr output stream. + * + * @author Dariusz Górecki + */ +interface ConsoleOutputInterface extends OutputInterface +{ + /** + * @return OutputInterface + */ + public function getErrorOutput(); + + public function setErrorOutput(OutputInterface $error); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Output/NullOutput.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Output/NullOutput.php new file mode 100644 index 0000000..783d42b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Output/NullOutput.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\Console\Output; + +/** + * NullOutput suppresses all output. + * + * $output = new NullOutput(); + * + * @author Fabien Potencier + * + * @api + */ +class NullOutput extends Output +{ + /** + * Writes a message to the output. + * + * @param string $message A message to write to the output + * @param Boolean $newline Whether to add a newline or not + */ + protected function doWrite($message, $newline) + { + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Output/Output.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Output/Output.php new file mode 100644 index 0000000..3866dbc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Output/Output.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\Console\Output; + +use Symfony\Component\Console\Formatter\OutputFormatterInterface; +use Symfony\Component\Console\Formatter\OutputFormatter; + +/** + * Base class for output classes. + * + * There are three levels of verbosity: + * + * * normal: no option passed (normal output - information) + * * verbose: -v (more output - debug) + * * quiet: -q (no output) + * + * @author Fabien Potencier + * + * @api + */ +abstract class Output implements OutputInterface +{ + private $verbosity; + private $formatter; + + /** + * Constructor. + * + * @param integer $verbosity The verbosity level (self::VERBOSITY_QUIET, self::VERBOSITY_NORMAL, self::VERBOSITY_VERBOSE) + * @param Boolean $decorated Whether to decorate messages or not (null for auto-guessing) + * @param OutputFormatterInterface $formatter Output formatter instance + * + * @api + */ + public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null) + { + $this->verbosity = null === $verbosity ? self::VERBOSITY_NORMAL : $verbosity; + $this->formatter = null === $formatter ? new OutputFormatter() : $formatter; + $this->formatter->setDecorated((Boolean) $decorated); + } + + /** + * Sets output formatter. + * + * @param OutputFormatterInterface $formatter + * + * @api + */ + public function setFormatter(OutputFormatterInterface $formatter) + { + $this->formatter = $formatter; + } + + /** + * Returns current output formatter instance. + * + * @return OutputFormatterInterface + * + * @api + */ + public function getFormatter() + { + return $this->formatter; + } + + /** + * Sets the decorated flag. + * + * @param Boolean $decorated Whether to decorate the messages or not + * + * @api + */ + public function setDecorated($decorated) + { + $this->formatter->setDecorated((Boolean) $decorated); + } + + /** + * Gets the decorated flag. + * + * @return Boolean true if the output will decorate messages, false otherwise + * + * @api + */ + public function isDecorated() + { + return $this->formatter->isDecorated(); + } + + /** + * Sets the verbosity of the output. + * + * @param integer $level The level of verbosity + * + * @api + */ + public function setVerbosity($level) + { + $this->verbosity = (int) $level; + } + + /** + * Gets the current verbosity of the output. + * + * @return integer The current level of verbosity + * + * @api + */ + public function getVerbosity() + { + return $this->verbosity; + } + + /** + * 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 integer $type The type of output + * + * @api + */ + public function writeln($messages, $type = 0) + { + $this->write($messages, true, $type); + } + + /** + * Writes a message to the output. + * + * @param string|array $messages The message as an array of lines of a single string + * @param Boolean $newline Whether to add a newline or not + * @param integer $type The type of output + * + * @throws \InvalidArgumentException When unknown output type is given + * + * @api + */ + public function write($messages, $newline = false, $type = 0) + { + 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 Boolean $newline Whether to add a newline or not + */ + abstract protected function doWrite($message, $newline); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Output/OutputInterface.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Output/OutputInterface.php new file mode 100644 index 0000000..8423d48 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Output/OutputInterface.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\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 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 of a single string + * @param Boolean $newline Whether to add a newline or not + * @param integer $type The type of output + * + * @throws \InvalidArgumentException When unknown output type is given + * + * @api + */ + function write($messages, $newline = false, $type = 0); + + /** + * 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 integer $type The type of output + * + * @api + */ + function writeln($messages, $type = 0); + + /** + * Sets the verbosity of the output. + * + * @param integer $level The level of verbosity + * + * @api + */ + function setVerbosity($level); + + /** + * Gets the current verbosity of the output. + * + * @return integer The current level of verbosity + * + * @api + */ + function getVerbosity(); + + /** + * Sets the decorated flag. + * + * @param Boolean $decorated Whether to decorate the messages or not + * + * @api + */ + function setDecorated($decorated); + + /** + * Gets the decorated flag. + * + * @return Boolean true if the output will decorate messages, false otherwise + * + * @api + */ + function isDecorated(); + + /** + * Sets output formatter. + * + * @param OutputFormatterInterface $formatter + * + * @api + */ + function setFormatter(OutputFormatterInterface $formatter); + + /** + * Returns current output formatter instance. + * + * @return OutputFormatterInterface + * + * @api + */ + function getFormatter(); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Output/StreamOutput.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Output/StreamOutput.php new file mode 100644 index 0000000..e00d065 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Output/StreamOutput.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; + +/** + * 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 integer $verbosity The verbosity level (self::VERBOSITY_QUIET, self::VERBOSITY_NORMAL, + * self::VERBOSITY_VERBOSE) + * @param Boolean $decorated Whether to decorate messages or not (null for auto-guessing) + * @param OutputFormatter $formatter Output formatter instance + * + * @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($decorated); + } + + parent::__construct($verbosity, $decorated, $formatter); + } + + /** + * Gets the stream attached to this StreamOutput instance. + * + * @return resource A stream resource + */ + public function getStream() + { + return $this->stream; + } + + /** + * Writes a message to the output. + * + * @param string $message A message to write to the output + * @param Boolean $newline Whether to add a newline or not + * + * @throws \RuntimeException When unable to write output (should never happen) + */ + protected function doWrite($message, $newline) + { + if (false === @fwrite($this->stream, $message.($newline ? PHP_EOL : ''))) { + // @codeCoverageIgnoreStart + // should never happen + throw new \RuntimeException('Unable to write output.'); + // @codeCoverageIgnoreEnd + } + + fflush($this->stream); + } + + /** + * Returns true if the stream supports colorization. + * + * Colorization is disabled if not supported by the stream: + * + * - windows without ansicon + * - non tty consoles + * + * @return Boolean true if the stream supports colorization, false otherwise + */ + protected function hasColorSupport() + { + // @codeCoverageIgnoreStart + if (DIRECTORY_SEPARATOR == '\\') { + return false !== getenv('ANSICON'); + } + + return function_exists('posix_isatty') && @posix_isatty($this->stream); + // @codeCoverageIgnoreEnd + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/README.md b/vendor/symfony/symfony/src/Symfony/Component/Console/README.md new file mode 100644 index 0000000..d817952 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/README.md @@ -0,0 +1,55 @@ +Console Component +================= + +Console eases the creation of beautiful and testable command line interfaces. + +The Application object manages the CLI application: + + 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: + + 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: + + phpunit + +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/symfony/src/Symfony/Component/Console/Shell.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Shell.php new file mode 100644 index 0000000..2dc51b6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Shell.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\Console; + +use Symfony\Component\Console\Application; +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 $prompt; + private $processIsolation; + + /** + * 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(); + $this->prompt = $application->getName().' > '; + $this->processIsolation = false; + } + + /** + * 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; + } + + /** + * Tries to return autocompletion for the current entered text. + * + * @param string $text The last segment of the entered text + * + * @return Boolean|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->prompt); + } else { + $this->output->write($this->prompt); + $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 = (Boolean) $processIsolation; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tester/ApplicationTester.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tester/ApplicationTester.php new file mode 100644 index 0000000..2c576aa --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tester/ApplicationTester.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\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. + * + * @author Fabien Potencier + */ +class ApplicationTester +{ + private $application; + private $input; + private $output; + + /** + * 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 integer 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->application->run($this->input, $this->output); + } + + /** + * Gets the display returned by the last execution of the application. + * + * @return string The display + */ + public function getDisplay() + { + rewind($this->output->getStream()); + + return stream_get_contents($this->output->getStream()); + } + + /** + * 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; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tester/CommandTester.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tester/CommandTester.php new file mode 100644 index 0000000..c840574 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tester/CommandTester.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\Console\Tester; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\ArrayInput; +use Symfony\Component\Console\Output\StreamOutput; + +/** + * Eases the testing of console commands. + * + * @author Fabien Potencier + */ +class CommandTester +{ + private $command; + private $input; + private $output; + + /** + * Constructor. + * + * @param Command $command A Command instance to test. + */ + public function __construct(Command $command) + { + $this->command = $command; + } + + /** + * Executes the command. + * + * 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 integer The command exit code + */ + public function execute(array $input, array $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->command->run($this->input, $this->output); + } + + /** + * Gets the display returned by the last execution of the command. + * + * @return string The display + */ + public function getDisplay() + { + rewind($this->output->getStream()); + + return stream_get_contents($this->output->getStream()); + } + + /** + * 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; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/ApplicationTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/ApplicationTest.php new file mode 100644 index 0000000..6fa4cff --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -0,0 +1,470 @@ + + * + * 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\Input\ArrayInput; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\NullOutput; +use Symfony\Component\Console\Output\Output; +use Symfony\Component\Console\Tester\ApplicationTester; + +class ApplicationTest extends \PHPUnit_Framework_TestCase +{ + static protected $fixturesPath; + + static public 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'; + } + + 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 first 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()), '->setHelp() returns a help message'); + } + + public function testAll() + { + $application = new Application(); + $commands = $application->all(); + $this->assertEquals('Symfony\\Component\\Console\\Command\\HelpCommand', get_class($commands['help']), '->all() returns the registered commands'); + + $application->add(new \FooCommand()); + $commands = $application->all('foo'); + $this->assertEquals(1, count($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'); + } + + 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'); + + try { + $application->get('foofoo'); + $this->fail('->get() throws an \InvalidArgumentException if the command does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->get() throws an \InvalidArgumentException if the command does not exist'); + $this->assertEquals('The command "foofoo" does not exist.', $e->getMessage(), '->get() throws an \InvalidArgumentException if the command does not exist'); + } + + $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->assertEquals('Symfony\Component\Console\Command\HelpCommand', get_class($command), '->get() returns the help command if --help is provided as the input'); + } + + 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'); + try { + $application->findNamespace('f'); + $this->fail('->findNamespace() throws an \InvalidArgumentException if the abbreviation is ambiguous'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->findNamespace() throws an \InvalidArgumentException if the abbreviation is ambiguous'); + $this->assertEquals('The namespace "f" is ambiguous (foo, foo1).', $e->getMessage(), '->findNamespace() throws an \InvalidArgumentException if the abbreviation is ambiguous'); + } + + try { + $application->findNamespace('bar'); + $this->fail('->findNamespace() throws an \InvalidArgumentException if no command is in the given namespace'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->findNamespace() throws an \InvalidArgumentException if no command is in the given namespace'); + $this->assertEquals('There are no commands defined in the "bar" namespace.', $e->getMessage(), '->findNamespace() throws an \InvalidArgumentException if no command is in the given namespace'); + } + } + + public function testFind() + { + $application = new Application(); + $application->add(new \FooCommand()); + $this->assertEquals('FooCommand', get_class($application->find('foo:bar')), '->find() returns a command if its name exists'); + $this->assertEquals('Symfony\Component\Console\Command\HelpCommand', get_class($application->find('h')), '->find() returns a command if its name exists'); + $this->assertEquals('FooCommand', get_class($application->find('f:bar')), '->find() returns a command if the abbreviation for the namespace exists'); + $this->assertEquals('FooCommand', get_class($application->find('f:b')), '->find() returns a command if the abbreviation for the namespace and the command name exist'); + $this->assertEquals('FooCommand', get_class($application->find('a')), '->find() returns a command if the abbreviation exists for an alias'); + + $application->add(new \Foo1Command()); + $application->add(new \Foo2Command()); + + try { + $application->find('f'); + $this->fail('->find() throws an \InvalidArgumentException if the abbreviation is ambiguous for a namespace'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if the abbreviation is ambiguous for a namespace'); + $this->assertRegExp('/Command "f" is not defined./', $e->getMessage(), '->find() throws an \InvalidArgumentException if the abbreviation is ambiguous for a namespace'); + } + + try { + $application->find('a'); + $this->fail('->find() throws an \InvalidArgumentException if the abbreviation is ambiguous for an alias'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if the abbreviation is ambiguous for an alias'); + $this->assertEquals('Command "a" is ambiguous (afoobar, afoobar1 and 1 more).', $e->getMessage(), '->find() throws an \InvalidArgumentException if the abbreviation is ambiguous for an alias'); + } + + try { + $application->find('foo:b'); + $this->fail('->find() throws an \InvalidArgumentException if the abbreviation is ambiguous for a command'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if the abbreviation is ambiguous for a command'); + $this->assertEquals('Command "foo:b" is ambiguous (foo:bar, foo:bar1).', $e->getMessage(), '->find() throws an \InvalidArgumentException if the abbreviation is ambiguous for a command'); + } + } + + public function testFindAlternativeCommands() + { + $application = new Application(); + + $application->add(new \FooCommand()); + $application->add(new \Foo1Command()); + $application->add(new \Foo2Command()); + + try { + $application->find($commandName = 'Unknow 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'); + } + + try { + $application->find($commandName = 'foo'); + $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('/foo:bar/', $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, with alternative : "foo:bar"'); + $this->assertRegExp('/foo1:bar/', $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, with alternative : "foo1:bar"'); + $this->assertRegExp('/foo:bar1/', $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, with alternative : "foo:bar1"'); + } + + // Test if "foo1" command throw an "\InvalidArgumentException" and does not contain + // "foo:bar" as alternative because "foo1" is too far from "foo:bar" + try { + $application->find($commandName = 'foo1'); + $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->assertFalse(strpos($e->getMessage(), 'foo:bar'), '->find() throws an \InvalidArgumentException if command does not exist, without "foo:bar" alternative'); + } + } + + 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('Unknow-namespace:Unknow-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 "Unknow-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 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', $this->normalizeLineBreaks($tester->getDisplay()), '->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'); + } + } + + public function testAsText() + { + $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'); + } + + public function testAsXml() + { + $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', $this->normalizeLineBreaks($tester->getDisplay()), '->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', $this->normalizeLineBreaks($tester->getDisplay()), '->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', $this->normalizeLineBreaks($tester->getDisplay()), '->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); + + $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', $this->normalizeLineBreaks($tester->getDisplay()), '->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->assertSame('Symfony\Component\Console\Input\ArgvInput', get_class($command->input), '->run() creates an ArgvInput by default if none is given'); + $this->assertSame('Symfony\Component\Console\Output\ConsoleOutput', get_class($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', $this->normalizeLineBreaks($tester->getDisplay()), '->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', $this->normalizeLineBreaks($tester->getDisplay()), '->run() runs the help command if --help is passed'); + + $tester->run(array('-h' => true), array('decorated' => false)); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_run2.txt', $this->normalizeLineBreaks($tester->getDisplay()), '->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', $this->normalizeLineBreaks($tester->getDisplay()), '->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', $this->normalizeLineBreaks($tester->getDisplay()), '->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', $this->normalizeLineBreaks($tester->getDisplay()), '->run() displays the program version if --version is passed'); + + $tester->run(array('-V' => true), array('decorated' => false)); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_run4.txt', $this->normalizeLineBreaks($tester->getDisplay()), '->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', '-v' => true)); + $this->assertSame(Output::VERBOSITY_VERBOSE, $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'); + } + + /** + * @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)), + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Command/CommandTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Command/CommandTest.php new file mode 100644 index 0000000..557116e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Command/CommandTest.php @@ -0,0 +1,253 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\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 +{ + static protected $fixturesPath; + + static public function setUpBeforeClass() + { + self::$fixturesPath = __DIR__.'/../Fixtures/'; + require_once self::$fixturesPath.'/TestCommand.php'; + } + + public function testConstructor() + { + try { + $command = new Command(); + $this->fail('__construct() throws a \LogicException if the name is null'); + } catch (\Exception $e) { + $this->assertInstanceOf('\LogicException', $e, '__construct() throws a \LogicException if the name is null'); + $this->assertEquals('The command name cannot be empty.', $e->getMessage(), '__construct() throws a \LogicException if the name is null'); + } + $command = new Command('foo:bar'); + $this->assertEquals('foo:bar', $command->getName(), '__construct() takes the command name as its first argument'); + } + + 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'); + + try { + $command->setName(''); + $this->fail('->setName() throws an \InvalidArgumentException if the name is empty'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->setName() throws an \InvalidArgumentException if the name is empty'); + $this->assertEquals('Command name "" is invalid.', $e->getMessage(), '->setName() throws an \InvalidArgumentException if the name is empty'); + } + + try { + $command->setName('foo:'); + $this->fail('->setName() throws an \InvalidArgumentException if the name is empty'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->setName() throws an \InvalidArgumentException if the name is empty'); + $this->assertEquals('Command name "foo:" is invalid.', $e->getMessage(), '->setName() throws an \InvalidArgumentException if the name is empty'); + } + } + + 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 testRun() + { + $command = new \TestCommand(); + $tester = new CommandTester($command); + try { + $tester->execute(array('--bar' => true)); + $this->fail('->run() throws a \InvalidArgumentException when the input does not validate the current InputDefinition'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->run() throws a \InvalidArgumentException when the input does not validate the current InputDefinition'); + $this->assertEquals('The "--bar" option does not exist.', $e->getMessage(), '->run() throws a \InvalidArgumentException when the input does not validate the current InputDefinition'); + } + + $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'); + + $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'); + + $command = new Command('foo'); + try { + $command->run(new StringInput(''), new NullOutput()); + $this->fail('->run() throws a \LogicException if the execute() method has not been overridden and no code has been provided'); + } catch (\Exception $e) { + $this->assertInstanceOf('\LogicException', $e, '->run() throws a \LogicException if the execute() method has not been overridden and no code has been provided'); + $this->assertEquals('You must override the execute() method in the concrete command class.', $e->getMessage(), '->run() throws a \LogicException if the execute() method has not been overridden and no code has been provided'); + } + } + + 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 testAsText() + { + $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'); + } + + public function testAsXml() + { + $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/symfony/src/Symfony/Component/Console/Tests/Command/HelpCommandTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Command/HelpCommandTest.php new file mode 100644 index 0000000..417eea1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Command/HelpCommandTest.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\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 testExecute() + { + $command = new HelpCommand(); + + $commandTester = new CommandTester($command); + $command->setCommand(new ListCommand()); + $commandTester->execute(array()); + $this->assertRegExp('/list \[--xml\] \[--raw\] \[namespace\]/', $commandTester->getDisplay(), '->execute() returns a text help for the given command'); + + $command->setCommand(new ListCommand()); + $commandTester->execute(array('--xml' => true)); + $this->assertRegExp('/getDisplay(), '->execute() returns an XML help text if --xml is passed'); + + $application = new Application(); + $commandTester = new CommandTester($application->get('help')); + $commandTester->execute(array('command_name' => 'list')); + $this->assertRegExp('/list \[--xml\] \[--raw\] \[namespace\]/', $commandTester->getDisplay(), '->execute() returns a text help for the given command'); + + $commandTester->execute(array('command_name' => 'list', '--xml' => true)); + $this->assertRegExp('/getDisplay(), '->execute() returns an XML help text if --xml is passed'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Command/ListCommandTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Command/ListCommandTest.php new file mode 100644 index 0000000..fb0eacc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Command/ListCommandTest.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\Console\Tests\Command; + +use Symfony\Component\Console\Tester\CommandTester; +use Symfony\Component\Console\Application; + +class ListCommandTest extends \PHPUnit_Framework_TestCase +{ + public function testExecute() + { + $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'); + + $commandTester->execute(array('command' => $command->getName(), '--xml' => true)); + $this->assertRegExp('//', $commandTester->getDisplay(), '->execute() returns a list of available commands in XML if --xml is passed'); + + $commandTester->execute(array('command' => $command->getName(), '--raw' => true)); + $output = <<assertEquals(str_replace("\n", PHP_EOL, $output), $commandTester->getDisplay(), 'boo'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/Foo1Command.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/Foo1Command.php new file mode 100644 index 0000000..254162f --- /dev/null +++ b/vendor/symfony/symfony/src/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/symfony/src/Symfony/Component/Console/Tests/Fixtures/Foo2Command.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/Foo2Command.php new file mode 100644 index 0000000..8071dc8 --- /dev/null +++ b/vendor/symfony/symfony/src/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/symfony/src/Symfony/Component/Console/Tests/Fixtures/Foo3Command.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/Foo3Command.php new file mode 100644 index 0000000..7349bc3 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/Foo3Command.php @@ -0,0 +1,25 @@ +setName('foo3:bar') + ->setDescription('The foo3:bar command') + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + try { + throw new \Exception("First exception"); + } catch (\Exception $e) { + throw new \Exception("Second exception", 0, $e); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/FooCommand.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/FooCommand.php new file mode 100644 index 0000000..355e0ad --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/FooCommand.php @@ -0,0 +1,33 @@ +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/symfony/src/Symfony/Component/Console/Tests/Fixtures/TestCommand.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/TestCommand.php new file mode 100644 index 0000000..dcd3273 --- /dev/null +++ b/vendor/symfony/symfony/src/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/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_astext1.txt b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_astext1.txt new file mode 100644 index 0000000..2f692c0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_astext1.txt @@ -0,0 +1,20 @@ +Console Tool + +Usage: + [options] command [arguments] + +Options: + --help -h Display this help message. + --quiet -q Do not output any message. + --verbose -v Increase verbosity of messages. + --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 \ No newline at end of file diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_astext2.txt b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_astext2.txt new file mode 100644 index 0000000..1457bf7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_astext2.txt @@ -0,0 +1,16 @@ +Console Tool + +Usage: + [options] command [arguments] + +Options: + --help -h Display this help message. + --quiet -q Do not output any message. + --verbose -v Increase verbosity of messages. + --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 \ No newline at end of file diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_asxml1.txt b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_asxml1.txt new file mode 100644 index 0000000..ce21a32 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_asxml1.txt @@ -0,0 +1,83 @@ + + + + + help [--xml] [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 as XML by using the <comment>--xml</comment> option: + + <info>php app/console help --xml list</info> + + + + The command name + + help + + + + + + + + + list [--xml] [--raw] [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 as XML by using the <comment>--xml</comment> option: + + <info>php app/console list --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 + + + + + + + + help + list + + + foo:bar + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_asxml2.txt b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_asxml2.txt new file mode 100644 index 0000000..9e1f4a1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_asxml2.txt @@ -0,0 +1,15 @@ + + + + + foo:bar + The foo:bar command + + + afoobar + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_gethelp.txt b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_gethelp.txt new file mode 100644 index 0000000..5ad5420 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_gethelp.txt @@ -0,0 +1,13 @@ +Console Tool + +Usage: + [options] command [arguments] + +Options: + --help -h Display this help message. + --quiet -q Do not output any message. + --verbose -v Increase verbosity of messages. + --version -V Display this application version. + --ansi Force ANSI output. + --no-ansi Disable ANSI output. + --no-interaction -n Do not ask any interactive question. \ No newline at end of file diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception1.txt b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception1.txt new file mode 100644 index 0000000..4629345 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception1.txt @@ -0,0 +1,8 @@ + + + + [InvalidArgumentException] + Command "foo" is not defined. + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception2.txt b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception2.txt new file mode 100644 index 0000000..56dd52e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception2.txt @@ -0,0 +1,11 @@ + + + + [InvalidArgumentException] + The "--foo" option does not exist. + + + +list [--xml] [--raw] [namespace] + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception3.txt b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception3.txt new file mode 100644 index 0000000..c639924 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception3.txt @@ -0,0 +1,19 @@ + + + + [Exception] + Second exception + + + + + + + [Exception] + First exception + + + +foo3:bar + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception4.txt b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception4.txt new file mode 100644 index 0000000..19f893b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception4.txt @@ -0,0 +1,9 @@ + + + + [InvalidArgumentException] + Command "foo" is not define + d. + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_run1.txt b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_run1.txt new file mode 100644 index 0000000..176dc88 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_run1.txt @@ -0,0 +1,17 @@ +Console Tool + +Usage: + [options] command [arguments] + +Options: + --help -h Display this help message. + --quiet -q Do not output any message. + --verbose -v Increase verbosity of messages. + --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/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_run2.txt b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_run2.txt new file mode 100644 index 0000000..f717033 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_run2.txt @@ -0,0 +1,26 @@ +Usage: + help [--xml] [command_name] + +Arguments: + command The command to execute + command_name The command name (default: 'help') + +Options: + --xml To output help as XML + --help (-h) Display this help message. + --quiet (-q) Do not output any message. + --verbose (-v) Increase verbosity of messages. + --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 as XML by using the --xml option: + + php app/console help --xml list + diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_run3.txt b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_run3.txt new file mode 100644 index 0000000..441db54 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_run3.txt @@ -0,0 +1,27 @@ +Usage: + list [--xml] [--raw] [namespace] + +Arguments: + namespace The namespace name + +Options: + --xml To output help as XML + --raw To output raw command list + +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 as XML by using the --xml option: + + php app/console list --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/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_run4.txt b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_run4.txt new file mode 100644 index 0000000..47187fc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/application_run4.txt @@ -0,0 +1 @@ +Console Tool diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/command_astext.txt b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/command_astext.txt new file mode 100644 index 0000000..e599903 --- /dev/null +++ b/vendor/symfony/symfony/src/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) Increase verbosity of messages. + --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/symfony/src/Symfony/Component/Console/Tests/Fixtures/command_asxml.txt b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/command_asxml.txt new file mode 100644 index 0000000..806c5a5 --- /dev/null +++ b/vendor/symfony/symfony/src/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/symfony/src/Symfony/Component/Console/Tests/Fixtures/definition_astext.txt b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/definition_astext.txt new file mode 100644 index 0000000..2ad6078 --- /dev/null +++ b/vendor/symfony/symfony/src/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: array('bar')) + +Options: + --foo (-f) The foo option + --baz The baz option (default: false) + --bar (-b) The bar option (default: 'bar') + --qux The qux option (default: array('foo', 'bar')) (multiple values allowed) + --qux2 The qux2 option (default: array ( 'foo' => 'bar',)) (multiple values allowed) diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/definition_asxml.txt b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Fixtures/definition_asxml.txt new file mode 100644 index 0000000..eec8c07 --- /dev/null +++ b/vendor/symfony/symfony/src/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/symfony/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleStackTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleStackTest.php new file mode 100644 index 0000000..e99ebc5 --- /dev/null +++ b/vendor/symfony/symfony/src/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/symfony/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleTest.php new file mode 100644 index 0000000..b2875e9 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleTest.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\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[0m", $style->apply('foo')); + + $style = new OutputFormatterStyle('red', null, array('blink')); + $this->assertEquals("\033[31;5mfoo\033[0m", $style->apply('foo')); + + $style = new OutputFormatterStyle(null, 'white'); + $this->assertEquals("\033[47mfoo\033[0m", $style->apply('foo')); + } + + public function testForeground() + { + $style = new OutputFormatterStyle(); + + $style->setForeground('black'); + $this->assertEquals("\033[30mfoo\033[0m", $style->apply('foo')); + + $style->setForeground('blue'); + $this->assertEquals("\033[34mfoo\033[0m", $style->apply('foo')); + + $this->setExpectedException('InvalidArgumentException'); + $style->setForeground('undefined-color'); + } + + public function testBackground() + { + $style = new OutputFormatterStyle(); + + $style->setBackground('black'); + $this->assertEquals("\033[40mfoo\033[0m", $style->apply('foo')); + + $style->setBackground('yellow'); + $this->assertEquals("\033[43mfoo\033[0m", $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[0m", $style->apply('foo')); + + $style->setOption('bold'); + $this->assertEquals("\033[7;8;1mfoo\033[0m", $style->apply('foo')); + + $style->unsetOption('reverse'); + $this->assertEquals("\033[8;1mfoo\033[0m", $style->apply('foo')); + + $style->setOption('bold'); + $this->assertEquals("\033[8;1mfoo\033[0m", $style->apply('foo')); + + $style->setOptions(array('bold')); + $this->assertEquals("\033[1mfoo\033[0m", $style->apply('foo')); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php new file mode 100644 index 0000000..0d1bf41 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php @@ -0,0 +1,191 @@ + + * + * 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 FormatterStyleTest extends \PHPUnit_Framework_TestCase +{ + public function testEmptyTag() + { + $formatter = new OutputFormatter(true); + $this->assertEquals("foo<>bar", $formatter->format('foo<>bar')); + } + + 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[0m", + $formatter->format('some error') + ); + $this->assertEquals( + "\033[32msome info\033[0m", + $formatter->format('some info') + ); + $this->assertEquals( + "\033[33msome comment\033[0m", + $formatter->format('some comment') + ); + $this->assertEquals( + "\033[30;46msome question\033[0m", + $formatter->format('some question') + ); + } + + public function testNestedStyles() + { + $formatter = new OutputFormatter(true); + + $this->assertEquals( + "\033[37;41msome \033[0m\033[32msome info\033[0m\033[37;41m error\033[0m", + $formatter->format('some some info error') + ); + } + + public function testDeepNestedStyles() + { + $formatter = new OutputFormatter(true); + + $this->assertEquals( + "\033[37;41merror\033[0m\033[32minfo\033[0m\033[33mcomment\033[0m\033[37;41merror\033[0m", + $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')); + + $this->assertEquals("\033[34;47msome custom msg\033[0m", $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[0m", $formatter->format('some custom msg')); + } + + public function testInlineStyle() + { + $formatter = new OutputFormatter(true); + + $this->assertEquals("\033[34;41msome text\033[0m", $formatter->format('some text')); + $this->assertEquals("\033[34;41msome text\033[0m", $formatter->format('some text')); + } + + 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[0m", $formatter->format('some error') + ); + $this->assertEquals( + "\033[32msome info\033[0m", $formatter->format('some info') + ); + $this->assertEquals( + "\033[33msome comment\033[0m", $formatter->format('some comment') + ); + $this->assertEquals( + "\033[30;46msome question\033[0m", $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/symfony/src/Symfony/Component/Console/Tests/Helper/DialogHelperTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Helper/DialogHelperTest.php new file mode 100644 index 0000000..a486f62 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Helper/DialogHelperTest.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\Helper; + +use Symfony\Component\Console\Helper\DialogHelper; +use Symfony\Component\Console\Helper\HelperSet; +use Symfony\Component\Console\Helper\FormatterHelper; +use Symfony\Component\Console\Output\StreamOutput; + +class DialogHelperTest extends \PHPUnit_Framework_TestCase +{ + 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 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()); + } + } + + protected function getInputStream($input) + { + $stream = fopen('php://memory', 'r+', false); + fputs($stream, $input); + rewind($stream); + + return $stream; + } + + protected function getOutputStream() + { + return new StreamOutput(fopen('php://memory', 'r+', false)); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Helper/FormatterHelperTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Helper/FormatterHelperTest.php new file mode 100644 index 0000000..430c077 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Helper/FormatterHelperTest.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\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 (!extension_loaded('mbstring')) { + $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' + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php new file mode 100644 index 0000000..cf63177 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php @@ -0,0 +1,217 @@ + + * + * 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 testParser() + { + $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'); + + $input = new ArgvInput(array('cli.php', '--foo')); + $input->bind(new InputDefinition(array(new InputOption('foo')))); + $this->assertEquals(array('foo' => true), $input->getOptions(), '->parse() parses long options without a value'); + + $input = new ArgvInput(array('cli.php', '--foo=bar')); + $input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)))); + $this->assertEquals(array('foo' => 'bar'), $input->getOptions(), '->parse() parses long options with a required value (with a = separator)'); + + $input = new ArgvInput(array('cli.php', '--foo', 'bar')); + $input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)))); + $this->assertEquals(array('foo' => 'bar'), $input->getOptions(), '->parse() parses long options with a required value (with a space separator)'); + + try { + $input = new ArgvInput(array('cli.php', '--foo')); + $input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)))); + $this->fail('->parse() throws a \RuntimeException if no value is passed to an option when it is required'); + } catch (\Exception $e) { + $this->assertInstanceOf('\RuntimeException', $e, '->parse() throws a \RuntimeException if no value is passed to an option when it is required'); + $this->assertEquals('The "--foo" option requires a value.', $e->getMessage(), '->parse() throws a \RuntimeException if no value is passed to an option when it is required'); + } + + $input = new ArgvInput(array('cli.php', '-f')); + $input->bind(new InputDefinition(array(new InputOption('foo', 'f')))); + $this->assertEquals(array('foo' => true), $input->getOptions(), '->parse() parses short options without a value'); + + $input = new ArgvInput(array('cli.php', '-fbar')); + $input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)))); + $this->assertEquals(array('foo' => 'bar'), $input->getOptions(), '->parse() parses short options with a required value (with no separator)'); + + $input = new ArgvInput(array('cli.php', '-f', 'bar')); + $input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)))); + $this->assertEquals(array('foo' => 'bar'), $input->getOptions(), '->parse() parses short options with a required value (with a space separator)'); + + $input = new ArgvInput(array('cli.php', '-f', '-b', 'foo')); + $input->bind(new InputDefinition(array(new InputArgument('name'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputOption('bar', 'b')))); + $this->assertEquals(array('foo' => null, 'bar' => true), $input->getOptions(), '->parse() parses short options with an optional value which is not present'); + + try { + $input = new ArgvInput(array('cli.php', '-f')); + $input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)))); + $this->fail('->parse() throws a \RuntimeException if no value is passed to an option when it is required'); + } catch (\Exception $e) { + $this->assertInstanceOf('\RuntimeException', $e, '->parse() throws a \RuntimeException if no value is passed to an option when it is required'); + $this->assertEquals('The "--foo" option requires a value.', $e->getMessage(), '->parse() throws a \RuntimeException if no value is passed to an option when it is required'); + } + + try { + $input = new ArgvInput(array('cli.php', '-ffoo')); + $input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_NONE)))); + $this->fail('->parse() throws a \RuntimeException if a value is passed to an option which does not take one'); + } catch (\Exception $e) { + $this->assertInstanceOf('\RuntimeException', $e, '->parse() throws a \RuntimeException if a value is passed to an option which does not take one'); + $this->assertEquals('The "-o" option does not exist.', $e->getMessage(), '->parse() throws a \RuntimeException if a value is passed to an option which does not take one'); + } + + try { + $input = new ArgvInput(array('cli.php', 'foo', 'bar')); + $input->bind(new InputDefinition()); + $this->fail('->parse() throws a \RuntimeException if too many arguments are passed'); + } catch (\Exception $e) { + $this->assertInstanceOf('\RuntimeException', $e, '->parse() throws a \RuntimeException if too many arguments are passed'); + $this->assertEquals('Too many arguments.', $e->getMessage(), '->parse() throws a \RuntimeException if too many arguments are passed'); + } + + try { + $input = new ArgvInput(array('cli.php', '--foo')); + $input->bind(new InputDefinition()); + $this->fail('->parse() throws a \RuntimeException if an unknown long option is passed'); + } catch (\Exception $e) { + $this->assertInstanceOf('\RuntimeException', $e, '->parse() throws a \RuntimeException if an unknown long option is passed'); + $this->assertEquals('The "--foo" option does not exist.', $e->getMessage(), '->parse() throws a \RuntimeException if an unknown long option is passed'); + } + + try { + $input = new ArgvInput(array('cli.php', '-f')); + $input->bind(new InputDefinition()); + $this->fail('->parse() throws a \RuntimeException if an unknown short option is passed'); + } catch (\Exception $e) { + $this->assertInstanceOf('\RuntimeException', $e, '->parse() throws a \RuntimeException if an unknown short option is passed'); + $this->assertEquals('The "-f" option does not exist.', $e->getMessage(), '->parse() throws a \RuntimeException if an unknown short option is passed'); + } + + $input = new ArgvInput(array('cli.php', '-fb')); + $input->bind(new InputDefinition(array(new InputOption('foo', 'f'), new InputOption('bar', 'b')))); + $this->assertEquals(array('foo' => true, 'bar' => true), $input->getOptions(), '->parse() parses short options when they are aggregated as a single one'); + + $input = new ArgvInput(array('cli.php', '-fb', 'bar')); + $input->bind(new InputDefinition(array(new InputOption('foo', 'f'), new InputOption('bar', 'b', InputOption::VALUE_REQUIRED)))); + $this->assertEquals(array('foo' => true, 'bar' => 'bar'), $input->getOptions(), '->parse() parses short options when they are aggregated as a single one and the last one has a required value'); + + $input = new ArgvInput(array('cli.php', '-fb', 'bar')); + $input->bind(new InputDefinition(array(new InputOption('foo', 'f'), new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL)))); + $this->assertEquals(array('foo' => true, 'bar' => 'bar'), $input->getOptions(), '->parse() parses short options when they are aggregated as a single one and the last one has an optional value'); + + $input = new ArgvInput(array('cli.php', '-fbbar')); + $input->bind(new InputDefinition(array(new InputOption('foo', 'f'), new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL)))); + $this->assertEquals(array('foo' => true, 'bar' => 'bar'), $input->getOptions(), '->parse() parses short options when they are aggregated as a single one and the last one has an optional value with no separator'); + + $input = new ArgvInput(array('cli.php', '-fbbar')); + $input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL)))); + $this->assertEquals(array('foo' => 'bbar', 'bar' => null), $input->getOptions(), '->parse() parses short options when they are aggregated as a single one and one of them takes a value'); + + try { + $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'); + } catch (\RuntimeException $e) { + $this->assertNotEquals('Too many arguments.', $e->getMessage(), '->parse() parses array arguments'); + } + + $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()); + + try { + $input = new ArgvInput(array('cli.php', '-1')); + $input->bind(new InputDefinition(array(new InputArgument('number')))); + $this->fail('->parse() throws a \RuntimeException if an unknown option is passed'); + } catch (\Exception $e) { + $this->assertInstanceOf('\RuntimeException', $e, '->parse() parses arguments with leading dashes as options without having encountered a double-dash sequence'); + $this->assertEquals('The "-1" option does not exist.', $e->getMessage(), '->parse() parses arguments with leading dashes as options without having encountered a double-dash sequence'); + } + + $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'); + + $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->assertEquals('', $input->getFirstArgument(), '->getFirstArgument() returns the first argument from the raw input'); + + $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'); + } + + /** + * @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'), + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php new file mode 100644 index 0000000..82f477e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.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\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 testParse() + { + $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name')))); + $this->assertEquals(array('name' => 'foo'), $input->getArguments(), '->parse() parses required arguments'); + + try { + $input = new ArrayInput(array('foo' => 'foo'), new InputDefinition(array(new InputArgument('name')))); + $this->fail('->parse() throws an \InvalidArgumentException exception if an invalid argument is passed'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->parse() throws an \InvalidArgumentException exception if an invalid argument is passed'); + $this->assertEquals('The "foo" argument does not exist.', $e->getMessage(), '->parse() throws an \InvalidArgumentException exception if an invalid argument is passed'); + } + + $input = new ArrayInput(array('--foo' => 'bar'), new InputDefinition(array(new InputOption('foo')))); + $this->assertEquals(array('foo' => 'bar'), $input->getOptions(), '->parse() parses long options'); + + $input = new ArrayInput(array('--foo' => 'bar'), new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, '', 'default')))); + $this->assertEquals(array('foo' => 'bar'), $input->getOptions(), '->parse() parses long options with a default value'); + + $input = new ArrayInput(array('--foo' => null), new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, '', 'default')))); + $this->assertEquals(array('foo' => 'default'), $input->getOptions(), '->parse() parses long options with a default value'); + + try { + $input = new ArrayInput(array('--foo' => null), new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)))); + $this->fail('->parse() throws an \InvalidArgumentException exception if a required option is passed without a value'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->parse() throws an \InvalidArgumentException exception if a required option is passed without a value'); + $this->assertEquals('The "--foo" option requires a value.', $e->getMessage(), '->parse() throws an \InvalidArgumentException exception if a required option is passed without a value'); + } + + try { + $input = new ArrayInput(array('--foo' => 'foo'), new InputDefinition()); + $this->fail('->parse() throws an \InvalidArgumentException exception if an invalid option is passed'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->parse() throws an \InvalidArgumentException exception if an invalid option is passed'); + $this->assertEquals('The "--foo" option does not exist.', $e->getMessage(), '->parse() throws an \InvalidArgumentException exception if an invalid option is passed'); + } + + $input = new ArrayInput(array('-f' => 'bar'), new InputDefinition(array(new InputOption('foo', 'f')))); + $this->assertEquals(array('foo' => 'bar'), $input->getOptions(), '->parse() parses short options'); + + try { + $input = new ArrayInput(array('-o' => 'foo'), new InputDefinition()); + $this->fail('->parse() throws an \InvalidArgumentException exception if an invalid option is passed'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->parse() throws an \InvalidArgumentException exception if an invalid option is passed'); + $this->assertEquals('The "-o" option does not exist.', $e->getMessage(), '->parse() throws an \InvalidArgumentException exception if an invalid option is passed'); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/InputArgumentTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/InputArgumentTest.php new file mode 100644 index 0000000..1b680a9 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/InputArgumentTest.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\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'); + + // mode argument + $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'); + + try { + $argument = new InputArgument('foo', 'ANOTHER_ONE'); + $this->fail('__construct() throws an Exception if the mode is not valid'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, '__construct() throws an Exception if the mode is not valid'); + $this->assertEquals('Argument mode "ANOTHER_ONE" is not valid.', $e->getMessage()); + } + try { + $argument = new InputArgument('foo', -1); + $this->fail('__construct() throws an Exception if the mode is not valid'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, '__construct() throws an Exception if the mode is not valid'); + $this->assertEquals('Argument mode "-1" is not valid.', $e->getMessage()); + } + } + + 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'); + + try { + $argument = new InputArgument('foo', InputArgument::REQUIRED); + $argument->setDefault('default'); + $this->fail('->setDefault() throws an Exception if you give a default value for a required argument'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, '->parse() throws an \InvalidArgumentException exception if an invalid option is passed'); + $this->assertEquals('Cannot set a default value except for Parameter::OPTIONAL mode.', $e->getMessage()); + } + + try { + $argument = new InputArgument('foo', InputArgument::IS_ARRAY); + $argument->setDefault('default'); + $this->fail('->setDefault() throws an Exception if you give a default value which is not an array for a IS_ARRAY option'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, '->setDefault() throws an Exception if you give a default value which is not an array for a IS_ARRAY option'); + $this->assertEquals('A default value for an array argument must be an array.', $e->getMessage()); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/InputDefinitionTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/InputDefinitionTest.php new file mode 100644 index 0000000..2b339f0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/InputDefinitionTest.php @@ -0,0 +1,364 @@ + + * + * 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 +{ + static protected $fixtures; + + protected $foo, $bar, $foo1, $foo2; + + static public function setUpBeforeClass() + { + self::$fixtures = __DIR__.'/../Fixtures/'; + } + + public function testConstructor() + { + $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'); + + $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'); + + // arguments must have different names + try { + $definition->addArgument($this->foo1); + $this->fail('->addArgument() throws a Exception if another argument is already registered with the same name'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, '->addArgument() throws a Exception if another argument is already registered with the same name'); + $this->assertEquals('An argument with name "foo" already exists.', $e->getMessage()); + } + + // cannot add a parameter after an array parameter + $definition->addArgument(new InputArgument('fooarray', InputArgument::IS_ARRAY)); + try { + $definition->addArgument(new InputArgument('anotherbar')); + $this->fail('->addArgument() throws a Exception if there is an array parameter already registered'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, '->addArgument() throws a Exception if there is an array parameter already registered'); + $this->assertEquals('Cannot add an argument after an array argument.', $e->getMessage()); + } + + + // cannot add a required argument after an optional one + $definition = new InputDefinition(); + $definition->addArgument($this->foo); + try { + $definition->addArgument($this->foo2); + $this->fail('->addArgument() throws an exception if you try to add a required argument after an optional one'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, '->addArgument() throws an exception if you try to add a required argument after an optional one'); + $this->assertEquals('Cannot add a required argument after an optional one.', $e->getMessage()); + } + } + + 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'); + try { + $definition->getArgument('bar'); + $this->fail('->getArgument() throws an exception if the InputArgument name does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, '->getArgument() throws an exception if the InputArgument name does not exist'); + $this->assertEquals('The "bar" argument does not exist.', $e->getMessage()); + } + } + + 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'); + try { + $definition->getOptionForShortcut('f'); + $this->fail('->setOptions() clears all InputOption objects'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, '->setOptions() clears all InputOption objects'); + $this->assertEquals('The "-f" option does not exist.', $e->getMessage()); + } + } + + 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'); + try { + $definition->addOption($this->foo2); + $this->fail('->addOption() throws a Exception if the another option is already registered with the same name'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, '->addOption() throws a Exception if the another option is already registered with the same name'); + $this->assertEquals('An option named "foo" already exists.', $e->getMessage()); + } + try { + $definition->addOption($this->foo1); + $this->fail('->addOption() throws a Exception if the another option is already registered with the same shortcut'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, '->addOption() throws a Exception if the another option is already registered with the same shortcut'); + $this->assertEquals('An option with shortcut "f" already exists.', $e->getMessage()); + } + } + + 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'); + try { + $definition->getOption('bar'); + $this->fail('->getOption() throws an exception if the option name does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, '->getOption() throws an exception if the option name does not exist'); + $this->assertEquals('The "--bar" option does not exist.', $e->getMessage()); + } + } + + 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'); + try { + $definition->getOptionForShortcut('l'); + $this->fail('->getOption() throws an exception if the shortcut does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, '->getOption() throws an exception if the shortcut does not exist'); + $this->assertEquals('The "-l" option does not exist.', $e->getMessage()); + } + } + + 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' => null, + 'foo2' => null, + 'foo3' => 'default', + 'foo4' => null, + 'foo5' => 'default', + 'foo6' => array(), + 'foo7' => array(1, 2), + ); + $this->assertEquals($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'); + } + + public function testAsText() + { + $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'), + new InputOption('qux', '', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The qux option', array('foo', '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'); + } + + public function testAsXml() + { + $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(), '->asText() returns a textual 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'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/InputOptionTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/InputOptionTest.php new file mode 100644 index 0000000..b5d8b43 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/InputOptionTest.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\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'); + + try { + $option = new InputOption('foo', 'f', InputOption::VALUE_IS_ARRAY); + $this->fail('->setDefault() throws an Exception if VALUE_IS_ARRAY option is used when an option does not accept a value'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, '->setDefault() throws an Exception if VALUE_IS_ARRAY option is used when an option does not accept a value'); + $this->assertEquals('Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.', $e->getMessage()); + } + + // shortcut argument + $option = new InputOption('foo', 'f'); + $this->assertEquals('f', $option->getShortcut(), '__construct() can take a shortcut as its second argument'); + $option = new InputOption('foo', '-f'); + $this->assertEquals('f', $option->getShortcut(), '__construct() removes the leading - of the shortcut'); + $option = new InputOption('foo'); + $this->assertNull($option->getShortcut(), '__construct() makes the shortcut null by default'); + + // mode argument + $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'); + + try { + $option = new InputOption('foo', 'f', 'ANOTHER_ONE'); + $this->fail('__construct() throws an Exception if the mode is not valid'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, '__construct() throws an Exception if the mode is not valid'); + $this->assertEquals('Option mode "ANOTHER_ONE" is not valid.', $e->getMessage()); + } + try { + $option = new InputOption('foo', 'f', -1); + $this->fail('__construct() throws an Exception if the mode is not valid'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, '__construct() throws an Exception if the mode is not valid'); + $this->assertEquals('Option mode "-1" is not valid.', $e->getMessage()); + } + } + + /** + * @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'); + + $option = new InputOption('foo', 'f', InputOption::VALUE_NONE); + try { + $option->setDefault('default'); + $this->fail('->setDefault() throws an Exception if you give a default value for a VALUE_NONE option'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, '->setDefault() throws an Exception if you give a default value for a VALUE_NONE option'); + $this->assertEquals('Cannot set a default value when using Option::VALUE_NONE mode.', $e->getMessage()); + } + + $option = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY); + try { + $option->setDefault('default'); + $this->fail('->setDefault() throws an Exception if you give a default value which is not an array for a VALUE_IS_ARRAY option'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, '->setDefault() throws an Exception if you give a default value which is not an array for a VALUE_IS_ARRAY option'); + $this->assertEquals('A default value for an array option must be an array.', $e->getMessage()); + } + } + + 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/symfony/src/Symfony/Component/Console/Tests/Input/InputTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/InputTest.php new file mode 100644 index 0000000..779d45d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/InputTest.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\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'); + + try { + $input->setOption('foo', 'bar'); + $this->fail('->setOption() throws a \InvalidArgumentException if the option does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->setOption() throws a \InvalidArgumentException if the option does not exist'); + $this->assertEquals('The "foo" option does not exist.', $e->getMessage()); + } + + try { + $input->getOption('foo'); + $this->fail('->getOption() throws a \InvalidArgumentException if the option does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->setOption() throws a \InvalidArgumentException if the option does not exist'); + $this->assertEquals('The "foo" option does not exist.', $e->getMessage()); + } + } + + 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'); + + try { + $input->setArgument('foo', 'bar'); + $this->fail('->setArgument() throws a \InvalidArgumentException if the argument does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->setOption() throws a \InvalidArgumentException if the option does not exist'); + $this->assertEquals('The "foo" argument does not exist.', $e->getMessage()); + } + + try { + $input->getArgument('foo'); + $this->fail('->getArgument() throws a \InvalidArgumentException if the argument does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->setOption() throws a \InvalidArgumentException if the option does not exist'); + $this->assertEquals('The "foo" argument does not exist.', $e->getMessage()); + } + } + + public function testValidate() + { + $input = new ArrayInput(array()); + $input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::REQUIRED)))); + + try { + $input->validate(); + $this->fail('->validate() throws a \RuntimeException if not enough arguments are given'); + } catch (\Exception $e) { + $this->assertInstanceOf('\RuntimeException', $e, '->validate() throws a \RuntimeException if not enough arguments are given'); + $this->assertEquals('Not enough arguments.', $e->getMessage()); + } + + $input = new ArrayInput(array('name' => 'foo')); + $input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::REQUIRED)))); + + try { + $input->validate(); + } catch (\RuntimeException $e) { + $this->fail('->validate() does not throw a \RuntimeException if enough arguments are given'); + } + } + + public function testSetFetInteractive() + { + $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/symfony/src/Symfony/Component/Console/Tests/Input/StringInputTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/StringInputTest.php new file mode 100644 index 0000000..031797c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Input/StringInputTest.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\Input; + +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 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('\"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'), + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Output/ConsoleOutputTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Output/ConsoleOutputTest.php new file mode 100644 index 0000000..7a3ede3 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Output/ConsoleOutputTest.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\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'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Output/NullOutputTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Output/NullOutputTest.php new file mode 100644 index 0000000..8dd5f7c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Output/NullOutputTest.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\Output; + +use Symfony\Component\Console\Output\NullOutput; + +class NullOutputTest extends \PHPUnit_Framework_TestCase +{ + public function testConstructor() + { + $output = new NullOutput(); + $output->write('foo'); + $this->assertTrue(true, '->write() does nothing'); // FIXME + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Output/OutputTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Output/OutputTest.php new file mode 100644 index 0000000..aa4a204 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Output/OutputTest.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\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'); + } + + public function testWrite() + { + $fooStyle = new OutputFormatterStyle('yellow', 'red', array('blink')); + $output = new TestOutput(Output::VERBOSITY_QUIET); + $output->writeln('foo'); + $this->assertEquals('', $output->output, '->writeln() outputs nothing if verbosity is set to VERBOSITY_QUIET'); + + $output = new TestOutput(); + $output->writeln(array('foo', 'bar')); + $this->assertEquals("foo\nbar\n", $output->output, '->writeln() can take an array of messages to output'); + + $output = new TestOutput(); + $output->writeln('foo', Output::OUTPUT_RAW); + $this->assertEquals("foo\n", $output->output, '->writeln() outputs the raw message if OUTPUT_RAW is specified'); + + $output = new TestOutput(); + $output->writeln('foo', Output::OUTPUT_PLAIN); + $this->assertEquals("foo\n", $output->output, '->writeln() strips decoration tags if OUTPUT_PLAIN is specified'); + + $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'); + + $output = new TestOutput(); + $output->getFormatter()->setStyle('FOO', $fooStyle); + $output->setDecorated(true); + $output->writeln('foo'); + $this->assertEquals("\033[33;41;5mfoo\033[0m\n", $output->output, '->writeln() decorates the output'); + + try { + $output->writeln('foo', 24); + $this->fail('->writeln() throws an \InvalidArgumentException when the type does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->writeln() throws an \InvalidArgumentException when the type does not exist'); + $this->assertEquals('Unknown output type given (24)', $e->getMessage()); + } + + $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/symfony/src/Symfony/Component/Console/Tests/Output/StreamOutputTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Output/StreamOutputTest.php new file mode 100644 index 0000000..b151a48 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Output/StreamOutputTest.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\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() + { + try { + $output = new StreamOutput('foo'); + $this->fail('__construct() throws an \InvalidArgumentException if the first argument is not a stream'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '__construct() throws an \InvalidArgumentException if the first argument is not a stream'); + $this->assertEquals('The StreamOutput class needs a stream as its first argument.', $e->getMessage()); + } + + $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'); + } + + 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/symfony/src/Symfony/Component/Console/Tests/Tester/ApplicationTesterTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Tester/ApplicationTesterTest.php new file mode 100644 index 0000000..6ce30ab --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Tester/ApplicationTesterTest.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\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'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Tester/CommandTesterTest.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Tester/CommandTesterTest.php new file mode 100644 index 0000000..e64d967 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/Tester/CommandTesterTest.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\Tests\Tester; + +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 $application; + 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'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/bootstrap.php b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/bootstrap.php new file mode 100644 index 0000000..c486b72 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/Tests/bootstrap.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +spl_autoload_register(function ($class) { + if (0 === strpos(ltrim($class, '/'), 'Symfony\Component\Console')) { + if (file_exists($file = __DIR__.'/../'.substr(str_replace('\\', '/', $class), strlen('Symfony\Component\Console')).'.php')) { + require_once $file; + } + } +}); diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/composer.json b/vendor/symfony/symfony/src/Symfony/Component/Console/composer.json new file mode 100644 index 0000000..6de78af --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/composer.json @@ -0,0 +1,30 @@ +{ + "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" + }, + "autoload": { + "psr-0": { "Symfony\\Component\\Console": "" } + }, + "target-dir": "Symfony/Component/Console", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/Console/phpunit.xml.dist b/vendor/symfony/symfony/src/Symfony/Component/Console/phpunit.xml.dist new file mode 100644 index 0000000..fd1c069 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/Console/phpunit.xml.dist @@ -0,0 +1,30 @@ + + + + + + ./Tests/ + + + + + + ./ + + ./Resources + ./Tests + ./vendor + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/CHANGELOG.md b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/CHANGELOG.md new file mode 100644 index 0000000..be10abe --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/CHANGELOG.md @@ -0,0 +1,7 @@ +CHANGELOG +========= + +2.1.0 +----- + + * none diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/CssSelector.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/CssSelector.php new file mode 100644 index 0000000..f5566be --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/CssSelector.php @@ -0,0 +1,322 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\CssSelector; + +use Symfony\Component\CssSelector\Exception\ParseException; + +/** + * CssSelector is the main entry point of the component and can convert CSS + * selectors to XPath expressions. + * + * $xpath = CssSelector::toXpath('h1.foo'); + * + * This component is a port of the Python lxml library, + * which is copyright Infrae and distributed under the BSD license. + * + * @author Fabien Potencier + * + * @api + */ +class CssSelector +{ + /** + * Translates a CSS expression to its XPath equivalent. + * Optionally, a prefix can be added to the resulting XPath + * expression with the $prefix parameter. + * + * @param mixed $cssExpr The CSS expression. + * @param string $prefix An optional prefix for the XPath expression. + * + * @return string + * + * @throws ParseException When got None for xpath expression + * + * @api + */ + static public function toXPath($cssExpr, $prefix = 'descendant-or-self::') + { + if (is_string($cssExpr)) { + if (!$cssExpr) { + return $prefix.'*'; + } + + if (preg_match('#^\w+\s*$#u', $cssExpr, $match)) { + return $prefix.trim($match[0]); + } + + if (preg_match('~^(\w*)#(\w+)\s*$~u', $cssExpr, $match)) { + return sprintf("%s%s[@id = '%s']", $prefix, $match[1] ? $match[1] : '*', $match[2]); + } + + if (preg_match('#^(\w*)\.(\w+)\s*$#u', $cssExpr, $match)) { + return sprintf("%s%s[contains(concat(' ', normalize-space(@class), ' '), ' %s ')]", $prefix, $match[1] ? $match[1] : '*', $match[2]); + } + + $parser = new self(); + $cssExpr = $parser->parse($cssExpr); + } + + $expr = $cssExpr->toXpath(); + + // @codeCoverageIgnoreStart + if (!$expr) { + throw new ParseException(sprintf('Got None for xpath expression from %s.', $cssExpr)); + } + // @codeCoverageIgnoreEnd + + if ($prefix) { + $expr->addPrefix($prefix); + } + + return (string) $expr; + } + + /** + * Parses an expression and returns the Node object that represents + * the parsed expression. + * + * @param string $string The expression to parse + * + * @return Node\NodeInterface + * + * @throws \Exception When tokenizer throws it while parsing + */ + public function parse($string) + { + $tokenizer = new Tokenizer(); + + $stream = new TokenStream($tokenizer->tokenize($string), $string); + + try { + return $this->parseSelectorGroup($stream); + } catch (\Exception $e) { + $class = get_class($e); + + throw new $class(sprintf('%s at %s -> %s', $e->getMessage(), implode($stream->getUsed(), ''), $stream->peek()), 0, $e); + } + } + + /** + * Parses a selector group contained in $stream and returns + * the Node object that represents the expression. + * + * @param TokenStream $stream The stream to parse. + * + * @return Node\NodeInterface + */ + private function parseSelectorGroup($stream) + { + $result = array(); + while (true) { + $result[] = $this->parseSelector($stream); + if ($stream->peek() == ',') { + $stream->next(); + } else { + break; + } + } + + if (count($result) == 1) { + return $result[0]; + } + + return new Node\OrNode($result); + } + + /** + * Parses a selector contained in $stream and returns the Node + * object that represents it. + * + * @param TokenStream $stream The stream containing the selector. + * + * @return Node\NodeInterface + * + * @throws ParseException When expected selector but got something else + */ + private function parseSelector($stream) + { + $result = $this->parseSimpleSelector($stream); + + while (true) { + $peek = $stream->peek(); + if (',' == $peek || null === $peek) { + return $result; + } elseif (in_array($peek, array('+', '>', '~'))) { + // A combinator + $combinator = (string) $stream->next(); + + // Ignore optional whitespace after a combinator + while (' ' == $stream->peek()) { + $stream->next(); + } + } else { + $combinator = ' '; + } + $consumed = count($stream->getUsed()); + $nextSelector = $this->parseSimpleSelector($stream); + if ($consumed == count($stream->getUsed())) { + throw new ParseException(sprintf("Expected selector, got '%s'", $stream->peek())); + } + + $result = new Node\CombinedSelectorNode($result, $combinator, $nextSelector); + } + + return $result; + } + + /** + * Parses a simple selector (the current token) from $stream and returns + * the resulting Node object. + * + * @param TokenStream $stream The stream containing the selector. + * + * @return Node\NodeInterface + * + * @throws ParseException When expected symbol but got something else + */ + private function parseSimpleSelector($stream) + { + $peek = $stream->peek(); + if ('*' != $peek && !$peek->isType('Symbol')) { + $element = $namespace = '*'; + } else { + $next = $stream->next(); + if ('*' != $next && !$next->isType('Symbol')) { + throw new ParseException(sprintf("Expected symbol, got '%s'", $next)); + } + + if ($stream->peek() == '|') { + $namespace = $next; + $stream->next(); + $element = $stream->next(); + if ('*' != $element && !$next->isType('Symbol')) { + throw new ParseException(sprintf("Expected symbol, got '%s'", $next)); + } + } else { + $namespace = '*'; + $element = $next; + } + } + + $result = new Node\ElementNode($namespace, $element); + $hasHash = false; + while (true) { + $peek = $stream->peek(); + if ('#' == $peek) { + if ($hasHash) { + /* You can't have two hashes + (FIXME: is there some more general rule I'm missing?) */ + // @codeCoverageIgnoreStart + break; + // @codeCoverageIgnoreEnd + } + $stream->next(); + $result = new Node\HashNode($result, $stream->next()); + $hasHash = true; + + continue; + } elseif ('.' == $peek) { + $stream->next(); + $result = new Node\ClassNode($result, $stream->next()); + + continue; + } elseif ('[' == $peek) { + $stream->next(); + $result = $this->parseAttrib($result, $stream); + $next = $stream->next(); + if (']' != $next) { + throw new ParseException(sprintf("] expected, got '%s'", $next)); + } + + continue; + } elseif (':' == $peek || '::' == $peek) { + $type = $stream->next(); + $ident = $stream->next(); + if (!$ident || !$ident->isType('Symbol')) { + throw new ParseException(sprintf("Expected symbol, got '%s'", $ident)); + } + + if ($stream->peek() == '(') { + $stream->next(); + $peek = $stream->peek(); + if ($peek->isType('String')) { + $selector = $stream->next(); + } elseif ($peek->isType('Symbol') && is_int($peek)) { + $selector = intval($stream->next()); + } else { + // FIXME: parseSimpleSelector, or selector, or...? + $selector = $this->parseSimpleSelector($stream); + } + $next = $stream->next(); + if (')' != $next) { + throw new ParseException(sprintf("Expected ')', got '%s' and '%s'", $next, $selector)); + } + + $result = new Node\FunctionNode($result, $type, $ident, $selector); + } else { + $result = new Node\PseudoNode($result, $type, $ident); + } + + continue; + } else { + if (' ' == $peek) { + $stream->next(); + } + + break; + } + // FIXME: not sure what "negation" is + } + + return $result; + } + + /** + * Parses an attribute from a selector contained in $stream and returns + * the resulting AttribNode object. + * + * @param Node\NodeInterface $selector The selector object whose attribute + * is to be parsed. + * @param TokenStream $stream The container token stream. + * + * @return Node\AttribNode + * + * @throws ParseException When encountered unexpected selector + */ + private function parseAttrib($selector, $stream) + { + $attrib = $stream->next(); + if ($stream->peek() == '|') { + $namespace = $attrib; + $stream->next(); + $attrib = $stream->next(); + } else { + $namespace = '*'; + } + + if ($stream->peek() == ']') { + return new Node\AttribNode($selector, $namespace, $attrib, 'exists', null); + } + + $op = $stream->next(); + if (!in_array($op, array('^=', '$=', '*=', '=', '~=', '|=', '!='))) { + throw new ParseException(sprintf("Operator expected, got '%s'", $op)); + } + + $value = $stream->next(); + if (!$value->isType('Symbol') && !$value->isType('String')) { + throw new ParseException(sprintf("Expected string or symbol, got '%s'", $value)); + } + + return new Node\AttribNode($selector, $namespace, $attrib, $op, $value); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Exception/ParseException.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Exception/ParseException.php new file mode 100644 index 0000000..38206c2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Exception/ParseException.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\CssSelector\Exception; + +/** + * ParseException is thrown when a CSS selector syntax is not valid. + * + * This component is a port of the Python lxml library, + * which is copyright Infrae and distributed under the BSD license. + * + * @author Fabien Potencier + */ +class ParseException extends \Exception +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/LICENSE b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/LICENSE new file mode 100644 index 0000000..cdffe7a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 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/symfony/src/Symfony/Component/CssSelector/Node/AttribNode.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/AttribNode.php new file mode 100644 index 0000000..b89606e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/AttribNode.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\CssSelector\Node; + +use Symfony\Component\CssSelector\XPathExpr; +use Symfony\Component\CssSelector\Exception\ParseException; + +/** + * AttribNode represents a "selector[namespace|attrib operator value]" node. + * + * This component is a port of the Python lxml library, + * which is copyright Infrae and distributed under the BSD license. + * + * @author Fabien Potencier + */ +class AttribNode implements NodeInterface +{ + protected $selector; + protected $namespace; + protected $attrib; + protected $operator; + protected $value; + + /** + * Constructor. + * + * @param NodeInterface $selector The XPath selector + * @param string $namespace The namespace + * @param string $attrib The attribute + * @param string $operator The operator + * @param string $value The value + */ + public function __construct($selector, $namespace, $attrib, $operator, $value) + { + $this->selector = $selector; + $this->namespace = $namespace; + $this->attrib = $attrib; + $this->operator = $operator; + $this->value = $value; + } + + /** + * {@inheritDoc} + */ + public function __toString() + { + if ($this->operator == 'exists') { + return sprintf('%s[%s[%s]]', __CLASS__, $this->selector, $this->formatAttrib()); + } + + return sprintf('%s[%s[%s %s %s]]', __CLASS__, $this->selector, $this->formatAttrib(), $this->operator, $this->value); + } + + /** + * {@inheritDoc} + */ + public function toXpath() + { + $path = $this->selector->toXpath(); + $attrib = $this->xpathAttrib(); + $value = $this->value; + if ($this->operator == 'exists') { + $path->addCondition($attrib); + } elseif ($this->operator == '=') { + $path->addCondition(sprintf('%s = %s', $attrib, XPathExpr::xpathLiteral($value))); + } elseif ($this->operator == '!=') { + // FIXME: this seems like a weird hack... + if ($value) { + $path->addCondition(sprintf('not(%s) or %s != %s', $attrib, $attrib, XPathExpr::xpathLiteral($value))); + } else { + $path->addCondition(sprintf('%s != %s', $attrib, XPathExpr::xpathLiteral($value))); + } + // path.addCondition('%s != %s' % (attrib, xpathLiteral(value))) + } elseif ($this->operator == '~=') { + $path->addCondition(sprintf("contains(concat(' ', normalize-space(%s), ' '), %s)", $attrib, XPathExpr::xpathLiteral(' '.$value.' '))); + } elseif ($this->operator == '|=') { + // Weird, but true... + $path->addCondition(sprintf('%s = %s or starts-with(%s, %s)', $attrib, XPathExpr::xpathLiteral($value), $attrib, XPathExpr::xpathLiteral($value.'-'))); + } elseif ($this->operator == '^=') { + $path->addCondition(sprintf('starts-with(%s, %s)', $attrib, XPathExpr::xpathLiteral($value))); + } elseif ($this->operator == '$=') { + // Oddly there is a starts-with in XPath 1.0, but not ends-with + $path->addCondition(sprintf('substring(%s, string-length(%s)-%s) = %s', $attrib, $attrib, strlen($value) - 1, XPathExpr::xpathLiteral($value))); + } elseif ($this->operator == '*=') { + // FIXME: case sensitive? + $path->addCondition(sprintf('contains(%s, %s)', $attrib, XPathExpr::xpathLiteral($value))); + } else { + throw new ParseException(sprintf('Unknown operator: %s', $this->operator)); + } + + return $path; + } + + /** + * Returns the XPath Attribute + * + * @return string The XPath attribute + */ + protected function xpathAttrib() + { + // FIXME: if attrib is *? + if ($this->namespace == '*') { + return '@'.$this->attrib; + } + + return sprintf('@%s:%s', $this->namespace, $this->attrib); + } + + /** + * Returns a formatted attribute + * + * @return string The formatted attribute + */ + protected function formatAttrib() + { + if ($this->namespace == '*') { + return $this->attrib; + } + + return sprintf('%s|%s', $this->namespace, $this->attrib); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/ClassNode.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/ClassNode.php new file mode 100644 index 0000000..014aa80 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/ClassNode.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\CssSelector\Node; + +use Symfony\Component\CssSelector\XPathExpr; + +/** + * ClassNode represents a "selector.className" node. + * + * This component is a port of the Python lxml library, + * which is copyright Infrae and distributed under the BSD license. + * + * @author Fabien Potencier + */ +class ClassNode implements NodeInterface +{ + protected $selector; + protected $className; + + /** + * The constructor. + * + * @param NodeInterface $selector The XPath Selector + * @param string $className The class name + */ + public function __construct($selector, $className) + { + $this->selector = $selector; + $this->className = $className; + } + + /** + * {@inheritDoc} + */ + public function __toString() + { + return sprintf('%s[%s.%s]', __CLASS__, $this->selector, $this->className); + } + + /** + * {@inheritDoc} + */ + public function toXpath() + { + $selXpath = $this->selector->toXpath(); + $selXpath->addCondition(sprintf("contains(concat(' ', normalize-space(@class), ' '), %s)", XPathExpr::xpathLiteral(' '.$this->className.' '))); + + return $selXpath; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/CombinedSelectorNode.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/CombinedSelectorNode.php new file mode 100644 index 0000000..d37e4f1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/CombinedSelectorNode.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\CssSelector\Node; + +use Symfony\Component\CssSelector\Exception\ParseException; + +/** + * CombinedSelectorNode represents a combinator node. + * + * This component is a port of the Python lxml library, + * which is copyright Infrae and distributed under the BSD license. + * + * @author Fabien Potencier + */ +class CombinedSelectorNode implements NodeInterface +{ + static protected $methodMapping = array( + ' ' => 'descendant', + '>' => 'child', + '+' => 'direct_adjacent', + '~' => 'indirect_adjacent', + ); + + protected $selector; + protected $combinator; + protected $subselector; + + /** + * The constructor. + * + * @param NodeInterface $selector The XPath selector + * @param string $combinator The combinator + * @param NodeInterface $subselector The sub XPath selector + */ + public function __construct($selector, $combinator, $subselector) + { + $this->selector = $selector; + $this->combinator = $combinator; + $this->subselector = $subselector; + } + + /** + * {@inheritDoc} + */ + public function __toString() + { + $comb = $this->combinator == ' ' ? '' : $this->combinator; + + return sprintf('%s[%s %s %s]', __CLASS__, $this->selector, $comb, $this->subselector); + } + + /** + * {@inheritDoc} + * @throws ParseException When unknown combinator is found + */ + public function toXpath() + { + if (!isset(self::$methodMapping[$this->combinator])) { + throw new ParseException(sprintf('Unknown combinator: %s', $this->combinator)); + } + + $method = '_xpath_'.self::$methodMapping[$this->combinator]; + $path = $this->selector->toXpath(); + + return $this->$method($path, $this->subselector); + } + + /** + * Joins a NodeInterface into the XPath of this object. + * + * @param XPathExpr $xpath The XPath expression for this object + * @param NodeInterface $sub The NodeInterface object to add + * + * @return XPathExpr An XPath instance + */ + protected function _xpath_descendant($xpath, $sub) + { + // when sub is a descendant in any way of xpath + $xpath->join('/descendant::', $sub->toXpath()); + + return $xpath; + } + + /** + * Joins a NodeInterface as a child of this object. + * + * @param XPathExpr $xpath The parent XPath expression + * @param NodeInterface $sub The NodeInterface object to add + * + * @return XPathExpr An XPath instance + */ + protected function _xpath_child($xpath, $sub) + { + // when sub is an immediate child of xpath + $xpath->join('/', $sub->toXpath()); + + return $xpath; + } + + /** + * Joins an XPath expression as an adjacent of another. + * + * @param XPathExpr $xpath The parent XPath expression + * @param NodeInterface $sub The adjacent XPath expression + * + * @return XPathExpr An XPath instance + */ + protected function _xpath_direct_adjacent($xpath, $sub) + { + // when sub immediately follows xpath + $xpath->join('/following-sibling::', $sub->toXpath()); + $xpath->addNameTest(); + $xpath->addCondition('position() = 1'); + + return $xpath; + } + + /** + * Joins an XPath expression as an indirect adjacent of another. + * + * @param XPathExpr $xpath The parent XPath expression + * @param NodeInterface $sub The indirect adjacent NodeInterface object + * + * @return XPathExpr An XPath instance + */ + protected function _xpath_indirect_adjacent($xpath, $sub) + { + // when sub comes somewhere after xpath as a sibling + $xpath->join('/following-sibling::', $sub->toXpath()); + + return $xpath; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/ElementNode.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/ElementNode.php new file mode 100644 index 0000000..5cc7d4b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/ElementNode.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\CssSelector\Node; + +use Symfony\Component\CssSelector\XPathExpr; + +/** + * ElementNode represents a "namespace|element" node. + * + * This component is a port of the Python lxml library, + * which is copyright Infrae and distributed under the BSD license. + * + * @author Fabien Potencier + */ +class ElementNode implements NodeInterface +{ + protected $namespace; + protected $element; + + /** + * Constructor. + * + * @param string $namespace Namespace + * @param string $element Element + */ + public function __construct($namespace, $element) + { + $this->namespace = $namespace; + $this->element = $element; + } + + /** + * {@inheritDoc} + */ + public function __toString() + { + return sprintf('%s[%s]', __CLASS__, $this->formatElement()); + } + + /** + * Formats the element into a string. + * + * @return string Element as an XPath string + */ + public function formatElement() + { + if ($this->namespace == '*') { + return $this->element; + } + + return sprintf('%s|%s', $this->namespace, $this->element); + } + + /** + * {@inheritDoc} + */ + public function toXpath() + { + if ($this->namespace == '*') { + $el = strtolower($this->element); + } else { + // FIXME: Should we lowercase here? + $el = sprintf('%s:%s', $this->namespace, $this->element); + } + + return new XPathExpr(null, null, $el); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/FunctionNode.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/FunctionNode.php new file mode 100644 index 0000000..959f29d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/FunctionNode.php @@ -0,0 +1,290 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\CssSelector\Node; + +use Symfony\Component\CssSelector\Exception\ParseException; +use Symfony\Component\CssSelector\XPathExpr; + +/** + * FunctionNode represents a "selector:name(expr)" node. + * + * This component is a port of the Python lxml library, + * which is copyright Infrae and distributed under the BSD license. + * + * @author Fabien Potencier + */ +class FunctionNode implements NodeInterface +{ + static protected $unsupported = array('target', 'lang', 'enabled', 'disabled'); + + protected $selector; + protected $type; + protected $name; + protected $expr; + + /** + * Constructor. + * + * @param NodeInterface $selector The XPath expression + * @param string $type + * @param string $name + * @param XPathExpr $expr + */ + public function __construct($selector, $type, $name, $expr) + { + $this->selector = $selector; + $this->type = $type; + $this->name = $name; + $this->expr = $expr; + } + + /** + * {@inheritDoc} + */ + public function __toString() + { + return sprintf('%s[%s%s%s(%s)]', __CLASS__, $this->selector, $this->type, $this->name, $this->expr); + } + + /** + * {@inheritDoc} + * @throws ParseException When unsupported or unknown pseudo-class is found + */ + public function toXpath() + { + $selPath = $this->selector->toXpath(); + if (in_array($this->name, self::$unsupported)) { + throw new ParseException(sprintf('The pseudo-class %s is not supported', $this->name)); + } + $method = '_xpath_'.str_replace('-', '_', $this->name); + if (!method_exists($this, $method)) { + throw new ParseException(sprintf('The pseudo-class %s is unknown', $this->name)); + } + + return $this->$method($selPath, $this->expr); + } + + /** + * undocumented function + * + * @param XPathExpr $xpath + * @param mixed $expr + * @param Boolean $last + * @param Boolean $addNameTest + * + * @return XPathExpr + */ + protected function _xpath_nth_child($xpath, $expr, $last = false, $addNameTest = true) + { + list($a, $b) = $this->parseSeries($expr); + if (!$a && !$b && !$last) { + // a=0 means nothing is returned... + $xpath->addCondition('false() and position() = 0'); + + return $xpath; + } + + if ($addNameTest) { + $xpath->addNameTest(); + } + + $xpath->addStarPrefix(); + if ($a == 0) { + if ($last) { + $b = sprintf('last() - %s', $b); + } + $xpath->addCondition(sprintf('position() = %s', $b)); + + return $xpath; + } + + if ($last) { + // FIXME: I'm not sure if this is right + $a = -$a; + $b = -$b; + } + + if ($b > 0) { + $bNeg = -$b; + } else { + $bNeg = sprintf('+%s', -$b); + } + + if ($a != 1) { + $expr = array(sprintf('(position() %s) mod %s = 0', $bNeg, $a)); + } else { + $expr = array(); + } + + if ($b >= 0) { + $expr[] = sprintf('position() >= %s', $b); + } elseif ($b < 0 && $last) { + $expr[] = sprintf('position() < (last() %s)', $b); + } + $expr = implode($expr, ' and '); + + if ($expr) { + $xpath->addCondition($expr); + } + + return $xpath; + /* FIXME: handle an+b, odd, even + an+b means every-a, plus b, e.g., 2n+1 means odd + 0n+b means b + n+0 means a=1, i.e., all elements + an means every a elements, i.e., 2n means even + -n means -1n + -1n+6 means elements 6 and previous */ + } + + /** + * undocumented function + * + * @param XPathExpr $xpath + * @param XPathExpr $expr + * + * @return XPathExpr + */ + protected function _xpath_nth_last_child($xpath, $expr) + { + return $this->_xpath_nth_child($xpath, $expr, true); + } + + /** + * undocumented function + * + * @param XPathExpr $xpath + * @param XPathExpr $expr + * + * @return XPathExpr + */ + protected function _xpath_nth_of_type($xpath, $expr) + { + if ($xpath->getElement() == '*') { + throw new ParseException('*:nth-of-type() is not implemented'); + } + + return $this->_xpath_nth_child($xpath, $expr, false, false); + } + + /** + * undocumented function + * + * @param XPathExpr $xpath + * @param XPathExpr $expr + * + * @return XPathExpr + */ + protected function _xpath_nth_last_of_type($xpath, $expr) + { + return $this->_xpath_nth_child($xpath, $expr, true, false); + } + + /** + * undocumented function + * + * @param XPathExpr $xpath + * @param XPathExpr $expr + * + * @return XPathExpr + */ + protected function _xpath_contains($xpath, $expr) + { + // text content, minus tags, must contain expr + if ($expr instanceof ElementNode) { + $expr = $expr->formatElement(); + } + + // FIXME: lower-case is only available with XPath 2 + //$xpath->addCondition(sprintf('contains(lower-case(string(.)), %s)', XPathExpr::xpathLiteral(strtolower($expr)))); + $xpath->addCondition(sprintf('contains(string(.), %s)', XPathExpr::xpathLiteral($expr))); + + // FIXME: Currently case insensitive matching doesn't seem to be happening + + return $xpath; + } + + /** + * undocumented function + * + * @param XPathExpr $xpath + * @param XPathExpr $expr + * + * @return XPathExpr + */ + protected function _xpath_not($xpath, $expr) + { + // everything for which not expr applies + $expr = $expr->toXpath(); + $cond = $expr->getCondition(); + // FIXME: should I do something about element_path? + $xpath->addCondition(sprintf('not(%s)', $cond)); + + return $xpath; + } + + /** + * Parses things like '1n+2', or 'an+b' generally, returning (a, b) + * + * @param mixed $s + * + * @return array + */ + protected function parseSeries($s) + { + if ($s instanceof ElementNode) { + $s = $s->formatElement(); + } + + if (!$s || '*' == $s) { + // Happens when there's nothing, which the CSS parser thinks of as * + return array(0, 0); + } + + if ('odd' == $s) { + return array(2, 1); + } + + if ('even' == $s) { + return array(2, 0); + } + + if ('n' == $s) { + return array(1, 0); + } + + if (false === strpos($s, 'n')) { + // Just a b + + return array(0, intval((string) $s)); + } + + list($a, $b) = explode('n', $s); + if (!$a) { + $a = 1; + } elseif ('-' == $a || '+' == $a) { + $a = intval($a.'1'); + } else { + $a = intval($a); + } + + if (!$b) { + $b = 0; + } elseif ('-' == $b || '+' == $b) { + $b = intval($b.'1'); + } else { + $b = intval($b); + } + + return array($a, $b); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/HashNode.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/HashNode.php new file mode 100644 index 0000000..87a6590 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/HashNode.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\CssSelector\Node; + +use Symfony\Component\CssSelector\XPathExpr; + +/** + * HashNode represents a "selector#id" node. + * + * This component is a port of the Python lxml library, + * which is copyright Infrae and distributed under the BSD license. + * + * @author Fabien Potencier + */ +class HashNode implements NodeInterface +{ + protected $selector; + protected $id; + + /** + * Constructor. + * + * @param NodeInterface $selector The NodeInterface object + * @param string $id The ID + */ + public function __construct($selector, $id) + { + $this->selector = $selector; + $this->id = $id; + } + + /** + * {@inheritDoc} + */ + public function __toString() + { + return sprintf('%s[%s#%s]', __CLASS__, $this->selector, $this->id); + } + + /** + * {@inheritDoc} + */ + public function toXpath() + { + $path = $this->selector->toXpath(); + $path->addCondition(sprintf('@id = %s', XPathExpr::xpathLiteral($this->id))); + + return $path; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/NodeInterface.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/NodeInterface.php new file mode 100644 index 0000000..534f0dd --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/NodeInterface.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\CssSelector\Node; + +/** + * ClassNode represents a "selector.className" node. + * + * This component is a port of the Python lxml library, + * which is copyright Infrae and distributed under the BSD license. + * + * @author Fabien Potencier + */ +interface NodeInterface +{ + /** + * Returns a string representation of the object. + * + * @return string The string representation + */ + function __toString(); + + /** + * @return XPathExpr The XPath expression + * + * @throws ParseException When unknown operator is found + */ + function toXpath(); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/OrNode.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/OrNode.php new file mode 100644 index 0000000..dc047a3 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/OrNode.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\CssSelector\Node; + +use Symfony\Component\CssSelector\XPathExprOr; + +/** + * OrNode represents a "Or" node. + * + * This component is a port of the Python lxml library, + * which is copyright Infrae and distributed under the BSD license. + * + * @author Fabien Potencier + */ +class OrNode implements NodeInterface +{ + protected $items; + + /** + * Constructor. + * + * @param array $items An array of NodeInterface objects + */ + public function __construct($items) + { + $this->items = $items; + } + + /** + * {@inheritDoc} + */ + public function __toString() + { + return sprintf('%s(%s)', __CLASS__, $this->items); + } + + /** + * {@inheritDoc} + */ + public function toXpath() + { + $paths = array(); + foreach ($this->items as $item) { + $paths[] = $item->toXpath(); + } + + return new XPathExprOr($paths); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/PseudoNode.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/PseudoNode.php new file mode 100644 index 0000000..3f93b70 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Node/PseudoNode.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\CssSelector\Node; + +use Symfony\Component\CssSelector\Exception\ParseException; + +/** + * PseudoNode represents a "selector:ident" node. + * + * This component is a port of the Python lxml library, + * which is copyright Infrae and distributed under the BSD license. + * + * @author Fabien Potencier + */ +class PseudoNode implements NodeInterface +{ + static protected $unsupported = array( + 'indeterminate', 'first-line', 'first-letter', + 'selection', 'before', 'after', 'link', 'visited', + 'active', 'focus', 'hover', + ); + + protected $element; + protected $type; + protected $ident; + + /** + * Constructor. + * + * @param NodeInterface $element The NodeInterface element + * @param string $type Node type + * @param string $ident The ident + * + * @throws ParseException When incorrect PseudoNode type is given + */ + public function __construct($element, $type, $ident) + { + $this->element = $element; + + if (!in_array($type, array(':', '::'))) { + throw new ParseException(sprintf('The PseudoNode type can only be : or :: (%s given).', $type)); + } + + $this->type = $type; + $this->ident = $ident; + } + + /** + * {@inheritDoc} + */ + public function __toString() + { + return sprintf('%s[%s%s%s]', __CLASS__, $this->element, $this->type, $this->ident); + } + + /** + * {@inheritDoc} + * @throws ParseException When unsupported or unknown pseudo-class is found + */ + public function toXpath() + { + $elXpath = $this->element->toXpath(); + + if (in_array($this->ident, self::$unsupported)) { + throw new ParseException(sprintf('The pseudo-class %s is unsupported', $this->ident)); + } + $method = 'xpath_'.str_replace('-', '_', $this->ident); + if (!method_exists($this, $method)) { + throw new ParseException(sprintf('The pseudo-class %s is unknown', $this->ident)); + } + + return $this->$method($elXpath); + } + + /** + * @param XPathExpr $xpath The XPath expression + * + * @return XPathExpr The modified XPath expression + */ + protected function xpath_checked($xpath) + { + // FIXME: is this really all the elements? + $xpath->addCondition("(@selected or @checked) and (name(.) = 'input' or name(.) = 'option')"); + + return $xpath; + } + + /** + * @param XPathExpr $xpath The XPath expression + * + * @return XPathExpr The modified XPath expression + * + * @throws ParseException If this element is the root element + */ + protected function xpath_root($xpath) + { + // if this element is the root element + throw new ParseException(); + } + + /** + * Marks this XPath expression as the first child. + * + * @param XPathExpr $xpath The XPath expression + * + * @return XPathExpr The modified expression + */ + protected function xpath_first_child($xpath) + { + $xpath->addStarPrefix(); + $xpath->addNameTest(); + $xpath->addCondition('position() = 1'); + + return $xpath; + } + + /** + * Sets the XPath to be the last child. + * + * @param XPathExpr $xpath The XPath expression + * + * @return XPathExpr The modified expression + */ + protected function xpath_last_child($xpath) + { + $xpath->addStarPrefix(); + $xpath->addNameTest(); + $xpath->addCondition('position() = last()'); + + return $xpath; + } + + /** + * Sets the XPath expression to be the first of type. + * + * @param XPathExpr $xpath The XPath expression + * + * @return XPathExpr The modified expression + */ + protected function xpath_first_of_type($xpath) + { + if ($xpath->getElement() == '*') { + throw new ParseException('*:first-of-type is not implemented'); + } + $xpath->addStarPrefix(); + $xpath->addCondition('position() = 1'); + + return $xpath; + } + + /** + * Sets the XPath expression to be the last of type. + * + * @param XPathExpr $xpath The XPath expression + * + * @return XPathExpr The modified expression + * + * @throws ParseException Because *:last-of-type is not implemented + */ + protected function xpath_last_of_type($xpath) + { + if ($xpath->getElement() == '*') { + throw new ParseException('*:last-of-type is not implemented'); + } + $xpath->addStarPrefix(); + $xpath->addCondition('position() = last()'); + + return $xpath; + } + + /** + * Sets the XPath expression to be the only child. + * + * @param XPathExpr $xpath The XPath expression + * + * @return XPathExpr The modified expression + */ + protected function xpath_only_child($xpath) + { + $xpath->addNameTest(); + $xpath->addStarPrefix(); + $xpath->addCondition('last() = 1'); + + return $xpath; + } + + /** + * Sets the XPath expression to be only of type. + * + * @param XPathExpr $xpath The XPath expression + * + * @return XPathExpr The modified expression + * + * @throws ParseException Because *:only-of-type is not implemented + */ + protected function xpath_only_of_type($xpath) + { + if ($xpath->getElement() == '*') { + throw new ParseException('*:only-of-type is not implemented'); + } + $xpath->addCondition('last() = 1'); + + return $xpath; + } + + /** + * undocumented function + * + * @param XPathExpr $xpath The XPath expression + * + * @return XPathExpr The modified expression + */ + protected function xpath_empty($xpath) + { + $xpath->addCondition('not(*) and not(normalize-space())'); + + return $xpath; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/README.md b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/README.md new file mode 100644 index 0000000..dd92f7a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/README.md @@ -0,0 +1,23 @@ +CssSelector Component +===================== + +CssSelector converts CSS selectors to XPath expressions. + +The component only goal is to convert CSS selectors to their XPath +equivalents: + + use Symfony\Component\CssSelector\CssSelector; + + print CssSelector::toXPath('div.item > h4 > a'); + +Resources +--------- + +This component is a port of the Python lxml library, which is copyright Infrae +and distributed under the BSD license. + +Current code is a port of https://github.com/SimonSapin/cssselect@fd2e70 + +You can run the unit tests with the following command: + + phpunit diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/CssSelectorTest.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/CssSelectorTest.php new file mode 100644 index 0000000..0d9ca85 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/CssSelectorTest.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\CssSelector\Tests; + +use Symfony\Component\CssSelector\CssSelector; + +class CssSelectorTest extends \PHPUnit_Framework_TestCase +{ + public function testCsstoXPath() + { + $this->assertEquals('descendant-or-self::*', CssSelector::toXPath('')); + $this->assertEquals('descendant-or-self::h1', CssSelector::toXPath('h1')); + $this->assertEquals("descendant-or-self::h1[@id = 'foo']", CssSelector::toXPath('h1#foo')); + $this->assertEquals("descendant-or-self::h1[contains(concat(' ', normalize-space(@class), ' '), ' foo ')]", CssSelector::toXPath('h1.foo')); + + $this->assertEquals('descendant-or-self::foo:h1', CssSelector::toXPath('foo|h1')); + } + + /** + * @dataProvider getCssSelectors + */ + public function testParse($css, $xpath) + { + $parser = new CssSelector(); + + $this->assertEquals($xpath, (string) $parser->parse($css)->toXPath(), '->parse() parses an input string and returns a node'); + } + + public function testParseExceptions() + { + $parser = new CssSelector(); + + try { + $parser->parse('h1:'); + $this->fail('->parse() throws an Exception if the css selector is not valid'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Symfony\Component\CssSelector\Exception\ParseException', $e, '->parse() throws an Exception if the css selector is not valid'); + $this->assertEquals("Expected symbol, got '' at h1: -> ", $e->getMessage(), '->parse() throws an Exception if the css selector is not valid'); + } + } + + public function getCssSelectors() + { + return array( + array('h1', "h1"), + array('foo|h1', "foo:h1"), + array('h1, h2, h3', "h1 | h2 | h3"), + array('h1:nth-child(3n+1)', "*/*[name() = 'h1' and ((position() -1) mod 3 = 0 and position() >= 1)]"), + array('h1 > p', "h1/p"), + array('h1#foo', "h1[@id = 'foo']"), + array('h1.foo', "h1[contains(concat(' ', normalize-space(@class), ' '), ' foo ')]"), + array('h1[class*="foo bar"]', "h1[contains(@class, 'foo bar')]"), + array('h1[foo|class*="foo bar"]', "h1[contains(@foo:class, 'foo bar')]"), + array('h1[class]', "h1[@class]"), + array('h1 .foo', "h1/descendant::*[contains(concat(' ', normalize-space(@class), ' '), ' foo ')]"), + array('h1 #foo', "h1/descendant::*[@id = 'foo']"), + array('h1 [class*=foo]', "h1/descendant::*[contains(@class, 'foo')]"), + array('div>.foo', "div/*[contains(concat(' ', normalize-space(@class), ' '), ' foo ')]"), + array('div > .foo', "div/*[contains(concat(' ', normalize-space(@class), ' '), ' foo ')]"), + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/AttribNodeTest.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/AttribNodeTest.php new file mode 100644 index 0000000..2f19fe2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/AttribNodeTest.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\CssSelector\Tests\Node; + +use Symfony\Component\CssSelector\Node\AttribNode; +use Symfony\Component\CssSelector\Node\ElementNode; + +class AttribNodeTest extends \PHPUnit_Framework_TestCase +{ + public function testToXpath() + { + $element = new ElementNode('*', 'h1'); + + $operators = array( + '^=' => "h1[starts-with(@class, 'foo')]", + '$=' => "h1[substring(@class, string-length(@class)-2) = 'foo']", + '*=' => "h1[contains(@class, 'foo')]", + '=' => "h1[@class = 'foo']", + '~=' => "h1[contains(concat(' ', normalize-space(@class), ' '), ' foo ')]", + '|=' => "h1[@class = 'foo' or starts-with(@class, 'foo-')]", + '!=' => "h1[not(@class) or @class != 'foo']", + ); + + // h1[class??foo] + foreach ($operators as $op => $xpath) { + $attrib = new AttribNode($element, '*', 'class', $op, 'foo'); + $this->assertEquals($xpath, (string) $attrib->toXpath(), '->toXpath() returns the xpath representation of the node'); + } + + // h1[class] + $attrib = new AttribNode($element, '*', 'class', 'exists', 'foo'); + $this->assertEquals('h1[@class]', (string) $attrib->toXpath(), '->toXpath() returns the xpath representation of the node'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/ClassNodeTest.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/ClassNodeTest.php new file mode 100644 index 0000000..c0a96f1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/ClassNodeTest.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\CssSelector\Tests\Node; + +use Symfony\Component\CssSelector\Node\ClassNode; +use Symfony\Component\CssSelector\Node\ElementNode; + +class ClassNodeTest extends \PHPUnit_Framework_TestCase +{ + public function testToXpath() + { + // h1.foo + $element = new ElementNode('*', 'h1'); + $class = new ClassNode($element, 'foo'); + + $this->assertEquals("h1[contains(concat(' ', normalize-space(@class), ' '), ' foo ')]", (string) $class->toXpath(), '->toXpath() returns the xpath representation of the node'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/CombinedSelectorNodeTest.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/CombinedSelectorNodeTest.php new file mode 100644 index 0000000..28f4e28 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/CombinedSelectorNodeTest.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\CssSelector\Tests\Node; + +use Symfony\Component\CssSelector\Node\CombinedSelectorNode; +use Symfony\Component\CssSelector\Node\ElementNode; + +class CombinedSelectorNodeTest extends \PHPUnit_Framework_TestCase +{ + public function testToXpath() + { + $combinators = array( + ' ' => "h1/descendant::p", + '>' => "h1/p", + '+' => "h1/following-sibling::*[name() = 'p' and (position() = 1)]", + '~' => "h1/following-sibling::p", + ); + + // h1 ?? p + $element1 = new ElementNode('*', 'h1'); + $element2 = new ElementNode('*', 'p'); + foreach ($combinators as $combinator => $xpath) { + $combinator = new CombinedSelectorNode($element1, $combinator, $element2); + $this->assertEquals($xpath, (string) $combinator->toXpath(), '->toXpath() returns the xpath representation of the node'); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/ElementNodeTest.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/ElementNodeTest.php new file mode 100644 index 0000000..5d23e3f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/ElementNodeTest.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\CssSelector\Tests\Node; + +use Symfony\Component\CssSelector\Node\ElementNode; + +class ElementNodeTest extends \PHPUnit_Framework_TestCase +{ + public function testToXpath() + { + // h1 + $element = new ElementNode('*', 'h1'); + + $this->assertEquals('h1', (string) $element->toXpath(), '->toXpath() returns the xpath representation of the node'); + + // foo|h1 + $element = new ElementNode('foo', 'h1'); + + $this->assertEquals('foo:h1', (string) $element->toXpath(), '->toXpath() returns the xpath representation of the node'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/FunctionNodeTest.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/FunctionNodeTest.php new file mode 100644 index 0000000..9654402 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/FunctionNodeTest.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\CssSelector\Tests\Node; + +use Symfony\Component\CssSelector\Node\FunctionNode; +use Symfony\Component\CssSelector\Node\ElementNode; +use Symfony\Component\CssSelector\Token; + +class FunctionNodeTest extends \PHPUnit_Framework_TestCase +{ + public function testToXpath() + { + $element = new ElementNode('*', 'h1'); + + // h1:contains("foo") + $function = new FunctionNode($element, ':', 'contains', 'foo'); + $this->assertEquals("h1[contains(string(.), 'foo')]", (string) $function->toXpath(), '->toXpath() returns the xpath representation of the node'); + + // h1:nth-child(1) + $function = new FunctionNode($element, ':', 'nth-child', 1); + $this->assertEquals("*/*[name() = 'h1' and (position() = 1)]", (string) $function->toXpath(), '->toXpath() returns the xpath representation of the node'); + + // h1:nth-child() + $function = new FunctionNode($element, ':', 'nth-child', ''); + $this->assertEquals("h1[false() and position() = 0]", (string) $function->toXpath(), '->toXpath() returns the xpath representation of the node'); + + // h1:nth-child(odd) + $element2 = new ElementNode('*', new Token('Symbol', 'odd', -1)); + $function = new FunctionNode($element, ':', 'nth-child', $element2); + $this->assertEquals("*/*[name() = 'h1' and ((position() -1) mod 2 = 0 and position() >= 1)]", (string) $function->toXpath(), '->toXpath() returns the xpath representation of the node'); + + // h1:nth-child(even) + $element2 = new ElementNode('*', new Token('Symbol', 'even', -1)); + $function = new FunctionNode($element, ':', 'nth-child', $element2); + $this->assertEquals("*/*[name() = 'h1' and ((position() +0) mod 2 = 0 and position() >= 0)]", (string) $function->toXpath(), '->toXpath() returns the xpath representation of the node'); + + // h1:nth-child(n) + $element2 = new ElementNode('*', new Token('Symbol', 'n', -1)); + $function = new FunctionNode($element, ':', 'nth-child', $element2); + $this->assertEquals("*/*[name() = 'h1' and (position() >= 0)]", (string) $function->toXpath(), '->toXpath() returns the xpath representation of the node'); + + // h1:nth-child(3n+1) + $element2 = new ElementNode('*', new Token('Symbol', '3n+1', -1)); + $function = new FunctionNode($element, ':', 'nth-child', $element2); + $this->assertEquals("*/*[name() = 'h1' and ((position() -1) mod 3 = 0 and position() >= 1)]", (string) $function->toXpath(), '->toXpath() returns the xpath representation of the node'); + + // h1:nth-child(n+1) + $element2 = new ElementNode('*', new Token('Symbol', 'n+1', -1)); + $function = new FunctionNode($element, ':', 'nth-child', $element2); + $this->assertEquals("*/*[name() = 'h1' and (position() >= 1)]", (string) $function->toXpath(), '->toXpath() returns the xpath representation of the node'); + + // h1:nth-child(1) + $element2 = new ElementNode('*', new Token('Symbol', '2', -1)); + $function = new FunctionNode($element, ':', 'nth-child', $element2); + $this->assertEquals("*/*[name() = 'h1' and (position() = 2)]", (string) $function->toXpath(), '->toXpath() returns the xpath representation of the node'); + + // h1:nth-child(2n) + $element2 = new ElementNode('*', new Token('Symbol', '2n', -1)); + $function = new FunctionNode($element, ':', 'nth-child', $element2); + $this->assertEquals("*/*[name() = 'h1' and ((position() +0) mod 2 = 0 and position() >= 0)]", (string) $function->toXpath(), '->toXpath() returns the xpath representation of the node'); + + // h1:nth-child(-n) + $element2 = new ElementNode('*', new Token('Symbol', '-n', -1)); + $function = new FunctionNode($element, ':', 'nth-child', $element2); + $this->assertEquals("*/*[name() = 'h1' and ((position() +0) mod -1 = 0 and position() >= 0)]", (string) $function->toXpath(), '->toXpath() returns the xpath representation of the node'); + + // h1:nth-last-child(2) + $function = new FunctionNode($element, ':', 'nth-last-child', 2); + $this->assertEquals("*/*[name() = 'h1' and (position() = last() - 2)]", (string) $function->toXpath(), '->toXpath() returns the xpath representation of the node'); + + // h1:nth-of-type(2) + $function = new FunctionNode($element, ':', 'nth-of-type', 2); + $this->assertEquals("*/h1[position() = 2]", (string) $function->toXpath(), '->toXpath() returns the xpath representation of the node'); + + // h1:nth-last-of-type(2) + $function = new FunctionNode($element, ':', 'nth-last-of-type', 2); + $this->assertEquals("*/h1[position() = last() - 2]", (string) $function->toXpath(), '->toXpath() returns the xpath representation of the node'); + + /* + // h1:not(p) + $element2 = new ElementNode('*', 'p'); + $function = new FunctionNode($element, ':', 'not', $element2); + + $this->assertEquals("h1[not()]", (string) $function->toXpath(), '->toXpath() returns the xpath representation of the node'); + */ + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/HashNodeTest.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/HashNodeTest.php new file mode 100644 index 0000000..d919747 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/HashNodeTest.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\CssSelector\Tests\Node; + +use Symfony\Component\CssSelector\Node\HashNode; +use Symfony\Component\CssSelector\Node\ElementNode; + +class HashNodeTest extends \PHPUnit_Framework_TestCase +{ + public function testToXpath() + { + // h1#foo + $element = new ElementNode('*', 'h1'); + $hash = new HashNode($element, 'foo'); + + $this->assertEquals("h1[@id = 'foo']", (string) $hash->toXpath(), '->toXpath() returns the xpath representation of the node'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/OrNodeTest.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/OrNodeTest.php new file mode 100644 index 0000000..9b9e6e3 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/OrNodeTest.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\CssSelector\Tests\Node; + +use Symfony\Component\CssSelector\Node\OrNode; +use Symfony\Component\CssSelector\Node\ElementNode; + +class OrNodeTest extends \PHPUnit_Framework_TestCase +{ + public function testToXpath() + { + // h1, h2, h3 + $element1 = new ElementNode('*', 'h1'); + $element2 = new ElementNode('*', 'h2'); + $element3 = new ElementNode('*', 'h3'); + $or = new OrNode(array($element1, $element2, $element3)); + + $this->assertEquals("h1 | h2 | h3", (string) $or->toXpath(), '->toXpath() returns the xpath representation of the node'); + } + + public function testIssueMissingPrefix() + { + // h1, h2, h3 + $element1 = new ElementNode('*', 'h1'); + $element2 = new ElementNode('*', 'h2'); + $element3 = new ElementNode('*', 'h3'); + $or = new OrNode(array($element1, $element2, $element3)); + + $xPath = $or->toXPath(); + $xPath->addPrefix('descendant-or-self::'); + + $this->assertEquals("descendant-or-self::h1 | descendant-or-self::h2 | descendant-or-self::h3", (string) $xPath); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/PseudoNodeTest.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/PseudoNodeTest.php new file mode 100644 index 0000000..8bd0cec --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/Node/PseudoNodeTest.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\CssSelector\Tests\Node; + +use Symfony\Component\CssSelector\Node\PseudoNode; +use Symfony\Component\CssSelector\Node\ElementNode; + +class PseudoNodeTest extends \PHPUnit_Framework_TestCase +{ + public function testToXpath() + { + $element = new ElementNode('*', 'h1'); + + // h1:checked + $pseudo = new PseudoNode($element, ':', 'checked'); + $this->assertEquals("h1[(@selected or @checked) and (name(.) = 'input' or name(.) = 'option')]", (string) $pseudo->toXpath(), '->toXpath() returns the xpath representation of the node'); + + // h1:first-child + $pseudo = new PseudoNode($element, ':', 'first-child'); + $this->assertEquals("*/*[name() = 'h1' and (position() = 1)]", (string) $pseudo->toXpath(), '->toXpath() returns the xpath representation of the node'); + + // h1:last-child + $pseudo = new PseudoNode($element, ':', 'last-child'); + $this->assertEquals("*/*[name() = 'h1' and (position() = last())]", (string) $pseudo->toXpath(), '->toXpath() returns the xpath representation of the node'); + + // h1:first-of-type + $pseudo = new PseudoNode($element, ':', 'first-of-type'); + $this->assertEquals("*/h1[position() = 1]", (string) $pseudo->toXpath(), '->toXpath() returns the xpath representation of the node'); + + // h1:last-of-type + $pseudo = new PseudoNode($element, ':', 'last-of-type'); + $this->assertEquals("*/h1[position() = last()]", (string) $pseudo->toXpath(), '->toXpath() returns the xpath representation of the node'); + + // h1:only-child + $pseudo = new PseudoNode($element, ':', 'only-child'); + $this->assertEquals("*/*[name() = 'h1' and (last() = 1)]", (string) $pseudo->toXpath(), '->toXpath() returns the xpath representation of the node'); + + // h1:only-of-type + $pseudo = new PseudoNode($element, ':', 'only-of-type'); + $this->assertEquals("h1[last() = 1]", (string) $pseudo->toXpath(), '->toXpath() returns the xpath representation of the node'); + + // h1:empty + $pseudo = new PseudoNode($element, ':', 'empty'); + $this->assertEquals("h1[not(*) and not(normalize-space())]", (string) $pseudo->toXpath(), '->toXpath() returns the xpath representation of the node'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/TokenizerTest.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/TokenizerTest.php new file mode 100644 index 0000000..6c559b4 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/TokenizerTest.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\CssSelector\Tests; + +use Symfony\Component\CssSelector\Tokenizer; + +class TokenizerTest extends \PHPUnit_Framework_TestCase +{ + protected $tokenizer; + + protected function setUp() + { + $this->tokenizer = new Tokenizer(); + } + + /** + * @dataProvider getCssSelectors + */ + public function testTokenize($css) + { + $this->assertEquals($css, $this->tokensToString($this->tokenizer->tokenize($css)), '->tokenize() lexes an input string and returns an array of tokens'); + } + + public function testTokenizeWithQuotedStrings() + { + $this->assertEquals('foo[class=foo bar ]', $this->tokensToString($this->tokenizer->tokenize('foo[class="foo bar"]')), '->tokenize() lexes an input string and returns an array of tokens'); + $this->assertEquals("foo[class=foo Abar ]", $this->tokensToString($this->tokenizer->tokenize('foo[class="foo \\65 bar"]')), '->tokenize() lexes an input string and returns an array of tokens'); + } + + /** + * @expectedException Symfony\Component\CssSelector\Exception\ParseException + */ + public function testTokenizeInvalidString() + { + $this->tokensToString($this->tokenizer->tokenize('/invalid')); + } + + public function getCssSelectors() + { + return array( + array('h1'), + array('h1:nth-child(3n+1)'), + array('h1 > p'), + array('h1#foo'), + array('h1.foo'), + array('h1[class*=foo]'), + array('h1 .foo'), + array('h1 #foo'), + array('h1 [class*=foo]'), + ); + } + + protected function tokensToString($tokens) + { + $str = ''; + foreach ($tokens as $token) { + $str .= str_repeat(' ', $token->getPosition() - strlen($str)).$token; + } + + return $str; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/XPathExprTest.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/XPathExprTest.php new file mode 100644 index 0000000..df6e5a0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/XPathExprTest.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\CssSelector\Tests; + +use Symfony\Component\CssSelector\XPathExpr; + +class XPathExprTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getXPathLiteralValues + */ + public function testXpathLiteral($value, $literal) + { + $this->assertEquals($literal, XPathExpr::xpathLiteral($value)); + } + + public function getXPathLiteralValues() + { + return array( + array('foo', "'foo'"), + array("foo's bar", '"foo\'s bar"'), + array("foo's \"middle\" bar", 'concat(\'foo\', "\'", \'s "middle" bar\')'), + array("foo's 'middle' \"bar\"", 'concat(\'foo\', "\'", \'s \', "\'", \'middle\', "\'", \' "bar"\')'), + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/bootstrap.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/bootstrap.php new file mode 100644 index 0000000..d2c7d08 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tests/bootstrap.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +spl_autoload_register(function ($class) { + if (0 === strpos(ltrim($class, '/'), 'Symfony\Component\CssSelector')) { + if (file_exists($file = __DIR__.'/../'.substr(str_replace('\\', '/', $class), strlen('Symfony\Component\CssSelector')).'.php')) { + require_once $file; + } + } +}); diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Token.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Token.php new file mode 100644 index 0000000..6748a44 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Token.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\CssSelector; + +/** + * Token represents a CSS Selector token. + * + * This component is a port of the Python lxml library, + * which is copyright Infrae and distributed under the BSD license. + * + * @author Fabien Potencier + */ +class Token +{ + private $type; + private $value; + private $position; + + /** + * Constructor. + * + * @param string $type The type of this token. + * @param mixed $value The value of this token. + * @param integer $position The order of this token. + */ + public function __construct($type, $value, $position) + { + $this->type = $type; + $this->value = $value; + $this->position = $position; + } + + /** + * Gets a string representation of this token. + * + * @return string + */ + public function __toString() + { + return (string) $this->value; + } + + /** + * Answers whether this token's type equals to $type. + * + * @param string $type The type to test against this token's one. + * + * @return Boolean + */ + public function isType($type) + { + return $this->type == $type; + } + + /** + * Gets the position of this token. + * + * @return integer + */ + public function getPosition() + { + return $this->position; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/TokenStream.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/TokenStream.php new file mode 100644 index 0000000..cf04702 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/TokenStream.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\CssSelector; + +/** + * TokenStream represents a stream of CSS Selector tokens. + * + * This component is a port of the Python lxml library, + * which is copyright Infrae and distributed under the BSD license. + * + * @author Fabien Potencier + */ +class TokenStream +{ + private $used; + private $tokens; + private $source; + private $peeked; + private $peeking; + + /** + * Constructor. + * + * @param array $tokens The tokens that make the stream. + * @param mixed $source The source of the stream. + */ + public function __construct($tokens, $source = null) + { + $this->used = array(); + $this->tokens = $tokens; + $this->source = $source; + $this->peeked = null; + $this->peeking = false; + } + + /** + * Gets the tokens that have already been visited in this stream. + * + * @return array + */ + public function getUsed() + { + return $this->used; + } + + /** + * Gets the next token in the stream or null if there is none. + * Note that if this stream was set to be peeking its behavior + * will be restored to not peeking after this operation. + * + * @return mixed + */ + public function next() + { + if ($this->peeking) { + $this->peeking = false; + $this->used[] = $this->peeked; + + return $this->peeked; + } + + if (!count($this->tokens)) { + return null; + } + + $next = array_shift($this->tokens); + $this->used[] = $next; + + return $next; + } + + /** + * Peeks for the next token in this stream. This means that the next token + * will be returned but it won't be considered as used (visited) until the + * next() method is invoked. + * If there are no remaining tokens null will be returned. + * + * @see next() + * + * @return mixed + */ + public function peek() + { + if (!$this->peeking) { + if (!count($this->tokens)) { + return null; + } + + $this->peeked = array_shift($this->tokens); + + $this->peeking = true; + } + + return $this->peeked; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tokenizer.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tokenizer.php new file mode 100644 index 0000000..67d5b67 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/Tokenizer.php @@ -0,0 +1,201 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\CssSelector; + +use Symfony\Component\CssSelector\Exception\ParseException; + +/** + * Tokenizer lexes a CSS Selector to tokens. + * + * This component is a port of the Python lxml library, + * which is copyright Infrae and distributed under the BSD license. + * + * @author Fabien Potencier + */ +class Tokenizer +{ + /** + * Takes a CSS selector and returns an array holding the Tokens + * it contains. + * + * @param string $s The selector to lex. + * + * @return array Token[] + */ + public function tokenize($s) + { + if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) { + $mbEncoding = mb_internal_encoding(); + mb_internal_encoding('ASCII'); + } + + $tokens = array(); + $pos = 0; + $s = preg_replace('#/\*.*?\*/#s', '', $s); + + while (true) { + if (preg_match('#\s+#A', $s, $match, 0, $pos)) { + $precedingWhitespacePos = $pos; + $pos += strlen($match[0]); + } else { + $precedingWhitespacePos = 0; + } + + if ($pos >= strlen($s)) { + if (isset($mbEncoding)) { + mb_internal_encoding($mbEncoding); + } + + return $tokens; + } + + if (preg_match('#[+-]?\d*n(?:[+-]\d+)?#A', $s, $match, 0, $pos) && 'n' !== $match[0]) { + $sym = substr($s, $pos, strlen($match[0])); + $tokens[] = new Token('Symbol', $sym, $pos); + $pos += strlen($match[0]); + + continue; + } + + $c = $s[$pos]; + $c2 = substr($s, $pos, 2); + if (in_array($c2, array('~=', '|=', '^=', '$=', '*=', '::', '!='))) { + $tokens[] = new Token('Token', $c2, $pos); + $pos += 2; + + continue; + } + + if (in_array($c, array('>', '+', '~', ',', '.', '*', '=', '[', ']', '(', ')', '|', ':', '#'))) { + if (in_array($c, array('.', '#', '[')) && $precedingWhitespacePos > 0) { + $tokens[] = new Token('Token', ' ', $precedingWhitespacePos); + } + $tokens[] = new Token('Token', $c, $pos); + ++$pos; + + continue; + } + + if ('"' === $c || "'" === $c) { + // Quoted string + $oldPos = $pos; + list($sym, $pos) = $this->tokenizeEscapedString($s, $pos); + + $tokens[] = new Token('String', $sym, $oldPos); + + continue; + } + + $oldPos = $pos; + list($sym, $pos) = $this->tokenizeSymbol($s, $pos); + + $tokens[] = new Token('Symbol', $sym, $oldPos); + + continue; + } + } + + /** + * Tokenizes a quoted string (i.e. 'A string quoted with \' characters'), + * and returns an array holding the unquoted string contained by $s and + * the new position from which tokenizing should take over. + * + * @param string $s The selector string containing the quoted string. + * @param integer $pos The starting position for the quoted string. + * + * @return array + * + * @throws ParseException When expected closing is not found + */ + private function tokenizeEscapedString($s, $pos) + { + $quote = $s[$pos]; + + $pos = $pos + 1; + $start = $pos; + while (true) { + $next = strpos($s, $quote, $pos); + if (false === $next) { + throw new ParseException(sprintf('Expected closing %s for string in: %s', $quote, substr($s, $start))); + } + + $result = substr($s, $start, $next - $start); + if ('\\' === $result[strlen($result) - 1]) { + // next quote character is escaped + $pos = $next + 1; + continue; + } + + if (false !== strpos($result, '\\')) { + $result = $this->unescapeStringLiteral($result); + } + + return array($result, $next + 1); + } + } + + /** + * Unescapes a string literal and returns the unescaped string. + * + * @param string $literal The string literal to unescape. + * + * @return string + * + * @throws ParseException When invalid escape sequence is found + */ + private function unescapeStringLiteral($literal) + { + return preg_replace_callback('#(\\\\(?:[A-Fa-f0-9]{1,6}(?:\r\n|\s)?|[^A-Fa-f0-9]))#', function ($matches) use ($literal) { + if ($matches[0][0] == '\\' && strlen($matches[0]) > 1) { + $matches[0] = substr($matches[0], 1); + if (in_array($matches[0][0], array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'a', 'b', 'c', 'd', 'e', 'f'))) { + return chr(trim($matches[0])); + } + } else { + throw new ParseException(sprintf('Invalid escape sequence %s in string %s', $matches[0], $literal)); + } + }, $literal); + } + + /** + * Lexes selector $s and returns an array holding the name of the symbol + * contained in it and the new position from which tokenizing should take + * over. + * + * @param string $s The selector string. + * @param integer $pos The position in $s at which the symbol starts. + * + * @return array + * + * @throws ParseException When Unexpected symbol is found + */ + private function tokenizeSymbol($s, $pos) + { + $start = $pos; + + if (!preg_match('#[^\w\-]#', $s, $match, PREG_OFFSET_CAPTURE, $pos)) { + // Goes to end of s + return array(substr($s, $start), strlen($s)); + } + + $matchStart = $match[0][1]; + + if ($matchStart == $pos) { + throw new ParseException(sprintf('Unexpected symbol: %s at %s', $s[$pos], $pos)); + } + + $result = substr($s, $start, $matchStart - $start); + $pos = $matchStart; + + return array($result, $pos); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/XPathExpr.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/XPathExpr.php new file mode 100644 index 0000000..2e239dd --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/XPathExpr.php @@ -0,0 +1,254 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\CssSelector; + +/** + * XPathExpr represents an XPath expression. + * + * This component is a port of the Python lxml library, + * which is copyright Infrae and distributed under the BSD license. + * + * @author Fabien Potencier + */ +class XPathExpr +{ + private $prefix; + private $path; + private $element; + private $condition; + private $starPrefix; + + /** + * Constructor. + * + * @param string $prefix Prefix for the XPath expression. + * @param string $path Actual path of the expression. + * @param string $element The element in the expression. + * @param string $condition A condition for the expression. + * @param Boolean $starPrefix Indicates whether to use a star prefix. + */ + public function __construct($prefix = null, $path = null, $element = '*', $condition = null, $starPrefix = false) + { + $this->prefix = $prefix; + $this->path = $path; + $this->element = $element; + $this->condition = $condition; + $this->starPrefix = $starPrefix; + } + + /** + * Gets the prefix of this XPath expression. + * + * @return string + */ + public function getPrefix() + { + return $this->prefix; + } + + /** + * Gets the path of this XPath expression. + * + * @return string + */ + public function getPath() + { + return $this->path; + } + + /** + * Answers whether this XPath expression has a star prefix. + * + * @return Boolean + */ + public function hasStarPrefix() + { + return $this->starPrefix; + } + + /** + * Gets the element of this XPath expression. + * + * @return string + */ + public function getElement() + { + return $this->element; + } + + /** + * Gets the condition of this XPath expression. + * + * @return string + */ + public function getCondition() + { + return $this->condition; + } + + /** + * Gets a string representation for this XPath expression. + * + * @return string + */ + public function __toString() + { + $path = ''; + if (null !== $this->prefix) { + $path .= $this->prefix; + } + + if (null !== $this->path) { + $path .= $this->path; + } + + $path .= $this->element; + + if ($this->condition) { + $path .= sprintf('[%s]', $this->condition); + } + + return $path; + } + + /** + * Adds a condition to this XPath expression. + * Any pre-existent condition will be ANDed to it. + * + * @param string $condition The condition to add. + */ + public function addCondition($condition) + { + if ($this->condition) { + $this->condition = sprintf('%s and (%s)', $this->condition, $condition); + } else { + $this->condition = $condition; + } + } + + /** + * Adds a prefix to this XPath expression. + * It will be prepended to any pre-existent prefixes. + * + * @param string $prefix The prefix to add. + */ + public function addPrefix($prefix) + { + if ($this->prefix) { + $this->prefix = $prefix.$this->prefix; + } else { + $this->prefix = $prefix; + } + } + + /** + * Adds a condition to this XPath expression using the name of the element + * as the desired value. + * This method resets the element to '*'. + */ + public function addNameTest() + { + if ($this->element == '*') { + // We weren't doing a test anyway + return; + } + + $this->addCondition(sprintf('name() = %s', XPathExpr::xpathLiteral($this->element))); + $this->element = '*'; + } + + /** + * Adds a star prefix to this XPath expression. + * This method will prepend a '*' to the path and set the star prefix flag + * to true. + */ + public function addStarPrefix() + { + /* + Adds a /* prefix if there is no prefix. This is when you need + to keep context's constrained to a single parent. + */ + if ($this->path) { + $this->path .= '*/'; + } else { + $this->path = '*/'; + } + + $this->starPrefix = true; + } + + /** + * Joins this XPath expression with $other (another XPath expression) using + * $combiner to join them. + * + * @param string $combiner The combiner string. + * @param XPathExpr $other The other XPath expression to combine with + * this one. + */ + public function join($combiner, $other) + { + $prefix = (string) $this; + + $prefix .= $combiner; + $path = $other->getPrefix().$other->getPath(); + + /* We don't need a star prefix if we are joining to this other + prefix; so we'll get rid of it */ + if ($other->hasStarPrefix() && '*/' == $path) { + $path = ''; + } + $this->prefix = $prefix; + $this->path = $path; + $this->element = $other->getElement(); + $this->condition = $other->GetCondition(); + } + + /** + * Gets an XPath literal for $s. + * + * @param mixed $s Can either be a Node\ElementNode or a string. + * + * @return string + */ + static public function xpathLiteral($s) + { + if ($s instanceof Node\ElementNode) { + // This is probably a symbol that looks like an expression... + $s = $s->formatElement(); + } else { + $s = (string) $s; + } + + if (false === strpos($s, "'")) { + return sprintf("'%s'", $s); + } + + if (false === strpos($s, '"')) { + return sprintf('"%s"', $s); + } + + $string = $s; + $parts = array(); + while (true) { + if (false !== $pos = strpos($string, "'")) { + $parts[] = sprintf("'%s'", substr($string, 0, $pos)); + $parts[] = "\"'\""; + $string = substr($string, $pos + 1); + } else { + $parts[] = "'$string'"; + break; + } + } + + return sprintf('concat(%s)', implode($parts, ', ')); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/XPathExprOr.php b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/XPathExprOr.php new file mode 100644 index 0000000..f516367 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/XPathExprOr.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\CssSelector; + +/** + * XPathExprOr represents XPath |'d expressions. + * + * Note that unfortunately it isn't the union, it's the sum, so duplicate elements will appear. + * + * This component is a port of the Python lxml library, + * which is copyright Infrae and distributed under the BSD license. + * + * @author Fabien Potencier + */ +class XPathExprOr extends XPathExpr +{ + /** + * Constructor. + * + * @param array $items The items in the expression. + * @param string $prefix Optional prefix for the expression. + */ + public function __construct($items, $prefix = null) + { + $this->items = $items; + $this->prefix = $prefix; + } + + /** + * Gets a string representation of this |'d expression. + * + * @return string + */ + public function __toString() + { + $prefix = $this->getPrefix(); + + $tmp = array(); + foreach ($this->items as $i) { + $tmp[] = sprintf('%s%s', $prefix, $i); + } + + return implode($tmp, ' | '); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/composer.json b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/composer.json new file mode 100644 index 0000000..a2a65e6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/composer.json @@ -0,0 +1,30 @@ +{ + "name": "symfony/css-selector", + "type": "library", + "description": "Symfony CssSelector 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" + }, + "autoload": { + "psr-0": { "Symfony\\Component\\CssSelector": "" } + }, + "target-dir": "Symfony/Component/CssSelector", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/CssSelector/phpunit.xml.dist b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/phpunit.xml.dist new file mode 100644 index 0000000..1aeb811 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/CssSelector/phpunit.xml.dist @@ -0,0 +1,30 @@ + + + + + + ./Tests/ + + + + + + ./ + + ./Resources + ./Tests + ./vendor + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Alias.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Alias.php new file mode 100644 index 0000000..fd75578 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Alias.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\DependencyInjection; + +/** + * @api + */ +class Alias +{ + private $id; + private $public; + + /** + * Constructor. + * + * @param string $id Alias identifier + * @param Boolean $public If this alias is public + * + * @api + */ + public function __construct($id, $public = true) + { + $this->id = strtolower($id); + $this->public = $public; + } + + /** + * Checks if this DI Alias should be public or not. + * + * @return Boolean + * + * @api + */ + public function isPublic() + { + return $this->public; + } + + /** + * Sets if this Alias is public. + * + * @param Boolean $boolean If this Alias should be public + * + * @api + */ + public function setPublic($boolean) + { + $this->public = (Boolean) $boolean; + } + + /** + * Returns the Id of this alias. + * + * @return string The alias id + * + * @api + */ + public function __toString() + { + return $this->id; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/CHANGELOG.md b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/CHANGELOG.md new file mode 100644 index 0000000..96839e9 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/CHANGELOG.md @@ -0,0 +1,12 @@ +CHANGELOG +========= + +2.1.0 +----- + + * added IntrospectableContainerInterface (to be able to check if a service + has been initialized or not) + * added ConfigurationExtensionInterface + * added Definition::clearTag() + * component exceptions that inherit base SPL classes are now used exclusively + (this includes dumped containers) diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php new file mode 100644 index 0000000..19079b4 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.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\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Run this pass before passes that need to know more about the relation of + * your services. + * + * This class will populate the ServiceReferenceGraph with information. You can + * retrieve the graph in other passes from the compiler. + * + * @author Johannes M. Schmitt + */ +class AnalyzeServiceReferencesPass implements RepeatablePassInterface +{ + private $graph; + private $container; + private $currentId; + private $currentDefinition; + private $repeatedPass; + private $onlyConstructorArguments; + + /** + * Constructor. + * + * @param Boolean $onlyConstructorArguments Sets this Service Reference pass to ignore method calls + */ + public function __construct($onlyConstructorArguments = false) + { + $this->onlyConstructorArguments = (Boolean) $onlyConstructorArguments; + } + + /** + * {@inheritDoc} + */ + public function setRepeatedPass(RepeatedPass $repeatedPass) + { + $this->repeatedPass = $repeatedPass; + } + + /** + * Processes a ContainerBuilder object to populate the service reference graph. + * + * @param ContainerBuilder $container + */ + public function process(ContainerBuilder $container) + { + $this->container = $container; + $this->graph = $container->getCompiler()->getServiceReferenceGraph(); + $this->graph->clear(); + + foreach ($container->getDefinitions() as $id => $definition) { + if ($definition->isSynthetic() || $definition->isAbstract()) { + continue; + } + + $this->currentId = $id; + $this->currentDefinition = $definition; + $this->processArguments($definition->getArguments()); + + if (!$this->onlyConstructorArguments) { + $this->processArguments($definition->getMethodCalls()); + $this->processArguments($definition->getProperties()); + if ($definition->getConfigurator()) { + $this->processArguments(array($definition->getConfigurator())); + } + } + } + + foreach ($container->getAliases() as $id => $alias) { + $this->graph->connect($id, $alias, (string) $alias, $this->getDefinition((string) $alias), null); + } + } + + /** + * Processes service definitions for arguments to find relationships for the service graph. + * + * @param array $arguments An array of Reference or Definition objects relating to service definitions + */ + private function processArguments(array $arguments) + { + foreach ($arguments as $argument) { + if (is_array($argument)) { + $this->processArguments($argument); + } elseif ($argument instanceof Reference) { + $this->graph->connect( + $this->currentId, + $this->currentDefinition, + $this->getDefinitionId((string) $argument), + $this->getDefinition((string) $argument), + $argument + ); + } elseif ($argument instanceof Definition) { + $this->processArguments($argument->getArguments()); + $this->processArguments($argument->getMethodCalls()); + $this->processArguments($argument->getProperties()); + } + } + } + + /** + * Returns a service definition given the full name or an alias. + * + * @param string $id A full id or alias for a service definition. + * + * @return Definition The definition related to the supplied id + */ + private function getDefinition($id) + { + $id = $this->getDefinitionId($id); + + return null === $id ? null : $this->container->getDefinition($id); + } + + private function getDefinitionId($id) + { + while ($this->container->hasAlias($id)) { + $id = (string) $this->container->getAlias($id); + } + + if (!$this->container->hasDefinition($id)) { + return null; + } + + return $id; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php new file mode 100644 index 0000000..9cb3ff0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.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\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Checks your services for circular references + * + * References from method calls are ignored since we might be able to resolve + * these references depending on the order in which services are called. + * + * Circular reference from method calls will only be detected at run-time. + * + * @author Johannes M. Schmitt + */ +class CheckCircularReferencesPass implements CompilerPassInterface +{ + private $currentId; + private $currentPath; + + /** + * Checks the ContainerBuilder object for circular references. + * + * @param ContainerBuilder $container The ContainerBuilder instances + */ + public function process(ContainerBuilder $container) + { + $graph = $container->getCompiler()->getServiceReferenceGraph(); + + foreach ($graph->getNodes() as $id => $node) { + $this->currentId = $id; + $this->currentPath = array($id); + + $this->checkOutEdges($node->getOutEdges()); + } + } + + /** + * Checks for circular references. + * + * @param array $edges An array of Nodes + * + * @throws ServiceCircularReferenceException When a circular reference is found. + */ + private function checkOutEdges(array $edges) + { + foreach ($edges as $edge) { + $node = $edge->getDestNode(); + $this->currentPath[] = $id = $node->getId(); + + if ($this->currentId === $id) { + throw new ServiceCircularReferenceException($this->currentId, $this->currentPath); + } + + $this->checkOutEdges($node->getOutEdges()); + array_pop($this->currentPath); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/CheckDefinitionValidityPass.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/CheckDefinitionValidityPass.php new file mode 100644 index 0000000..e536331 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/CheckDefinitionValidityPass.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\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * This pass validates each definition individually only taking the information + * into account which is contained in the definition itself. + * + * Later passes can rely on the following, and specifically do not need to + * perform these checks themselves: + * + * - non synthetic, non abstract services always have a class set + * - synthetic services are always public + * - synthetic services are always of non-prototype scope + * + * @author Johannes M. Schmitt + */ +class CheckDefinitionValidityPass implements CompilerPassInterface +{ + /** + * Processes the ContainerBuilder to validate the Definition. + * + * @param ContainerBuilder $container + * + * @throws RuntimeException When the Definition is invalid + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getDefinitions() as $id => $definition) { + // synthetic service is public + if ($definition->isSynthetic() && !$definition->isPublic()) { + throw new RuntimeException(sprintf( + 'A synthetic service ("%s") must be public.', + $id + )); + } + + // synthetic service has non-prototype scope + if ($definition->isSynthetic() && ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope()) { + throw new RuntimeException(sprintf( + 'A synthetic service ("%s") cannot be of scope "prototype".', + $id + )); + } + + // non-synthetic, non-abstract service has class + if (!$definition->isAbstract() && !$definition->isSynthetic() && !$definition->getClass()) { + if ($definition->getFactoryClass() || $definition->getFactoryService()) { + throw new RuntimeException(sprintf( + 'Please add the class to service "%s" even if it is constructed by a factory ' + .'since we might need to add method calls based on compile-time checks.', + $id + )); + } + + throw new RuntimeException(sprintf( + 'The definition for "%s" has no class. If you intend to inject ' + .'this service dynamically at runtime, please mark it as synthetic=true. ' + .'If this is an abstract definition solely used by child definitions, ' + .'please add abstract=true, otherwise specify a class to get rid of this error.', + $id + )); + } + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php new file mode 100644 index 0000000..2cd5480 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.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\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Definition; + +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Checks that all references are pointing to a valid service. + * + * @author Johannes M. Schmitt + */ +class CheckExceptionOnInvalidReferenceBehaviorPass implements CompilerPassInterface +{ + private $container; + private $sourceId; + + public function process(ContainerBuilder $container) + { + $this->container = $container; + + foreach ($container->getDefinitions() as $id => $definition) { + $this->sourceId = $id; + $this->processDefinition($definition); + } + } + + private function processDefinition(Definition $definition) + { + $this->processReferences($definition->getArguments()); + $this->processReferences($definition->getMethodCalls()); + $this->processReferences($definition->getProperties()); + } + + private function processReferences(array $arguments) + { + foreach ($arguments as $argument) { + if (is_array($argument)) { + $this->processReferences($argument); + } elseif ($argument instanceof Definition) { + $this->processDefinition($argument); + } elseif ($argument instanceof Reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE === $argument->getInvalidBehavior()) { + $destId = (string) $argument; + + if (!$this->container->has($destId)) { + throw new ServiceNotFoundException($destId, $this->sourceId); + } + } + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/CheckReferenceValidityPass.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/CheckReferenceValidityPass.php new file mode 100644 index 0000000..436dc74 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/CheckReferenceValidityPass.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\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Exception\ScopeCrossingInjectionException; +use Symfony\Component\DependencyInjection\Exception\ScopeWideningInjectionException; + +/** + * Checks the validity of references + * + * The following checks are performed by this pass: + * - target definitions are not abstract + * - target definitions are of equal or wider scope + * - target definitions are in the same scope hierarchy + * + * @author Johannes M. Schmitt + */ +class CheckReferenceValidityPass implements CompilerPassInterface +{ + private $container; + private $currentId; + private $currentDefinition; + private $currentScope; + private $currentScopeAncestors; + private $currentScopeChildren; + + /** + * Processes the ContainerBuilder to validate References. + * + * @param ContainerBuilder $container + */ + public function process(ContainerBuilder $container) + { + $this->container = $container; + + $children = $this->container->getScopeChildren(); + $ancestors = array(); + + $scopes = $this->container->getScopes(); + foreach ($scopes as $name => $parent) { + $ancestors[$name] = array($parent); + + while (isset($scopes[$parent])) { + $ancestors[$name][] = $parent = $scopes[$parent]; + } + } + + foreach ($container->getDefinitions() as $id => $definition) { + if ($definition->isSynthetic() || $definition->isAbstract()) { + continue; + } + + $this->currentId = $id; + $this->currentDefinition = $definition; + $this->currentScope = $scope = $definition->getScope(); + + if (ContainerInterface::SCOPE_CONTAINER === $scope) { + $this->currentScopeChildren = array_keys($scopes); + $this->currentScopeAncestors = array(); + } elseif (ContainerInterface::SCOPE_PROTOTYPE !== $scope) { + $this->currentScopeChildren = $children[$scope]; + $this->currentScopeAncestors = $ancestors[$scope]; + } + + $this->validateReferences($definition->getArguments()); + $this->validateReferences($definition->getMethodCalls()); + $this->validateReferences($definition->getProperties()); + } + } + + /** + * Validates an array of References. + * + * @param array $arguments An array of Reference objects + * + * @throws RuntimeException when there is a reference to an abstract definition. + */ + private function validateReferences(array $arguments) + { + foreach ($arguments as $argument) { + if (is_array($argument)) { + $this->validateReferences($argument); + } elseif ($argument instanceof Reference) { + $targetDefinition = $this->getDefinition((string) $argument); + + if (null !== $targetDefinition && $targetDefinition->isAbstract()) { + throw new RuntimeException(sprintf( + 'The definition "%s" has a reference to an abstract definition "%s". ' + .'Abstract definitions cannot be the target of references.', + $this->currentId, + $argument + )); + } + + $this->validateScope($argument, $targetDefinition); + } + } + } + + /** + * Validates the scope of a single Reference. + * + * @param Reference $reference + * @param Definition $definition + * + * @throws ScopeWideningInjectionException when the definition references a service of a narrower scope + * @throws ScopeCrossingInjectionException when the definition references a service of another scope hierarchy + */ + private function validateScope(Reference $reference, Definition $definition = null) + { + if (ContainerInterface::SCOPE_PROTOTYPE === $this->currentScope) { + return; + } + + if (!$reference->isStrict()) { + return; + } + + if (null === $definition) { + return; + } + + if ($this->currentScope === $scope = $definition->getScope()) { + return; + } + + $id = (string) $reference; + + if (in_array($scope, $this->currentScopeChildren, true)) { + throw new ScopeWideningInjectionException($this->currentId, $this->currentScope, $id, $scope); + } + + if (!in_array($scope, $this->currentScopeAncestors, true)) { + throw new ScopeCrossingInjectionException($this->currentId, $this->currentScope, $id, $scope); + } + } + + /** + * Returns the Definition given an id. + * + * @param string $id Definition identifier + * + * @return Definition + */ + private function getDefinition($id) + { + if (!$this->container->hasDefinition($id)) { + return null; + } + + return $this->container->getDefinition($id); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/Compiler.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/Compiler.php new file mode 100644 index 0000000..01f224b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/Compiler.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\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\PassConfig; + +/** + * This class is used to remove circular dependencies between individual passes. + * + * @author Johannes M. Schmitt + * + * @api + */ +class Compiler +{ + private $passConfig; + private $log; + private $loggingFormatter; + private $serviceReferenceGraph; + + /** + * Constructor. + */ + public function __construct() + { + $this->passConfig = new PassConfig(); + $this->serviceReferenceGraph = new ServiceReferenceGraph(); + $this->loggingFormatter = new LoggingFormatter(); + $this->log = array(); + } + + /** + * Returns the PassConfig. + * + * @return PassConfig The PassConfig instance + * + * @api + */ + public function getPassConfig() + { + return $this->passConfig; + } + + /** + * Returns the ServiceReferenceGraph. + * + * @return ServiceReferenceGraph The ServiceReferenceGraph instance + * + * @api + */ + public function getServiceReferenceGraph() + { + return $this->serviceReferenceGraph; + } + + /** + * Returns the logging formatter which can be used by compilation passes. + * + * @return LoggingFormatter + */ + public function getLoggingFormatter() + { + return $this->loggingFormatter; + } + + /** + * Adds a pass to the PassConfig. + * + * @param CompilerPassInterface $pass A compiler pass + * @param string $type The type of the pass + * + * @api + */ + public function addPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION) + { + $this->passConfig->addPass($pass, $type); + } + + /** + * Adds a log message. + * + * @param string $string The log message + */ + public function addLogMessage($string) + { + $this->log[] = $string; + } + + /** + * Returns the log. + * + * @return array Log array + */ + public function getLog() + { + return $this->log; + } + + /** + * Run the Compiler and process all Passes. + * + * @param ContainerBuilder $container + * + * @api + */ + public function compile(ContainerBuilder $container) + { + foreach ($this->passConfig->getPasses() as $pass) { + $pass->process($container); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/CompilerPassInterface.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/CompilerPassInterface.php new file mode 100644 index 0000000..1ae8bb9 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/CompilerPassInterface.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\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Interface that must be implemented by compilation passes + * + * @author Johannes M. Schmitt + * + * @api + */ +interface CompilerPassInterface +{ + /** + * You can modify the container here before it is dumped to PHP code. + * + * @param ContainerBuilder $container + * + * @api + */ + function process(ContainerBuilder $container); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php new file mode 100644 index 0000000..9e21972 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.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\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Inline service definitions where this is possible. + * + * @author Johannes M. Schmitt + */ +class InlineServiceDefinitionsPass implements RepeatablePassInterface +{ + private $repeatedPass; + private $graph; + private $compiler; + private $formatter; + private $currentId; + + /** + * {@inheritDoc} + */ + public function setRepeatedPass(RepeatedPass $repeatedPass) + { + $this->repeatedPass = $repeatedPass; + } + + /** + * Processes the ContainerBuilder for inline service definitions. + * + * @param ContainerBuilder $container + */ + public function process(ContainerBuilder $container) + { + $this->compiler = $container->getCompiler(); + $this->formatter = $this->compiler->getLoggingFormatter(); + $this->graph = $this->compiler->getServiceReferenceGraph(); + + foreach ($container->getDefinitions() as $id => $definition) { + $this->currentId = $id; + + $definition->setArguments( + $this->inlineArguments($container, $definition->getArguments()) + ); + + $definition->setMethodCalls( + $this->inlineArguments($container, $definition->getMethodCalls()) + ); + + $definition->setProperties( + $this->inlineArguments($container, $definition->getProperties()) + ); + } + } + + /** + * Processes inline arguments. + * + * @param ContainerBuilder $container The ContainerBuilder + * @param array $arguments An array of arguments + */ + private function inlineArguments(ContainerBuilder $container, array $arguments) + { + foreach ($arguments as $k => $argument) { + if (is_array($argument)) { + $arguments[$k] = $this->inlineArguments($container, $argument); + } elseif ($argument instanceof Reference) { + if (!$container->hasDefinition($id = (string) $argument)) { + continue; + } + + if ($this->isInlinableDefinition($container, $id, $definition = $container->getDefinition($id))) { + $this->compiler->addLogMessage($this->formatter->formatInlineService($this, $id, $this->currentId)); + + if (ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope()) { + $arguments[$k] = $definition; + } else { + $arguments[$k] = clone $definition; + } + } + } elseif ($argument instanceof Definition) { + $argument->setArguments($this->inlineArguments($container, $argument->getArguments())); + $argument->setMethodCalls($this->inlineArguments($container, $argument->getMethodCalls())); + $argument->setProperties($this->inlineArguments($container, $argument->getProperties())); + } + } + + return $arguments; + } + + /** + * Checks if the definition is inlineable. + * + * @param ContainerBuilder $container + * @param string $id + * @param Definition $definition + * + * @return Boolean If the definition is inlineable + */ + private function isInlinableDefinition(ContainerBuilder $container, $id, Definition $definition) + { + if (ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope()) { + return true; + } + + if ($definition->isPublic()) { + return false; + } + + if (!$this->graph->hasNode($id)) { + return true; + } + + $ids = array(); + foreach ($this->graph->getNode($id)->getInEdges() as $edge) { + $ids[] = $edge->getSourceNode()->getId(); + } + + if (count(array_unique($ids)) > 1) { + return false; + } + + return $container->getDefinition(reset($ids))->getScope() === $definition->getScope(); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/LoggingFormatter.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/LoggingFormatter.php new file mode 100644 index 0000000..0c6c90d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/LoggingFormatter.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\DependencyInjection\Compiler; + + +/** + * Used to format logging messages during the compilation. + * + * @author Johannes M. Schmitt + */ +class LoggingFormatter +{ + public function formatRemoveService(CompilerPassInterface $pass, $id, $reason) + { + return $this->format($pass, sprintf('Removed service "%s"; reason: %s', $id, $reason)); + } + + public function formatInlineService(CompilerPassInterface $pass, $id, $target) + { + return $this->format($pass, sprintf('Inlined service "%s" to "%s".', $id, $target)); + } + + public function formatUpdateReference(CompilerPassInterface $pass, $serviceId, $oldDestId, $newDestId) + { + return $this->format($pass, sprintf('Changed reference of service "%s" previously pointing to "%s" to "%s".', $serviceId, $oldDestId, $newDestId)); + } + + public function formatResolveInheritance(CompilerPassInterface $pass, $childId, $parentId) + { + return $this->format($pass, sprintf('Resolving inheritance for "%s" (parent: %s).', $childId, $parentId)); + } + + public function format(CompilerPassInterface $pass, $message) + { + return sprintf('%s: %s', get_class($pass), $message); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php new file mode 100644 index 0000000..a9beb5b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.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\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Merges extension configs into the container builder + * + * @author Fabien Potencier + */ +class MergeExtensionConfigurationPass implements CompilerPassInterface +{ + /** + * {@inheritDoc} + */ + public function process(ContainerBuilder $container) + { + $parameters = $container->getParameterBag()->all(); + $definitions = $container->getDefinitions(); + $aliases = $container->getAliases(); + + foreach ($container->getExtensions() as $name => $extension) { + if (!$config = $container->getExtensionConfig($name)) { + // this extension was not called + continue; + } + $config = $container->getParameterBag()->resolveValue($config); + + $tmpContainer = new ContainerBuilder($container->getParameterBag()); + $tmpContainer->addObjectResource($extension); + + $extension->load($config, $tmpContainer); + + $container->merge($tmpContainer); + } + + $container->addDefinitions($definitions); + $container->addAliases($aliases); + $container->getParameterBag()->add($parameters); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php new file mode 100644 index 0000000..e863f75 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php @@ -0,0 +1,259 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * Compiler Pass Configuration + * + * This class has a default configuration embedded. + * + * @author Johannes M. Schmitt + * + * @api + */ +class PassConfig +{ + const TYPE_AFTER_REMOVING = 'afterRemoving'; + const TYPE_BEFORE_OPTIMIZATION = 'beforeOptimization'; + const TYPE_BEFORE_REMOVING = 'beforeRemoving'; + const TYPE_OPTIMIZE = 'optimization'; + const TYPE_REMOVE = 'removing'; + + private $mergePass; + private $afterRemovingPasses; + private $beforeOptimizationPasses; + private $beforeRemovingPasses; + private $optimizationPasses; + private $removingPasses; + + /** + * Constructor. + */ + public function __construct() + { + $this->mergePass = new MergeExtensionConfigurationPass(); + + $this->afterRemovingPasses = array(); + $this->beforeOptimizationPasses = array(); + $this->beforeRemovingPasses = array(); + + $this->optimizationPasses = array( + new ResolveDefinitionTemplatesPass(), + new ResolveParameterPlaceHoldersPass(), + new CheckDefinitionValidityPass(), + new ResolveReferencesToAliasesPass(), + new ResolveInvalidReferencesPass(), + new AnalyzeServiceReferencesPass(true), + new CheckCircularReferencesPass(), + new CheckReferenceValidityPass(), + ); + + $this->removingPasses = array( + new RemovePrivateAliasesPass(), + new RemoveAbstractDefinitionsPass(), + new ReplaceAliasByActualDefinitionPass(), + new RepeatedPass(array( + new AnalyzeServiceReferencesPass(), + new InlineServiceDefinitionsPass(), + new AnalyzeServiceReferencesPass(), + new RemoveUnusedDefinitionsPass(), + )), + new CheckExceptionOnInvalidReferenceBehaviorPass(), + ); + } + + /** + * Returns all passes in order to be processed. + * + * @return array An array of all passes to process + * + * @api + */ + public function getPasses() + { + return array_merge( + array($this->mergePass), + $this->beforeOptimizationPasses, + $this->optimizationPasses, + $this->beforeRemovingPasses, + $this->removingPasses, + $this->afterRemovingPasses + ); + } + + /** + * Adds a pass. + * + * @param CompilerPassInterface $pass A Compiler pass + * @param string $type The pass type + * + * @throws InvalidArgumentException when a pass type doesn't exist + * + * @api + */ + public function addPass(CompilerPassInterface $pass, $type = self::TYPE_BEFORE_OPTIMIZATION) + { + $property = $type.'Passes'; + if (!isset($this->$property)) { + throw new InvalidArgumentException(sprintf('Invalid type "%s".', $type)); + } + + $passes = &$this->$property; + $passes[] = $pass; + } + + /** + * Gets all passes for the AfterRemoving pass. + * + * @return array An array of passes + * + * @api + */ + public function getAfterRemovingPasses() + { + return $this->afterRemovingPasses; + } + + /** + * Gets all passes for the BeforeOptimization pass. + * + * @return array An array of passes + * + * @api + */ + public function getBeforeOptimizationPasses() + { + return $this->beforeOptimizationPasses; + } + + /** + * Gets all passes for the BeforeRemoving pass. + * + * @return array An array of passes + * + * @api + */ + public function getBeforeRemovingPasses() + { + return $this->beforeRemovingPasses; + } + + /** + * Gets all passes for the Optimization pass. + * + * @return array An array of passes + * + * @api + */ + public function getOptimizationPasses() + { + return $this->optimizationPasses; + } + + /** + * Gets all passes for the Removing pass. + * + * @return array An array of passes + * + * @api + */ + public function getRemovingPasses() + { + return $this->removingPasses; + } + + /** + * Gets all passes for the Merge pass. + * + * @return array An array of passes + * + * @api + */ + public function getMergePass() + { + return $this->mergePass; + } + + /** + * Sets the Merge Pass. + * + * @param CompilerPassInterface $pass The merge pass + * + * @api + */ + public function setMergePass(CompilerPassInterface $pass) + { + $this->mergePass = $pass; + } + + /** + * Sets the AfterRemoving passes. + * + * @param array $passes An array of passes + * + * @api + */ + public function setAfterRemovingPasses(array $passes) + { + $this->afterRemovingPasses = $passes; + } + + /** + * Sets the BeforeOptimization passes. + * + * @param array $passes An array of passes + * + * @api + */ + public function setBeforeOptimizationPasses(array $passes) + { + $this->beforeOptimizationPasses = $passes; + } + + /** + * Sets the BeforeRemoving passes. + * + * @param array $passes An array of passes + * + * @api + */ + public function setBeforeRemovingPasses(array $passes) + { + $this->beforeRemovingPasses = $passes; + } + + /** + * Sets the Optimization passes. + * + * @param array $passes An array of passes + * + * @api + */ + public function setOptimizationPasses(array $passes) + { + $this->optimizationPasses = $passes; + } + + /** + * Sets the Removing passes. + * + * @param array $passes An array of passes + * + * @api + */ + public function setRemovingPasses(array $passes) + { + $this->removingPasses = $passes; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/RemoveAbstractDefinitionsPass.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/RemoveAbstractDefinitionsPass.php new file mode 100644 index 0000000..d97d923 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/RemoveAbstractDefinitionsPass.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\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Removes abstract Definitions + * + */ +class RemoveAbstractDefinitionsPass implements CompilerPassInterface +{ + /** + * Removes abstract definitions from the ContainerBuilder + * + * @param ContainerBuilder $container + */ + public function process(ContainerBuilder $container) + { + $compiler = $container->getCompiler(); + $formatter = $compiler->getLoggingFormatter(); + + foreach ($container->getDefinitions() as $id => $definition) { + if ($definition->isAbstract()) { + $container->removeDefinition($id); + $compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'abstract')); + } + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/RemovePrivateAliasesPass.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/RemovePrivateAliasesPass.php new file mode 100644 index 0000000..4842337 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/RemovePrivateAliasesPass.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\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Remove private aliases from the container. They were only used to establish + * dependencies between services, and these dependencies have been resolved in + * one of the previous passes. + * + * @author Johannes M. Schmitt + */ +class RemovePrivateAliasesPass implements CompilerPassInterface +{ + /** + * Removes private aliases from the ContainerBuilder + * + * @param ContainerBuilder $container + */ + public function process(ContainerBuilder $container) + { + $compiler = $container->getCompiler(); + $formatter = $compiler->getLoggingFormatter(); + + foreach ($container->getAliases() as $id => $alias) { + if ($alias->isPublic()) { + continue; + } + + $container->removeAlias($id); + $compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'private alias')); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/RemoveUnusedDefinitionsPass.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/RemoveUnusedDefinitionsPass.php new file mode 100644 index 0000000..0c7be66 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/RemoveUnusedDefinitionsPass.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\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Removes unused service definitions from the container. + * + * @author Johannes M. Schmitt + */ +class RemoveUnusedDefinitionsPass implements RepeatablePassInterface +{ + private $repeatedPass; + + /** + * {@inheritDoc} + */ + public function setRepeatedPass(RepeatedPass $repeatedPass) + { + $this->repeatedPass = $repeatedPass; + } + + /** + * Processes the ContainerBuilder to remove unused definitions. + * + * @param ContainerBuilder $container + */ + public function process(ContainerBuilder $container) + { + $compiler = $container->getCompiler(); + $formatter = $compiler->getLoggingFormatter(); + $graph = $compiler->getServiceReferenceGraph(); + + $hasChanged = false; + foreach ($container->getDefinitions() as $id => $definition) { + if ($definition->isPublic()) { + continue; + } + + if ($graph->hasNode($id)) { + $edges = $graph->getNode($id)->getInEdges(); + $referencingAliases = array(); + $sourceIds = array(); + foreach ($edges as $edge) { + $node = $edge->getSourceNode(); + $sourceIds[] = $node->getId(); + + if ($node->isAlias()) { + $referencingAliases[] = $node->getValue(); + } + } + $isReferenced = (count(array_unique($sourceIds)) - count($referencingAliases)) > 0; + } else { + $referencingAliases = array(); + $isReferenced = false; + } + + if (1 === count($referencingAliases) && false === $isReferenced) { + $container->setDefinition((string) reset($referencingAliases), $definition); + $definition->setPublic(true); + $container->removeDefinition($id); + $compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'replaces alias '.reset($referencingAliases))); + } elseif (0 === count($referencingAliases) && false === $isReferenced) { + $container->removeDefinition($id); + $compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'unused')); + $hasChanged = true; + } + } + + if ($hasChanged) { + $this->repeatedPass->setRepeat(); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/RepeatablePassInterface.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/RepeatablePassInterface.php new file mode 100644 index 0000000..81209c3 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/RepeatablePassInterface.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\DependencyInjection\Compiler; + +/** + * Interface that must be implemented by passes that are run as part of an + * RepeatedPass. + * + * @author Johannes M. Schmitt + */ +interface RepeatablePassInterface extends CompilerPassInterface +{ + /** + * Sets the RepeatedPass interface. + * + * @param RepeatedPass $repeatedPass + */ + function setRepeatedPass(RepeatedPass $repeatedPass); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/RepeatedPass.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/RepeatedPass.php new file mode 100644 index 0000000..d4af431 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/RepeatedPass.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\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * A pass that might be run repeatedly. + * + * @author Johannes M. Schmitt + */ +class RepeatedPass implements CompilerPassInterface +{ + private $repeat; + private $passes; + + /** + * Constructor. + * + * @param array $passes An array of RepeatablePassInterface objects + * @throws InvalidArgumentException if a pass is not a RepeatablePassInterface instance + */ + public function __construct(array $passes) + { + foreach ($passes as $pass) { + if (!$pass instanceof RepeatablePassInterface) { + throw new InvalidArgumentException('$passes must be an array of RepeatablePassInterface.'); + } + + $pass->setRepeatedPass($this); + } + + $this->passes = $passes; + } + + /** + * Process the repeatable passes that run more than once. + * + * @param ContainerBuilder $container + */ + public function process(ContainerBuilder $container) + { + $this->repeat = false; + foreach ($this->passes as $pass) { + $pass->process($container); + } + + if ($this->repeat) { + $this->process($container); + } + } + + /** + * Sets if the pass should repeat + */ + public function setRepeat() + { + $this->repeat = true; + } + + /** + * Returns the passes + * + * @return array An array of RepeatablePassInterface objects + */ + public function getPasses() + { + return $this->passes; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ReplaceAliasByActualDefinitionPass.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ReplaceAliasByActualDefinitionPass.php new file mode 100644 index 0000000..5d00ed6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ReplaceAliasByActualDefinitionPass.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\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Replaces aliases with actual service definitions, effectively removing these + * aliases. + * + * @author Johannes M. Schmitt + */ +class ReplaceAliasByActualDefinitionPass implements CompilerPassInterface +{ + private $compiler; + private $formatter; + private $sourceId; + + /** + * Process the Container to replace aliases with service definitions. + * + * @param ContainerBuilder $container + */ + public function process(ContainerBuilder $container) + { + $this->compiler = $container->getCompiler(); + $this->formatter = $this->compiler->getLoggingFormatter(); + + foreach ($container->getAliases() as $id => $alias) { + $aliasId = (string) $alias; + + $definition = $container->getDefinition($aliasId); + + if ($definition->isPublic()) { + continue; + } + + $definition->setPublic(true); + $container->setDefinition($id, $definition); + $container->removeDefinition($aliasId); + + $this->updateReferences($container, $aliasId, $id); + + // we have to restart the process due to concurrent modification of + // the container + $this->process($container); + + break; + } + } + + /** + * Updates references to remove aliases. + * + * @param ContainerBuilder $container The container + * @param string $currentId The alias identifier being replaced + * @param string $newId The id of the service the alias points to + */ + private function updateReferences($container, $currentId, $newId) + { + foreach ($container->getAliases() as $id => $alias) { + if ($currentId === (string) $alias) { + $container->setAlias($id, $newId); + } + } + + foreach ($container->getDefinitions() as $id => $definition) { + $this->sourceId = $id; + + $definition->setArguments( + $this->updateArgumentReferences($definition->getArguments(), $currentId, $newId) + ); + + $definition->setMethodCalls( + $this->updateArgumentReferences($definition->getMethodCalls(), $currentId, $newId) + ); + + $definition->setProperties( + $this->updateArgumentReferences($definition->getProperties(), $currentId, $newId) + ); + } + } + + /** + * Updates argument references. + * + * @param array $arguments An array of Arguments + * @param string $currentId The alias identifier + * @param string $newId The identifier the alias points to + */ + private function updateArgumentReferences(array $arguments, $currentId, $newId) + { + foreach ($arguments as $k => $argument) { + if (is_array($argument)) { + $arguments[$k] = $this->updateArgumentReferences($argument, $currentId, $newId); + } elseif ($argument instanceof Reference) { + if ($currentId === (string) $argument) { + $arguments[$k] = new Reference($newId, $argument->getInvalidBehavior()); + $this->compiler->addLogMessage($this->formatter->formatUpdateReference($this, $this->sourceId, $currentId, $newId)); + } + } + } + + return $arguments; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php new file mode 100644 index 0000000..53c6f52 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.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\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * This replaces all DefinitionDecorator instances with their equivalent fully + * merged Definition instance. + * + * @author Johannes M. Schmitt + */ +class ResolveDefinitionTemplatesPass implements CompilerPassInterface +{ + private $container; + private $compiler; + private $formatter; + + /** + * Process the ContainerBuilder to replace DefinitionDecorator instances with their real Definition instances. + * + * @param ContainerBuilder $container + */ + public function process(ContainerBuilder $container) + { + $this->container = $container; + $this->compiler = $container->getCompiler(); + $this->formatter = $this->compiler->getLoggingFormatter(); + + foreach (array_keys($container->getDefinitions()) as $id) { + // yes, we are specifically fetching the definition from the + // container to ensure we are not operating on stale data + $definition = $container->getDefinition($id); + if (!$definition instanceof DefinitionDecorator || $definition->isAbstract()) { + continue; + } + + $this->resolveDefinition($id, $definition); + } + } + + /** + * Resolves the definition + * + * @param string $id The definition identifier + * @param DefinitionDecorator $definition + * + * @return Definition + */ + private function resolveDefinition($id, DefinitionDecorator $definition) + { + if (!$this->container->hasDefinition($parent = $definition->getParent())) { + throw new RuntimeException(sprintf('The parent definition "%s" defined for definition "%s" does not exist.', $parent, $id)); + } + + $parentDef = $this->container->getDefinition($parent); + if ($parentDef instanceof DefinitionDecorator) { + $parentDef = $this->resolveDefinition($parent, $parentDef); + } + + $this->compiler->addLogMessage($this->formatter->formatResolveInheritance($this, $id, $parent)); + $def = new Definition(); + + // merge in parent definition + // purposely ignored attributes: scope, abstract, tags + $def->setClass($parentDef->getClass()); + $def->setArguments($parentDef->getArguments()); + $def->setMethodCalls($parentDef->getMethodCalls()); + $def->setProperties($parentDef->getProperties()); + $def->setFactoryClass($parentDef->getFactoryClass()); + $def->setFactoryMethod($parentDef->getFactoryMethod()); + $def->setFactoryService($parentDef->getFactoryService()); + $def->setConfigurator($parentDef->getConfigurator()); + $def->setFile($parentDef->getFile()); + $def->setPublic($parentDef->isPublic()); + + // overwrite with values specified in the decorator + $changes = $definition->getChanges(); + if (isset($changes['class'])) { + $def->setClass($definition->getClass()); + } + if (isset($changes['factory_class'])) { + $def->setFactoryClass($definition->getFactoryClass()); + } + if (isset($changes['factory_method'])) { + $def->setFactoryMethod($definition->getFactoryMethod()); + } + if (isset($changes['factory_service'])) { + $def->setFactoryService($definition->getFactoryService()); + } + if (isset($changes['configurator'])) { + $def->setConfigurator($definition->getConfigurator()); + } + if (isset($changes['file'])) { + $def->setFile($definition->getFile()); + } + if (isset($changes['public'])) { + $def->setPublic($definition->isPublic()); + } + + // merge arguments + foreach ($definition->getArguments() as $k => $v) { + if (is_numeric($k)) { + $def->addArgument($v); + continue; + } + + if (0 !== strpos($k, 'index_')) { + throw new RuntimeException(sprintf('Invalid argument key "%s" found.', $k)); + } + + $index = (integer) substr($k, strlen('index_')); + $def->replaceArgument($index, $v); + } + + // merge properties + foreach ($definition->getProperties() as $k => $v) { + $def->setProperty($k, $v); + } + + // append method calls + if (count($calls = $definition->getMethodCalls()) > 0) { + $def->setMethodCalls(array_merge($def->getMethodCalls(), $calls)); + } + + // these attributes are always taken from the child + $def->setAbstract($definition->isAbstract()); + $def->setScope($definition->getScope()); + $def->setTags($definition->getTags()); + + // set new definition on container + $this->container->setDefinition($id, $def); + + return $def; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php new file mode 100644 index 0000000..996199c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.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\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * Emulates the invalid behavior if the reference is not found within the + * container. + * + * @author Johannes M. Schmitt + */ +class ResolveInvalidReferencesPass implements CompilerPassInterface +{ + private $container; + + /** + * Process the ContainerBuilder to resolve invalid references. + * + * @param ContainerBuilder $container + */ + public function process(ContainerBuilder $container) + { + $this->container = $container; + foreach ($container->getDefinitions() as $definition) { + if ($definition->isSynthetic() || $definition->isAbstract()) { + continue; + } + + $definition->setArguments( + $this->processArguments($definition->getArguments()) + ); + + $calls = array(); + foreach ($definition->getMethodCalls() as $call) { + try { + $calls[] = array($call[0], $this->processArguments($call[1], true)); + } catch (RuntimeException $ignore) { + // this call is simply removed + } + } + $definition->setMethodCalls($calls); + + $properties = array(); + foreach ($definition->getProperties() as $name => $value) { + try { + $value = $this->processArguments(array($value), true); + $properties[$name] = reset($value); + } catch (RuntimeException $ignore) { + // ignore property + } + } + $definition->setProperties($properties); + } + } + + /** + * Processes arguments to determine invalid references. + * + * @param array $arguments An array of Reference objects + * @param Boolean $inMethodCall + */ + private function processArguments(array $arguments, $inMethodCall = false) + { + foreach ($arguments as $k => $argument) { + if (is_array($argument)) { + $arguments[$k] = $this->processArguments($argument, $inMethodCall); + } elseif ($argument instanceof Reference) { + $id = (string) $argument; + + $invalidBehavior = $argument->getInvalidBehavior(); + $exists = $this->container->has($id); + + // resolve invalid behavior + if ($exists && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) { + $arguments[$k] = new Reference($id); + } elseif (!$exists && ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) { + $arguments[$k] = null; + } elseif (!$exists && ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) { + if ($inMethodCall) { + throw new RuntimeException('Method shouldn\'t be called.'); + } + + $arguments[$k] = null; + } + } + } + + return $arguments; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ResolveParameterPlaceHoldersPass.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ResolveParameterPlaceHoldersPass.php new file mode 100644 index 0000000..f6e4c85 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ResolveParameterPlaceHoldersPass.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\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; + +/** + * Resolves all parameter placeholders "%somevalue%" to their real values. + * + * @author Johannes M. Schmitt + */ +class ResolveParameterPlaceHoldersPass implements CompilerPassInterface +{ + /** + * Processes the ContainerBuilder to resolve parameter placeholders. + * + * @param ContainerBuilder $container + */ + public function process(ContainerBuilder $container) + { + $parameterBag = $container->getParameterBag(); + + foreach ($container->getDefinitions() as $id => $definition) { + try { + $definition->setClass($parameterBag->resolveValue($definition->getClass())); + $definition->setFile($parameterBag->resolveValue($definition->getFile())); + $definition->setArguments($parameterBag->resolveValue($definition->getArguments())); + + $calls = array(); + foreach ($definition->getMethodCalls() as $name => $arguments) { + $calls[$parameterBag->resolveValue($name)] = $parameterBag->resolveValue($arguments); + } + $definition->setMethodCalls($calls); + + $definition->setProperties($parameterBag->resolveValue($definition->getProperties())); + } catch (ParameterNotFoundException $e) { + $e->setSourceId($id); + + throw $e; + } + } + + $aliases = array(); + foreach ($container->getAliases() as $name => $target) { + $aliases[$parameterBag->resolveValue($name)] = $parameterBag->resolveValue($target); + } + $container->setAliases($aliases); + + $parameterBag->resolve(); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ResolveReferencesToAliasesPass.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ResolveReferencesToAliasesPass.php new file mode 100644 index 0000000..015bdeb --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ResolveReferencesToAliasesPass.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\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Replaces all references to aliases with references to the actual service. + * + * @author Johannes M. Schmitt + */ +class ResolveReferencesToAliasesPass implements CompilerPassInterface +{ + private $container; + + /** + * Processes the ContainerBuilder to replace references to aliases with actual service references. + * + * @param ContainerBuilder $container + */ + public function process(ContainerBuilder $container) + { + $this->container = $container; + + foreach ($container->getDefinitions() as $definition) { + if ($definition->isSynthetic() || $definition->isAbstract()) { + continue; + } + + $definition->setArguments($this->processArguments($definition->getArguments())); + $definition->setMethodCalls($this->processArguments($definition->getMethodCalls())); + $definition->setProperties($this->processArguments($definition->getProperties())); + } + + foreach ($container->getAliases() as $id => $alias) { + $aliasId = (string) $alias; + if ($aliasId !== $defId = $this->getDefinitionId($aliasId)) { + $container->setAlias($id, new Alias($defId, $alias->isPublic())); + } + } + } + + /** + * Processes the arguments to replace aliases. + * + * @param array $arguments An array of References + * + * @return array An array of References + */ + private function processArguments(array $arguments) + { + foreach ($arguments as $k => $argument) { + if (is_array($argument)) { + $arguments[$k] = $this->processArguments($argument); + } elseif ($argument instanceof Reference) { + $defId = $this->getDefinitionId($id = (string) $argument); + + if ($defId !== $id) { + $arguments[$k] = new Reference($defId, $argument->getInvalidBehavior(), $argument->isStrict()); + } + } + } + + return $arguments; + } + + /** + * Resolves an alias into a definition id. + * + * @param string $id The definition or alias id to resolve + * + * @return string The definition id with aliases resolved + */ + private function getDefinitionId($id) + { + while ($this->container->hasAlias($id)) { + $id = (string) $this->container->getAlias($id); + } + + return $id; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraph.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraph.php new file mode 100644 index 0000000..b241bf8 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraph.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\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * This is a directed graph of your services. + * + * This information can be used by your compiler passes instead of collecting + * it themselves which improves performance quite a lot. + * + * @author Johannes M. Schmitt + */ +class ServiceReferenceGraph +{ + private $nodes; + + /** + * Constructor. + */ + public function __construct() + { + $this->nodes = array(); + } + + /** + * Checks if the graph has a specific node. + * + * @param string $id Id to check + */ + public function hasNode($id) + { + return isset($this->nodes[$id]); + } + + /** + * Gets a node by identifier. + * + * @param string $id The id to retrieve + * + * @return ServiceReferenceGraphNode The node matching the supplied identifier + * + * @throws InvalidArgumentException if no node matches the supplied identifier + */ + public function getNode($id) + { + if (!isset($this->nodes[$id])) { + throw new InvalidArgumentException(sprintf('There is no node with id "%s".', $id)); + } + + return $this->nodes[$id]; + } + + /** + * Returns all nodes. + * + * @return array An array of all ServiceReferenceGraphNode objects + */ + public function getNodes() + { + return $this->nodes; + } + + /** + * Clears all nodes. + */ + public function clear() + { + $this->nodes = array(); + } + + /** + * Connects 2 nodes together in the Graph. + * + * @param string $sourceId + * @param string $sourceValue + * @param string $destId + * @param string $destValue + * @param string $reference + */ + public function connect($sourceId, $sourceValue, $destId, $destValue = null, $reference = null) + { + $sourceNode = $this->createNode($sourceId, $sourceValue); + $destNode = $this->createNode($destId, $destValue); + $edge = new ServiceReferenceGraphEdge($sourceNode, $destNode, $reference); + + $sourceNode->addOutEdge($edge); + $destNode->addInEdge($edge); + } + + /** + * Creates a graph node. + * + * @param string $id + * @param string $value + * + * @return ServiceReferenceGraphNode + */ + private function createNode($id, $value) + { + if (isset($this->nodes[$id]) && $this->nodes[$id]->getValue() === $value) { + return $this->nodes[$id]; + } + + return $this->nodes[$id] = new ServiceReferenceGraphNode($id, $value); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraphEdge.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraphEdge.php new file mode 100644 index 0000000..19da234 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraphEdge.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\DependencyInjection\Compiler; + +/** + * Represents an edge in your service graph. + * + * Value is typically a reference. + * + * @author Johannes M. Schmitt + */ +class ServiceReferenceGraphEdge +{ + private $sourceNode; + private $destNode; + private $value; + + /** + * Constructor. + * + * @param ServiceReferenceGraphNode $sourceNode + * @param ServiceReferenceGraphNode $destNode + * @param string $value + */ + public function __construct(ServiceReferenceGraphNode $sourceNode, ServiceReferenceGraphNode $destNode, $value = null) + { + $this->sourceNode = $sourceNode; + $this->destNode = $destNode; + $this->value = $value; + } + + /** + * Returns the value of the edge + * + * @return ServiceReferenceGraphNode + */ + public function getValue() + { + return $this->value; + } + + /** + * Returns the source node + * + * @return ServiceReferenceGraphNode + */ + public function getSourceNode() + { + return $this->sourceNode; + } + + /** + * Returns the destination node + * + * @return ServiceReferenceGraphNode + */ + public function getDestNode() + { + return $this->destNode; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraphNode.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraphNode.php new file mode 100644 index 0000000..3fd5077 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraphNode.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\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Alias; + +/** + * Represents a node in your service graph. + * + * Value is typically a definition, or an alias. + * + * @author Johannes M. Schmitt + */ +class ServiceReferenceGraphNode +{ + private $id; + private $inEdges; + private $outEdges; + private $value; + + /** + * Constructor. + * + * @param string $id The node identifier + * @param mixed $value The node value + */ + public function __construct($id, $value) + { + $this->id = $id; + $this->value = $value; + $this->inEdges = array(); + $this->outEdges = array(); + } + + /** + * Adds an in edge to this node. + * + * @param ServiceReferenceGraphEdge $edge + */ + public function addInEdge(ServiceReferenceGraphEdge $edge) + { + $this->inEdges[] = $edge; + } + + /** + * Adds an out edge to this node. + * + * @param ServiceReferenceGraphEdge $edge + */ + public function addOutEdge(ServiceReferenceGraphEdge $edge) + { + $this->outEdges[] = $edge; + } + + /** + * Checks if the value of this node is an Alias. + * + * @return Boolean True if the value is an Alias instance + */ + public function isAlias() + { + return $this->value instanceof Alias; + } + + /** + * Checks if the value of this node is a Definition. + * + * @return Boolean True if the value is a Definition instance + */ + public function isDefinition() + { + return $this->value instanceof Definition; + } + + /** + * Returns the identifier. + * + * @return string + */ + public function getId() + { + return $this->id; + } + + /** + * Returns the in edges. + * + * @return array The in ServiceReferenceGraphEdge array + */ + public function getInEdges() + { + return $this->inEdges; + } + + /** + * Returns the out edges. + * + * @return array The out ServiceReferenceGraphEdge array + */ + public function getOutEdges() + { + return $this->outEdges; + } + + /** + * Returns the value of this Node + * + * @return mixed The value + */ + public function getValue() + { + return $this->value; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php new file mode 100644 index 0000000..8500644 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php @@ -0,0 +1,467 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; + +/** + * Container is a dependency injection container. + * + * It gives access to object instances (services). + * + * Services and parameters are simple key/pair stores. + * + * Parameter and service keys are case insensitive. + * + * A service id can contain lowercased letters, digits, underscores, and dots. + * Underscores are used to separate words, and dots to group services + * under namespaces: + * + *
      + *
    • request
    • + *
    • mysql_session_storage
    • + *
    • symfony.mysql_session_storage
    • + *
    + * + * A service can also be defined by creating a method named + * getXXXService(), where XXX is the camelized version of the id: + * + *
      + *
    • request -> getRequestService()
    • + *
    • mysql_session_storage -> getMysqlSessionStorageService()
    • + *
    • symfony.mysql_session_storage -> getSymfony_MysqlSessionStorageService()
    • + *
    + * + * The container can have three possible behaviors when a service does not exist: + * + * * EXCEPTION_ON_INVALID_REFERENCE: Throws an exception (the default) + * * NULL_ON_INVALID_REFERENCE: Returns null + * * IGNORE_ON_INVALID_REFERENCE: Ignores the wrapping command asking for the reference + * (for instance, ignore a setter if the service does not exist) + * + * @author Fabien Potencier + * @author Johannes M. Schmitt + * + * @api + */ +class Container implements IntrospectableContainerInterface +{ + protected $parameterBag; + protected $services; + protected $scopes; + protected $scopeChildren; + protected $scopedServices; + protected $scopeStacks; + protected $loading = array(); + + /** + * Constructor. + * + * @param ParameterBagInterface $parameterBag A ParameterBagInterface instance + * + * @api + */ + public function __construct(ParameterBagInterface $parameterBag = null) + { + $this->parameterBag = null === $parameterBag ? new ParameterBag() : $parameterBag; + + $this->services = array(); + $this->scopes = array(); + $this->scopeChildren = array(); + $this->scopedServices = array(); + $this->scopeStacks = array(); + + $this->set('service_container', $this); + } + + /** + * Compiles the container. + * + * This method does two things: + * + * * Parameter values are resolved; + * * The parameter bag is frozen. + * + * @api + */ + public function compile() + { + $this->parameterBag->resolve(); + + $this->parameterBag = new FrozenParameterBag($this->parameterBag->all()); + } + + /** + * Returns true if the container parameter bag are frozen. + * + * @return Boolean true if the container parameter bag are frozen, false otherwise + * + * @api + */ + public function isFrozen() + { + return $this->parameterBag instanceof FrozenParameterBag; + } + + /** + * Gets the service container parameter bag. + * + * @return ParameterBagInterface A ParameterBagInterface instance + * + * @api + */ + public function getParameterBag() + { + return $this->parameterBag; + } + + /** + * Gets a parameter. + * + * @param string $name The parameter name + * + * @return mixed The parameter value + * + * @throws InvalidArgumentException if the parameter is not defined + * + * @api + */ + public function getParameter($name) + { + return $this->parameterBag->get($name); + } + + /** + * Checks if a parameter exists. + * + * @param string $name The parameter name + * + * @return Boolean The presence of parameter in container + * + * @api + */ + public function hasParameter($name) + { + return $this->parameterBag->has($name); + } + + /** + * Sets a parameter. + * + * @param string $name The parameter name + * @param mixed $value The parameter value + * + * @api + */ + public function setParameter($name, $value) + { + $this->parameterBag->set($name, $value); + } + + /** + * Sets a service. + * + * @param string $id The service identifier + * @param object $service The service instance + * @param string $scope The scope of the service + * + * @api + */ + public function set($id, $service, $scope = self::SCOPE_CONTAINER) + { + if (self::SCOPE_PROTOTYPE === $scope) { + throw new InvalidArgumentException('You cannot set services of scope "prototype".'); + } + + $id = strtolower($id); + + if (self::SCOPE_CONTAINER !== $scope) { + if (!isset($this->scopedServices[$scope])) { + throw new RuntimeException('You cannot set services of inactive scopes.'); + } + + $this->scopedServices[$scope][$id] = $service; + } + + $this->services[$id] = $service; + } + + /** + * Returns true if the given service is defined. + * + * @param string $id The service identifier + * + * @return Boolean true if the service is defined, false otherwise + * + * @api + */ + public function has($id) + { + $id = strtolower($id); + + return isset($this->services[$id]) || method_exists($this, 'get'.strtr($id, array('_' => '', '.' => '_')).'Service'); + } + + /** + * Gets a service. + * + * If a service is both defined through a set() method and + * with a set*Service() method, the former has always precedence. + * + * @param string $id The service identifier + * @param integer $invalidBehavior The behavior when the service does not exist + * + * @return object The associated service + * + * @throws InvalidArgumentException if the service is not defined + * + * @see Reference + * + * @api + */ + public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE) + { + $id = strtolower($id); + + if (isset($this->services[$id])) { + return $this->services[$id]; + } + + if (isset($this->loading[$id])) { + throw new ServiceCircularReferenceException($id, array_keys($this->loading)); + } + + if (method_exists($this, $method = 'get'.strtr($id, array('_' => '', '.' => '_')).'Service')) { + $this->loading[$id] = true; + + try { + $service = $this->$method(); + } catch (\Exception $e) { + unset($this->loading[$id]); + throw $e; + } + + unset($this->loading[$id]); + + return $service; + } + + if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) { + throw new ServiceNotFoundException($id); + } + } + + /** + * Returns true if the given service has actually been initialized + * + * @param string $id The service identifier + * + * @return Boolean true if service has already been initialized, false otherwise + */ + public function initialized($id) + { + return isset($this->services[strtolower($id)]); + } + + /** + * Gets all service ids. + * + * @return array An array of all defined service ids + */ + public function getServiceIds() + { + $ids = array(); + $r = new \ReflectionClass($this); + foreach ($r->getMethods() as $method) { + if (preg_match('/^get(.+)Service$/', $method->name, $match)) { + $ids[] = self::underscore($match[1]); + } + } + + return array_unique(array_merge($ids, array_keys($this->services))); + } + + /** + * This is called when you enter a scope + * + * @param string $name + * + * @api + */ + public function enterScope($name) + { + if (!isset($this->scopes[$name])) { + throw new InvalidArgumentException(sprintf('The scope "%s" does not exist.', $name)); + } + + if (self::SCOPE_CONTAINER !== $this->scopes[$name] && !isset($this->scopedServices[$this->scopes[$name]])) { + throw new RuntimeException(sprintf('The parent scope "%s" must be active when entering this scope.', $this->scopes[$name])); + } + + // check if a scope of this name is already active, if so we need to + // remove all services of this scope, and those of any of its child + // scopes from the global services map + if (isset($this->scopedServices[$name])) { + $services = array($this->services, $name => $this->scopedServices[$name]); + unset($this->scopedServices[$name]); + + foreach ($this->scopeChildren[$name] as $child) { + $services[$child] = $this->scopedServices[$child]; + unset($this->scopedServices[$child]); + } + + // update global map + $this->services = call_user_func_array('array_diff_key', $services); + array_shift($services); + + // add stack entry for this scope so we can restore the removed services later + if (!isset($this->scopeStacks[$name])) { + $this->scopeStacks[$name] = new \SplStack(); + } + $this->scopeStacks[$name]->push($services); + } + + $this->scopedServices[$name] = array(); + } + + /** + * This is called to leave the current scope, and move back to the parent + * scope. + * + * @param string $name The name of the scope to leave + * + * @throws InvalidArgumentException if the scope is not active + * + * @api + */ + public function leaveScope($name) + { + if (!isset($this->scopedServices[$name])) { + throw new InvalidArgumentException(sprintf('The scope "%s" is not active.', $name)); + } + + // remove all services of this scope, or any of its child scopes from + // the global service map + $services = array($this->services, $this->scopedServices[$name]); + unset($this->scopedServices[$name]); + foreach ($this->scopeChildren[$name] as $child) { + if (!isset($this->scopedServices[$child])) { + continue; + } + + $services[] = $this->scopedServices[$child]; + unset($this->scopedServices[$child]); + } + $this->services = call_user_func_array('array_diff_key', $services); + + // check if we need to restore services of a previous scope of this type + if (isset($this->scopeStacks[$name]) && count($this->scopeStacks[$name]) > 0) { + $services = $this->scopeStacks[$name]->pop(); + $this->scopedServices += $services; + + array_unshift($services, $this->services); + $this->services = call_user_func_array('array_merge', $services); + } + } + + /** + * Adds a scope to the container. + * + * @param ScopeInterface $scope + * + * @api + */ + public function addScope(ScopeInterface $scope) + { + $name = $scope->getName(); + $parentScope = $scope->getParentName(); + + if (self::SCOPE_CONTAINER === $name || self::SCOPE_PROTOTYPE === $name) { + throw new InvalidArgumentException(sprintf('The scope "%s" is reserved.', $name)); + } + if (isset($this->scopes[$name])) { + throw new InvalidArgumentException(sprintf('A scope with name "%s" already exists.', $name)); + } + if (self::SCOPE_CONTAINER !== $parentScope && !isset($this->scopes[$parentScope])) { + throw new InvalidArgumentException(sprintf('The parent scope "%s" does not exist, or is invalid.', $parentScope)); + } + + $this->scopes[$name] = $parentScope; + $this->scopeChildren[$name] = array(); + + // normalize the child relations + while ($parentScope !== self::SCOPE_CONTAINER) { + $this->scopeChildren[$parentScope][] = $name; + $parentScope = $this->scopes[$parentScope]; + } + } + + /** + * Returns whether this container has a certain scope + * + * @param string $name The name of the scope + * + * @return Boolean + * + * @api + */ + public function hasScope($name) + { + return isset($this->scopes[$name]); + } + + /** + * Returns whether this scope is currently active + * + * This does not actually check if the passed scope actually exists. + * + * @param string $name + * + * @return Boolean + * + * @api + */ + public function isScopeActive($name) + { + return isset($this->scopedServices[$name]); + } + + /** + * Camelizes a string. + * + * @param string $id A string to camelize + * + * @return string The camelized string + */ + static public function camelize($id) + { + return preg_replace_callback('/(^|_|\.)+(.)/', function ($match) { return ('.' === $match[1] ? '_' : '').strtoupper($match[2]); }, $id); + } + + /** + * A string to underscore. + * + * @param string $id The string to underscore + * + * @return string The underscored string + */ + static public function underscore($id) + { + return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), strtr($id, '_', '.'))); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ContainerAware.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ContainerAware.php new file mode 100644 index 0000000..4096915 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ContainerAware.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\DependencyInjection; + +/** + * A simple implementation of ContainerAwareInterface. + * + * @author Fabien Potencier + * + * @api + */ +abstract class ContainerAware implements ContainerAwareInterface +{ + /** + * @var ContainerInterface + * + * @api + */ + protected $container; + + /** + * Sets the Container associated with this Controller. + * + * @param ContainerInterface $container A ContainerInterface instance + * + * @api + */ + public function setContainer(ContainerInterface $container = null) + { + $this->container = $container; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ContainerAwareInterface.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ContainerAwareInterface.php new file mode 100644 index 0000000..1879ec0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ContainerAwareInterface.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\DependencyInjection; + +/** + * ContainerAwareInterface should be implemented by classes that depends on a Container. + * + * @author Fabien Potencier + * + * @api + */ +interface ContainerAwareInterface +{ + /** + * Sets the Container. + * + * @param ContainerInterface $container A ContainerInterface instance + * + * @api + */ + function setContainer(ContainerInterface $container = null); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ContainerBuilder.php new file mode 100644 index 0000000..a706229 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -0,0 +1,867 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Symfony\Component\DependencyInjection\Compiler\Compiler; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Compiler\PassConfig; +use Symfony\Component\DependencyInjection\Exception\BadMethodCallException; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\LogicException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Config\Resource\ResourceInterface; + +/** + * ContainerBuilder is a DI container that provides an API to easily describe services. + * + * @author Fabien Potencier + * + * @api + */ +class ContainerBuilder extends Container implements TaggedContainerInterface +{ + private $extensions = array(); + private $extensionsByNs = array(); + private $definitions = array(); + private $aliases = array(); + private $resources = array(); + private $extensionConfigs = array(); + private $compiler; + + /** + * Registers an extension. + * + * @param ExtensionInterface $extension An extension instance + * + * @api + */ + public function registerExtension(ExtensionInterface $extension) + { + $this->extensions[$extension->getAlias()] = $extension; + + if (false !== $extension->getNamespace()) { + $this->extensionsByNs[$extension->getNamespace()] = $extension; + } + } + + /** + * Returns an extension by alias or namespace. + * + * @param string $name An alias or a namespace + * + * @return ExtensionInterface An extension instance + * + * @api + */ + public function getExtension($name) + { + if (isset($this->extensions[$name])) { + return $this->extensions[$name]; + } + + if (isset($this->extensionsByNs[$name])) { + return $this->extensionsByNs[$name]; + } + + throw new LogicException(sprintf('Container extension "%s" is not registered', $name)); + } + + /** + * Returns all registered extensions. + * + * @return array An array of ExtensionInterface + * + * @api + */ + public function getExtensions() + { + return $this->extensions; + } + + /** + * Checks if we have an extension. + * + * @param string $name The name of the extension + * + * @return Boolean If the extension exists + * + * @api + */ + public function hasExtension($name) + { + return isset($this->extensions[$name]) || isset($this->extensionsByNs[$name]); + } + + /** + * Returns an array of resources loaded to build this configuration. + * + * @return ResourceInterface[] An array of resources + * + * @api + */ + public function getResources() + { + return array_unique($this->resources); + } + + /** + * Adds a resource for this configuration. + * + * @param ResourceInterface $resource A resource instance + * + * @return ContainerBuilder The current instance + * + * @api + */ + public function addResource(ResourceInterface $resource) + { + $this->resources[] = $resource; + + return $this; + } + + public function setResources(array $resources) + { + $this->resources = $resources; + + return $this; + } + + /** + * Adds the object class hierarchy as resources. + * + * @param object $object An object instance + * + * @api + */ + public function addObjectResource($object) + { + $parent = new \ReflectionObject($object); + do { + $this->addResource(new FileResource($parent->getFileName())); + } while ($parent = $parent->getParentClass()); + } + + /** + * Loads the configuration for an extension. + * + * @param string $extension The extension alias or namespace + * @param array $values An array of values that customizes the extension + * + * @return ContainerBuilder The current instance + * @throws BadMethodCallException When this ContainerBuilder is frozen + * + * @api + */ + public function loadFromExtension($extension, array $values = array()) + { + if ($this->isFrozen()) { + throw new BadMethodCallException('Cannot load from an extension on a frozen container.'); + } + + $namespace = $this->getExtension($extension)->getAlias(); + + $this->extensionConfigs[$namespace][] = $values; + + return $this; + } + + /** + * Adds a compiler pass. + * + * @param CompilerPassInterface $pass A compiler pass + * @param string $type The type of compiler pass + * + * @api + */ + public function addCompilerPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION) + { + if (null === $this->compiler) { + $this->compiler = new Compiler(); + } + + $this->compiler->addPass($pass, $type); + + $this->addObjectResource($pass); + } + + /** + * Returns the compiler pass config which can then be modified. + * + * @return PassConfig The compiler pass config + * + * @api + */ + public function getCompilerPassConfig() + { + if (null === $this->compiler) { + $this->compiler = new Compiler(); + } + + return $this->compiler->getPassConfig(); + } + + /** + * Returns the compiler. + * + * @return Compiler The compiler + * + * @api + */ + public function getCompiler() + { + if (null === $this->compiler) { + $this->compiler = new Compiler(); + } + + return $this->compiler; + } + + /** + * Returns all Scopes. + * + * @return array An array of scopes + * + * @api + */ + public function getScopes() + { + return $this->scopes; + } + + /** + * Returns all Scope children. + * + * @return array An array of scope children. + * + * @api + */ + public function getScopeChildren() + { + return $this->scopeChildren; + } + + /** + * Sets a service. + * + * @param string $id The service identifier + * @param object $service The service instance + * @param string $scope The scope + * + * @throws BadMethodCallException When this ContainerBuilder is frozen + * + * @api + */ + public function set($id, $service, $scope = self::SCOPE_CONTAINER) + { + if ($this->isFrozen()) { + throw new BadMethodCallException('Setting service on a frozen container is not allowed'); + } + + $id = strtolower($id); + + unset($this->definitions[$id], $this->aliases[$id]); + + parent::set($id, $service, $scope); + } + + /** + * Removes a service definition. + * + * @param string $id The service identifier + * + * @api + */ + public function removeDefinition($id) + { + unset($this->definitions[strtolower($id)]); + } + + /** + * Returns true if the given service is defined. + * + * @param string $id The service identifier + * + * @return Boolean true if the service is defined, false otherwise + * + * @api + */ + public function has($id) + { + $id = strtolower($id); + + return isset($this->definitions[$id]) || isset($this->aliases[$id]) || parent::has($id); + } + + /** + * Gets a service. + * + * @param string $id The service identifier + * @param integer $invalidBehavior The behavior when the service does not exist + * + * @return object The associated service + * + * @throws InvalidArgumentException if the service is not defined + * @throws LogicException if the service has a circular reference to itself + * + * @see Reference + * + * @api + */ + public function get($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) + { + $id = strtolower($id); + + try { + return parent::get($id, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE); + } catch (InvalidArgumentException $e) { + if (isset($this->loading[$id])) { + throw new LogicException(sprintf('The service "%s" has a circular reference to itself.', $id), 0, $e); + } + + if (!$this->hasDefinition($id) && isset($this->aliases[$id])) { + return $this->get($this->aliases[$id]); + } + + try { + $definition = $this->getDefinition($id); + } catch (InvalidArgumentException $e) { + if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) { + return null; + } + + throw $e; + } + + $this->loading[$id] = true; + + $service = $this->createService($definition, $id); + + unset($this->loading[$id]); + + return $service; + } + } + + /** + * Merges a ContainerBuilder with the current ContainerBuilder configuration. + * + * Service definitions overrides the current defined ones. + * + * But for parameters, they are overridden by the current ones. It allows + * the parameters passed to the container constructor to have precedence + * over the loaded ones. + * + * $container = new ContainerBuilder(array('foo' => 'bar')); + * $loader = new LoaderXXX($container); + * $loader->load('resource_name'); + * $container->register('foo', new stdClass()); + * + * In the above example, even if the loaded resource defines a foo + * parameter, the value will still be 'bar' as defined in the ContainerBuilder + * constructor. + * + * @param ContainerBuilder $container The ContainerBuilder instance to merge. + * + * + * @throws BadMethodCallException When this ContainerBuilder is frozen + * + * @api + */ + public function merge(ContainerBuilder $container) + { + if ($this->isFrozen()) { + throw new BadMethodCallException('Cannot merge on a frozen container.'); + } + + $this->addDefinitions($container->getDefinitions()); + $this->addAliases($container->getAliases()); + $this->getParameterBag()->add($container->getParameterBag()->all()); + + foreach ($container->getResources() as $resource) { + $this->addResource($resource); + } + + foreach ($this->extensions as $name => $extension) { + if (!isset($this->extensionConfigs[$name])) { + $this->extensionConfigs[$name] = array(); + } + + $this->extensionConfigs[$name] = array_merge($this->extensionConfigs[$name], $container->getExtensionConfig($name)); + } + } + + /** + * Returns the configuration array for the given extension. + * + * @param string $name The name of the extension + * + * @return array An array of configuration + * + * @api + */ + public function getExtensionConfig($name) + { + if (!isset($this->extensionConfigs[$name])) { + $this->extensionConfigs[$name] = array(); + } + + return $this->extensionConfigs[$name]; + } + + /** + * Compiles the container. + * + * This method passes the container to compiler + * passes whose job is to manipulate and optimize + * the container. + * + * The main compiler passes roughly do four things: + * + * * The extension configurations are merged; + * * Parameter values are resolved; + * * The parameter bag is frozen; + * * Extension loading is disabled. + * + * @api + */ + public function compile() + { + if (null === $this->compiler) { + $this->compiler = new Compiler(); + } + + foreach ($this->compiler->getPassConfig()->getPasses() as $pass) { + $this->addObjectResource($pass); + } + + $this->compiler->compile($this); + + $this->extensionConfigs = array(); + + parent::compile(); + } + + /** + * Gets all service ids. + * + * @return array An array of all defined service ids + */ + public function getServiceIds() + { + return array_unique(array_merge(array_keys($this->getDefinitions()), array_keys($this->aliases), parent::getServiceIds())); + } + + /** + * Adds the service aliases. + * + * @param array $aliases An array of aliases + * + * @api + */ + public function addAliases(array $aliases) + { + foreach ($aliases as $alias => $id) { + $this->setAlias($alias, $id); + } + } + + /** + * Sets the service aliases. + * + * @param array $aliases An array of service definitions + * + * @api + */ + public function setAliases(array $aliases) + { + $this->aliases = array(); + $this->addAliases($aliases); + } + + /** + * Sets an alias for an existing service. + * + * @param string $alias The alias to create + * @param mixed $id The service to alias + * + * @api + */ + public function setAlias($alias, $id) + { + $alias = strtolower($alias); + + if (is_string($id)) { + $id = new Alias($id); + } elseif (!$id instanceof Alias) { + throw new InvalidArgumentException('$id must be a string, or an Alias object.'); + } + + if ($alias === strtolower($id)) { + throw new InvalidArgumentException('An alias can not reference itself, got a circular reference on "'.$alias.'".'); + } + + unset($this->definitions[$alias]); + + $this->aliases[$alias] = $id; + } + + /** + * Removes an alias. + * + * @param string $alias The alias to remove + * + * @api + */ + public function removeAlias($alias) + { + unset($this->aliases[strtolower($alias)]); + } + + /** + * Returns true if an alias exists under the given identifier. + * + * @param string $id The service identifier + * + * @return Boolean true if the alias exists, false otherwise + * + * @api + */ + public function hasAlias($id) + { + return isset($this->aliases[strtolower($id)]); + } + + /** + * Gets all defined aliases. + * + * @return array An array of aliases + * + * @api + */ + public function getAliases() + { + return $this->aliases; + } + + /** + * Gets an alias. + * + * @param string $id The service identifier + * + * @return string The aliased service identifier + * + * @throws InvalidArgumentException if the alias does not exist + * + * @api + */ + public function getAlias($id) + { + $id = strtolower($id); + + if (!$this->hasAlias($id)) { + throw new InvalidArgumentException(sprintf('The service alias "%s" does not exist.', $id)); + } + + return $this->aliases[$id]; + } + + /** + * Registers a service definition. + * + * This methods allows for simple registration of service definition + * with a fluid interface. + * + * @param string $id The service identifier + * @param string $class The service class + * + * @return Definition A Definition instance + * + * @api + */ + public function register($id, $class = null) + { + return $this->setDefinition(strtolower($id), new Definition($class)); + } + + /** + * Adds the service definitions. + * + * @param Definition[] $definitions An array of service definitions + * + * @api + */ + public function addDefinitions(array $definitions) + { + foreach ($definitions as $id => $definition) { + $this->setDefinition($id, $definition); + } + } + + /** + * Sets the service definitions. + * + * @param array $definitions An array of service definitions + * + * @api + */ + public function setDefinitions(array $definitions) + { + $this->definitions = array(); + $this->addDefinitions($definitions); + } + + /** + * Gets all service definitions. + * + * @return array An array of Definition instances + * + * @api + */ + public function getDefinitions() + { + return $this->definitions; + } + + /** + * Sets a service definition. + * + * @param string $id The service identifier + * @param Definition $definition A Definition instance + * + * @throws BadMethodCallException When this ContainerBuilder is frozen + * + * @api + */ + public function setDefinition($id, Definition $definition) + { + if ($this->isFrozen()) { + throw new BadMethodCallException('Adding definition to a frozen container is not allowed'); + } + + $id = strtolower($id); + + unset($this->aliases[$id]); + + return $this->definitions[$id] = $definition; + } + + /** + * Returns true if a service definition exists under the given identifier. + * + * @param string $id The service identifier + * + * @return Boolean true if the service definition exists, false otherwise + * + * @api + */ + public function hasDefinition($id) + { + return array_key_exists(strtolower($id), $this->definitions); + } + + /** + * Gets a service definition. + * + * @param string $id The service identifier + * + * @return Definition A Definition instance + * + * @throws InvalidArgumentException if the service definition does not exist + * + * @api + */ + public function getDefinition($id) + { + $id = strtolower($id); + + if (!$this->hasDefinition($id)) { + throw new InvalidArgumentException(sprintf('The service definition "%s" does not exist.', $id)); + } + + return $this->definitions[$id]; + } + + /** + * Gets a service definition by id or alias. + * + * The method "unaliases" recursively to return a Definition instance. + * + * @param string $id The service identifier or alias + * + * @return Definition A Definition instance + * + * @throws InvalidArgumentException if the service definition does not exist + * + * @api + */ + public function findDefinition($id) + { + while ($this->hasAlias($id)) { + $id = (string) $this->getAlias($id); + } + + return $this->getDefinition($id); + } + + /** + * Creates a service for a service definition. + * + * @param Definition $definition A service definition instance + * @param string $id The service identifier + * + * @return object The service described by the service definition + * + * @throws RuntimeException When factory specification is incomplete or scope is inactive + * @throws InvalidArgumentException When configure callable is not callable + */ + private function createService(Definition $definition, $id) + { + if (null !== $definition->getFile()) { + require_once $this->getParameterBag()->resolveValue($definition->getFile()); + } + + $arguments = $this->resolveServices($this->getParameterBag()->resolveValue($definition->getArguments())); + + if (null !== $definition->getFactoryMethod()) { + if (null !== $definition->getFactoryClass()) { + $factory = $this->getParameterBag()->resolveValue($definition->getFactoryClass()); + } elseif (null !== $definition->getFactoryService()) { + $factory = $this->get($this->getParameterBag()->resolveValue($definition->getFactoryService())); + } else { + throw new RuntimeException('Cannot create service from factory method without a factory service or factory class.'); + } + + $service = call_user_func_array(array($factory, $definition->getFactoryMethod()), $arguments); + } else { + $r = new \ReflectionClass($this->getParameterBag()->resolveValue($definition->getClass())); + + $service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs($arguments); + } + + if (self::SCOPE_PROTOTYPE !== $scope = $definition->getScope()) { + if (self::SCOPE_CONTAINER !== $scope && !isset($this->scopedServices[$scope])) { + throw new RuntimeException('You tried to create a service of an inactive scope.'); + } + + $this->services[$lowerId = strtolower($id)] = $service; + + if (self::SCOPE_CONTAINER !== $scope) { + $this->scopedServices[$scope][$lowerId] = $service; + } + } + + foreach ($definition->getMethodCalls() as $call) { + $services = self::getServiceConditionals($call[1]); + + $ok = true; + foreach ($services as $s) { + if (!$this->has($s)) { + $ok = false; + break; + } + } + + if ($ok) { + call_user_func_array(array($service, $call[0]), $this->resolveServices($this->getParameterBag()->resolveValue($call[1]))); + } + } + + $properties = $this->resolveServices($this->getParameterBag()->resolveValue($definition->getProperties())); + foreach ($properties as $name => $value) { + $service->$name = $value; + } + + if ($callable = $definition->getConfigurator()) { + if (is_array($callable) && is_object($callable[0]) && $callable[0] instanceof Reference) { + $callable[0] = $this->get((string) $callable[0]); + } elseif (is_array($callable)) { + $callable[0] = $this->getParameterBag()->resolveValue($callable[0]); + } + + if (!is_callable($callable)) { + throw new InvalidArgumentException(sprintf('The configure callable for class "%s" is not a callable.', get_class($service))); + } + + call_user_func($callable, $service); + } + + return $service; + } + + /** + * Replaces service references by the real service instance. + * + * @param mixed $value A value + * + * @return mixed The same value with all service references replaced by the real service instances + */ + public function resolveServices($value) + { + if (is_array($value)) { + foreach ($value as &$v) { + $v = $this->resolveServices($v); + } + } elseif (is_object($value) && $value instanceof Reference) { + $value = $this->get((string) $value, $value->getInvalidBehavior()); + } elseif (is_object($value) && $value instanceof Definition) { + $value = $this->createService($value, null); + } + + return $value; + } + + /** + * Returns service ids for a given tag. + * + * @param string $name The tag name + * + * @return array An array of tags + * + * @api + */ + public function findTaggedServiceIds($name) + { + $tags = array(); + foreach ($this->getDefinitions() as $id => $definition) { + if ($definition->getTag($name)) { + $tags[$id] = $definition->getTag($name); + } + } + + return $tags; + } + + /** + * Returns the Service Conditionals. + * + * @param mixed $value An array of conditionals to return. + * + * @return array An array of Service conditionals + */ + static public function getServiceConditionals($value) + { + $services = array(); + + if (is_array($value)) { + foreach ($value as $v) { + $services = array_unique(array_merge($services, self::getServiceConditionals($v))); + } + } elseif (is_object($value) && $value instanceof Reference && $value->getInvalidBehavior() === ContainerInterface::IGNORE_ON_INVALID_REFERENCE) { + $services[] = (string) $value; + } + + return $services; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ContainerInterface.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ContainerInterface.php new file mode 100644 index 0000000..6a5988e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ContainerInterface.php @@ -0,0 +1,154 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * ContainerInterface is the interface implemented by service container classes. + * + * @author Fabien Potencier + * @author Johannes M. Schmitt + * + * @api + */ +interface ContainerInterface +{ + const EXCEPTION_ON_INVALID_REFERENCE = 1; + const NULL_ON_INVALID_REFERENCE = 2; + const IGNORE_ON_INVALID_REFERENCE = 3; + const SCOPE_CONTAINER = 'container'; + const SCOPE_PROTOTYPE = 'prototype'; + + /** + * Sets a service. + * + * @param string $id The service identifier + * @param object $service The service instance + * @param string $scope The scope of the service + * + * @api + */ + function set($id, $service, $scope = self::SCOPE_CONTAINER); + + /** + * Gets a service. + * + * @param string $id The service identifier + * @param int $invalidBehavior The behavior when the service does not exist + * + * @return object The associated service + * + * @throws InvalidArgumentException if the service is not defined + * + * @see Reference + * + * @api + */ + function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE); + + /** + * Returns true if the given service is defined. + * + * @param string $id The service identifier + * + * @return Boolean true if the service is defined, false otherwise + * + * @api + */ + function has($id); + + /** + * Gets a parameter. + * + * @param string $name The parameter name + * + * @return mixed The parameter value + * + * @throws InvalidArgumentException if the parameter is not defined + * + * @api + */ + function getParameter($name); + + /** + * Checks if a parameter exists. + * + * @param string $name The parameter name + * + * @return Boolean The presence of parameter in container + * + * @api + */ + function hasParameter($name); + + /** + * Sets a parameter. + * + * @param string $name The parameter name + * @param mixed $value The parameter value + * + * @api + */ + function setParameter($name, $value); + + /** + * Enters the given scope + * + * @param string $name + * + * @api + */ + function enterScope($name); + + /** + * Leaves the current scope, and re-enters the parent scope + * + * @param string $name + * + * @api + */ + function leaveScope($name); + + /** + * Adds a scope to the container + * + * @param ScopeInterface $scope + * + * @api + */ + function addScope(ScopeInterface $scope); + + /** + * Whether this container has the given scope + * + * @param string $name + * + * @return Boolean + * + * @api + */ + function hasScope($name); + + /** + * Determines whether the given scope is currently active. + * + * It does however not check if the scope actually exists. + * + * @param string $name + * + * @return Boolean + * + * @api + */ + function isScopeActive($name); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Definition.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Definition.php new file mode 100644 index 0000000..e7265f2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Definition.php @@ -0,0 +1,655 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException; + +/** + * Definition represents a service definition. + * + * @author Fabien Potencier + * + * @api + */ +class Definition +{ + private $class; + private $file; + private $factoryClass; + private $factoryMethod; + private $factoryService; + private $scope; + private $properties; + private $calls; + private $configurator; + private $tags; + private $public; + private $synthetic; + private $abstract; + + protected $arguments; + + /** + * Constructor. + * + * @param string $class The service class + * @param array $arguments An array of arguments to pass to the service constructor + * + * @api + */ + public function __construct($class = null, array $arguments = array()) + { + $this->class = $class; + $this->arguments = $arguments; + $this->calls = array(); + $this->scope = ContainerInterface::SCOPE_CONTAINER; + $this->tags = array(); + $this->public = true; + $this->synthetic = false; + $this->abstract = false; + $this->properties = array(); + } + + /** + * Sets the name of the class that acts as a factory using the factory method, + * which will be invoked statically. + * + * @param string $factoryClass The factory class name + * + * @return Definition The current instance + * + * @api + */ + public function setFactoryClass($factoryClass) + { + $this->factoryClass = $factoryClass; + + return $this; + } + + /** + * Gets the factory class. + * + * @return string The factory class name + * + * @api + */ + public function getFactoryClass() + { + return $this->factoryClass; + } + + /** + * Sets the factory method able to create an instance of this class. + * + * @param string $factoryMethod The factory method name + * + * @return Definition The current instance + * + * @api + */ + public function setFactoryMethod($factoryMethod) + { + $this->factoryMethod = $factoryMethod; + + return $this; + } + + /** + * Gets the factory method. + * + * @return string The factory method name + * + * @api + */ + public function getFactoryMethod() + { + return $this->factoryMethod; + } + + /** + * Sets the name of the service that acts as a factory using the factory method. + * + * @param string $factoryService The factory service id + * + * @return Definition The current instance + * + * @api + */ + public function setFactoryService($factoryService) + { + $this->factoryService = $factoryService; + + return $this; + } + + /** + * Gets the factory service id. + * + * @return string The factory service id + * + * @api + */ + public function getFactoryService() + { + return $this->factoryService; + } + + /** + * Sets the service class. + * + * @param string $class The service class + * + * @return Definition The current instance + * + * @api + */ + public function setClass($class) + { + $this->class = $class; + + return $this; + } + + /** + * Gets the service class. + * + * @return string The service class + * + * @api + */ + public function getClass() + { + return $this->class; + } + + /** + * Sets the arguments to pass to the service constructor/factory method. + * + * @param array $arguments An array of arguments + * + * @return Definition The current instance + * + * @api + */ + public function setArguments(array $arguments) + { + $this->arguments = $arguments; + + return $this; + } + + /** + * @api + */ + public function setProperties(array $properties) + { + $this->properties = $properties; + + return $this; + } + + /** + * @api + */ + public function getProperties() + { + return $this->properties; + } + + /** + * @api + */ + public function setProperty($name, $value) + { + $this->properties[$name] = $value; + + return $this; + } + + /** + * Adds an argument to pass to the service constructor/factory method. + * + * @param mixed $argument An argument + * + * @return Definition The current instance + * + * @api + */ + public function addArgument($argument) + { + $this->arguments[] = $argument; + + return $this; + } + + /** + * Sets a specific argument + * + * @param integer $index + * @param mixed $argument + * + * @return Definition The current instance + * + * @api + */ + public function replaceArgument($index, $argument) + { + if ($index < 0 || $index > count($this->arguments) - 1) { + throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, count($this->arguments) - 1)); + } + + $this->arguments[$index] = $argument; + + return $this; + } + + /** + * Gets the arguments to pass to the service constructor/factory method. + * + * @return array The array of arguments + * + * @api + */ + public function getArguments() + { + return $this->arguments; + } + + /** + * Gets an argument to pass to the service constructor/factory method. + * + * @param integer $index + * + * @return mixed The argument value + * + * @api + */ + public function getArgument($index) + { + if ($index < 0 || $index > count($this->arguments) - 1) { + throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, count($this->arguments) - 1)); + } + + return $this->arguments[$index]; + } + + /** + * Sets the methods to call after service initialization. + * + * @param array $calls An array of method calls + * + * @return Definition The current instance + * + * @api + */ + public function setMethodCalls(array $calls = array()) + { + $this->calls = array(); + foreach ($calls as $call) { + $this->addMethodCall($call[0], $call[1]); + } + + return $this; + } + + /** + * Adds a method to call after service initialization. + * + * @param string $method The method name to call + * @param array $arguments An array of arguments to pass to the method call + * + * @return Definition The current instance + * + * @throws InvalidArgumentException on empty $method param + * + * @api + */ + public function addMethodCall($method, array $arguments = array()) + { + if (empty($method)) { + throw new InvalidArgumentException(sprintf('Method name cannot be empty.')); + } + $this->calls[] = array($method, $arguments); + + return $this; + } + + /** + * Removes a method to call after service initialization. + * + * @param string $method The method name to remove + * + * @return Definition The current instance + * + * @api + */ + public function removeMethodCall($method) + { + foreach ($this->calls as $i => $call) { + if ($call[0] === $method) { + unset($this->calls[$i]); + break; + } + } + + return $this; + } + + /** + * Check if the current definition has a given method to call after service initialization. + * + * @param string $method The method name to search for + * + * @return Boolean + * + * @api + */ + public function hasMethodCall($method) + { + foreach ($this->calls as $call) { + if ($call[0] === $method) { + return true; + } + } + + return false; + } + + /** + * Gets the methods to call after service initialization. + * + * @return array An array of method calls + * + * @api + */ + public function getMethodCalls() + { + return $this->calls; + } + + /** + * Sets tags for this definition + * + * @param array $tags + * + * @return Definition the current instance + * + * @api + */ + public function setTags(array $tags) + { + $this->tags = $tags; + + return $this; + } + + /** + * Returns all tags. + * + * @return array An array of tags + * + * @api + */ + public function getTags() + { + return $this->tags; + } + + /** + * Gets a tag by name. + * + * @param string $name The tag name + * + * @return array An array of attributes + * + * @api + */ + public function getTag($name) + { + return isset($this->tags[$name]) ? $this->tags[$name] : array(); + } + + /** + * Adds a tag for this definition. + * + * @param string $name The tag name + * @param array $attributes An array of attributes + * + * @return Definition The current instance + * + * @api + */ + public function addTag($name, array $attributes = array()) + { + $this->tags[$name][] = $attributes; + + return $this; + } + + /** + * Whether this definition has a tag with the given name + * + * @param string $name + * + * @return Boolean + * + * @api + */ + public function hasTag($name) + { + return isset($this->tags[$name]); + } + + /** + * Clears all tags for a given name. + * + * @param string $name The tag name + * + * @return Definition + */ + public function clearTag($name) + { + if (isset($this->tags[$name])) { + unset($this->tags[$name]); + } + + return $this; + } + + /** + * Clears the tags for this definition. + * + * @return Definition The current instance + * + * @api + */ + public function clearTags() + { + $this->tags = array(); + + return $this; + } + + /** + * Sets a file to require before creating the service. + * + * @param string $file A full pathname to include + * + * @return Definition The current instance + * + * @api + */ + public function setFile($file) + { + $this->file = $file; + + return $this; + } + + /** + * Gets the file to require before creating the service. + * + * @return string The full pathname to include + * + * @api + */ + public function getFile() + { + return $this->file; + } + + /** + * Sets the scope of the service + * + * @param string $scope Whether the service must be shared or not + * + * @return Definition The current instance + * + * @api + */ + public function setScope($scope) + { + $this->scope = $scope; + + return $this; + } + + /** + * Returns the scope of the service + * + * @return string + * + * @api + */ + public function getScope() + { + return $this->scope; + } + + /** + * Sets the visibility of this service. + * + * @param Boolean $boolean + * + * @return Definition The current instance + * + * @api + */ + public function setPublic($boolean) + { + $this->public = (Boolean) $boolean; + + return $this; + } + + /** + * Whether this service is public facing + * + * @return Boolean + * + * @api + */ + public function isPublic() + { + return $this->public; + } + + /** + * Sets whether this definition is synthetic, that is not constructed by the + * container, but dynamically injected. + * + * @param Boolean $boolean + * + * @return Definition the current instance + * + * @api + */ + public function setSynthetic($boolean) + { + $this->synthetic = (Boolean) $boolean; + + return $this; + } + + /** + * Whether this definition is synthetic, that is not constructed by the + * container, but dynamically injected. + * + * @return Boolean + * + * @api + */ + public function isSynthetic() + { + return $this->synthetic; + } + + /** + * Whether this definition is abstract, that means it merely serves as a + * template for other definitions. + * + * @param Boolean $boolean + * + * @return Definition the current instance + * + * @api + */ + public function setAbstract($boolean) + { + $this->abstract = (Boolean) $boolean; + + return $this; + } + + /** + * Whether this definition is abstract, that means it merely serves as a + * template for other definitions. + * + * @return Boolean + * + * @api + */ + public function isAbstract() + { + return $this->abstract; + } + + /** + * Sets a configurator to call after the service is fully initialized. + * + * @param mixed $callable A PHP callable + * + * @return Definition The current instance + * + * @api + */ + public function setConfigurator($callable) + { + $this->configurator = $callable; + + return $this; + } + + /** + * Gets the configurator to call after the service is fully initialized. + * + * @return mixed The PHP callable to call + * + * @api + */ + public function getConfigurator() + { + return $this->configurator; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/DefinitionDecorator.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/DefinitionDecorator.php new file mode 100644 index 0000000..0306f75 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/DefinitionDecorator.php @@ -0,0 +1,205 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException; + +/** + * This definition decorates another definition. + * + * @author Johannes M. Schmitt + * + * @api + */ +class DefinitionDecorator extends Definition +{ + private $parent; + private $changes; + + /** + * Constructor. + * + * @param Definition $parent The Definition instance to decorate. + * + * @api + */ + public function __construct($parent) + { + parent::__construct(); + + $this->parent = $parent; + $this->changes = array(); + } + + /** + * Returns the Definition being decorated. + * + * @return Definition + * + * @api + */ + public function getParent() + { + return $this->parent; + } + + /** + * Returns all changes tracked for the Definition object. + * + * @return array An array of changes for this Definition + * + * @api + */ + public function getChanges() + { + return $this->changes; + } + + /** + * {@inheritDoc} + * + * @api + */ + public function setClass($class) + { + $this->changes['class'] = true; + + return parent::setClass($class); + } + + /** + * {@inheritDoc} + * + * @api + */ + public function setFactoryClass($class) + { + $this->changes['factory_class'] = true; + + return parent::setFactoryClass($class); + } + + /** + * {@inheritDoc} + * + * @api + */ + public function setFactoryMethod($method) + { + $this->changes['factory_method'] = true; + + return parent::setFactoryMethod($method); + } + + /** + * {@inheritDoc} + * + * @api + */ + public function setFactoryService($service) + { + $this->changes['factory_service'] = true; + + return parent::setFactoryService($service); + } + + /** + * {@inheritDoc} + * + * @api + */ + public function setConfigurator($callable) + { + $this->changes['configurator'] = true; + + return parent::setConfigurator($callable); + } + + /** + * {@inheritDoc} + * + * @api + */ + public function setFile($file) + { + $this->changes['file'] = true; + + return parent::setFile($file); + } + + /** + * {@inheritDoc} + * + * @api + */ + public function setPublic($boolean) + { + $this->changes['public'] = true; + + return parent::setPublic($boolean); + } + + /** + * Gets an argument to pass to the service constructor/factory method. + * + * If replaceArgument() has been used to replace an argument, this method + * will return the replacement value. + * + * @param integer $index + * + * @return mixed The argument value + * + * @api + */ + public function getArgument($index) + { + if (array_key_exists('index_'.$index, $this->arguments)) { + return $this->arguments['index_'.$index]; + } + + $lastIndex = count(array_filter(array_keys($this->arguments), 'is_int')) - 1; + + if ($index < 0 || $index > $lastIndex) { + throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, $lastIndex)); + } + + return $this->arguments[$index]; + } + + /** + * You should always use this method when overwriting existing arguments + * of the parent definition. + * + * If you directly call setArguments() keep in mind that you must follow + * certain conventions when you want to overwrite the arguments of the + * parent definition, otherwise your arguments will only be appended. + * + * @param integer $index + * @param mixed $value + * + * @return DefinitionDecorator the current instance + * @throws InvalidArgumentException when $index isn't an integer + * + * @api + */ + public function replaceArgument($index, $value) + { + if (!is_int($index)) { + throw new InvalidArgumentException('$index must be an integer.'); + } + + $this->arguments['index_'.$index] = $value; + + return $this; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/Dumper.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/Dumper.php new file mode 100644 index 0000000..9892401 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/Dumper.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\DependencyInjection\Dumper; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Dumper is the abstract class for all built-in dumpers. + * + * @author Fabien Potencier + * + * @api + */ +abstract class Dumper implements DumperInterface +{ + protected $container; + + /** + * Constructor. + * + * @param ContainerBuilder $container The service container to dump + * + * @api + */ + public function __construct(ContainerBuilder $container) + { + $this->container = $container; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/DumperInterface.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/DumperInterface.php new file mode 100644 index 0000000..6972cbf --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/DumperInterface.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\DependencyInjection\Dumper; + +/** + * DumperInterface is the interface implemented by service container dumper classes. + * + * @author Fabien Potencier + * + * @api + */ +interface DumperInterface +{ + /** + * Dumps the service container. + * + * @param array $options An array of options + * + * @return string The representation of the service container + * + * @api + */ + function dump(array $options = array()); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/GraphvizDumper.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/GraphvizDumper.php new file mode 100644 index 0000000..debdc52 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/GraphvizDumper.php @@ -0,0 +1,273 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Dumper; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * GraphvizDumper dumps a service container as a graphviz file. + * + * You can convert the generated dot file with the dot utility (http://www.graphviz.org/): + * + * dot -Tpng container.dot > foo.png + * + * @author Fabien Potencier + */ +class GraphvizDumper extends Dumper +{ + private $nodes; + private $edges; + private $options = array( + 'graph' => array('ratio' => 'compress'), + 'node' => array('fontsize' => 11, 'fontname' => 'Arial', 'shape' => 'record'), + 'edge' => array('fontsize' => 9, 'fontname' => 'Arial', 'color' => 'grey', 'arrowhead' => 'open', 'arrowsize' => 0.5), + 'node.instance' => array('fillcolor' => '#9999ff', 'style' => 'filled'), + 'node.definition' => array('fillcolor' => '#eeeeee'), + 'node.missing' => array('fillcolor' => '#ff9999', 'style' => 'filled'), + ); + + /** + * Dumps the service container as a graphviz graph. + * + * Available options: + * + * * graph: The default options for the whole graph + * * node: The default options for nodes + * * edge: The default options for edges + * * node.instance: The default options for services that are defined directly by object instances + * * node.definition: The default options for services that are defined via service definition instances + * * node.missing: The default options for missing services + * + * @param array $options An array of options + * + * @return string The dot representation of the service container + */ + public function dump(array $options = array()) + { + foreach (array('graph', 'node', 'edge', 'node.instance', 'node.definition', 'node.missing') as $key) { + if (isset($options[$key])) { + $this->options[$key] = array_merge($this->options[$key], $options[$key]); + } + } + + $this->nodes = $this->findNodes(); + + $this->edges = array(); + foreach ($this->container->getDefinitions() as $id => $definition) { + $this->edges[$id] = array_merge( + $this->findEdges($id, $definition->getArguments(), true, ''), + $this->findEdges($id, $definition->getProperties(), false, '') + ); + + foreach ($definition->getMethodCalls() as $call) { + $this->edges[$id] = array_merge( + $this->edges[$id], + $this->findEdges($id, $call[1], false, $call[0].'()') + ); + } + } + + return $this->startDot().$this->addNodes().$this->addEdges().$this->endDot(); + } + + /** + * Returns all nodes. + * + * @return string A string representation of all nodes + */ + private function addNodes() + { + $code = ''; + foreach ($this->nodes as $id => $node) { + $aliases = $this->getAliases($id); + + $code .= sprintf(" node_%s [label=\"%s\\n%s\\n\", shape=%s%s];\n", $this->dotize($id), $id.($aliases ? ' ('.implode(', ', $aliases).')' : ''), $node['class'], $this->options['node']['shape'], $this->addAttributes($node['attributes'])); + } + + return $code; + } + + /** + * Returns all edges. + * + * @return string A string representation of all edges + */ + private function addEdges() + { + $code = ''; + foreach ($this->edges as $id => $edges) { + foreach ($edges as $edge) { + $code .= sprintf(" node_%s -> node_%s [label=\"%s\" style=\"%s\"];\n", $this->dotize($id), $this->dotize($edge['to']), $edge['name'], $edge['required'] ? 'filled' : 'dashed'); + } + } + + return $code; + } + + /** + * Finds all edges belonging to a specific service id. + * + * @param string $id The service id used to find edges + * @param array $arguments An array of arguments + * @param Boolean $required + * @param string $name + * + * @return array An array of edges + */ + private function findEdges($id, $arguments, $required, $name) + { + $edges = array(); + foreach ($arguments as $argument) { + if (is_object($argument) && $argument instanceof Parameter) { + $argument = $this->container->hasParameter($argument) ? $this->container->getParameter($argument) : null; + } elseif (is_string($argument) && preg_match('/^%([^%]+)%$/', $argument, $match)) { + $argument = $this->container->hasParameter($match[1]) ? $this->container->getParameter($match[1]) : null; + } + + if ($argument instanceof Reference) { + if (!$this->container->has((string) $argument)) { + $this->nodes[(string) $argument] = array('name' => $name, 'required' => $required, 'class' => '', 'attributes' => $this->options['node.missing']); + } + + $edges[] = array('name' => $name, 'required' => $required, 'to' => $argument); + } elseif (is_array($argument)) { + $edges = array_merge($edges, $this->findEdges($id, $argument, $required, $name)); + } + } + + return $edges; + } + + /** + * Finds all nodes. + * + * @return array An array of all nodes + */ + private function findNodes() + { + $nodes = array(); + + $container = clone $this->container; + + foreach ($container->getDefinitions() as $id => $definition) { + $nodes[$id] = array('class' => str_replace('\\', '\\\\', $this->container->getParameterBag()->resolveValue($definition->getClass())), 'attributes' => array_merge($this->options['node.definition'], array('style' => ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope() ? 'filled' : 'dotted'))); + + $container->setDefinition($id, new Definition('stdClass')); + } + + foreach ($container->getServiceIds() as $id) { + $service = $container->get($id); + + if (in_array($id, array_keys($container->getAliases()))) { + continue; + } + + if (!$container->hasDefinition($id)) { + $nodes[$id] = array('class' => str_replace('\\', '\\\\', get_class($service)), 'attributes' => $this->options['node.instance']); + } + } + + return $nodes; + } + + /** + * Returns the start dot. + * + * @return string The string representation of a start dot + */ + private function startDot() + { + return sprintf("digraph sc {\n %s\n node [%s];\n edge [%s];\n\n", + $this->addOptions($this->options['graph']), + $this->addOptions($this->options['node']), + $this->addOptions($this->options['edge']) + ); + } + + /** + * Returns the end dot. + * + * @return string + */ + private function endDot() + { + return "}\n"; + } + + /** + * Adds attributes + * + * @param array $attributes An array of attributes + * + * @return string A comma separated list of attributes + */ + private function addAttributes($attributes) + { + $code = array(); + foreach ($attributes as $k => $v) { + $code[] = sprintf('%s="%s"', $k, $v); + } + + return $code ? ', '.implode(', ', $code) : ''; + } + + /** + * Adds options + * + * @param array $options An array of options + * + * @return string A space separated list of options + */ + private function addOptions($options) + { + $code = array(); + foreach ($options as $k => $v) { + $code[] = sprintf('%s="%s"', $k, $v); + } + + return implode(' ', $code); + } + + /** + * Dotizes an identifier. + * + * @param string $id The identifier to dotize + * + * @return string A dotized string + */ + private function dotize($id) + { + return strtolower(preg_replace('/[^\w]/i', '_', $id)); + } + + /** + * Compiles an array of aliases for a specified service id. + * + * @param string $id A service id + * + * @return array An array of aliases + */ + private function getAliases($id) + { + $aliases = array(); + foreach ($this->container->getAliases() as $alias => $origin) { + if ($id == $origin) { + $aliases[] = $alias; + } + } + + return $aliases; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php new file mode 100644 index 0000000..4d34e55 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -0,0 +1,1136 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Dumper; + +use Symfony\Component\DependencyInjection\Variable; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; + +/** + * PhpDumper dumps a service container as a PHP class. + * + * @author Fabien Potencier + * @author Johannes M. Schmitt + * + * @api + */ +class PhpDumper extends Dumper +{ + /** + * Characters that might appear in the generated variable name as first character + * @var string + */ + const FIRST_CHARS = 'abcdefghijklmnopqrstuvwxyz'; + + /** + * Characters that might appear in the generated variable name as any but the first character + * @var string + */ + const NON_FIRST_CHARS = 'abcdefghijklmnopqrstuvwxyz0123456789_'; + + private $inlinedDefinitions; + private $definitionVariables; + private $referenceVariables; + private $variableCount; + private $reservedVariables = array('instance', 'class'); + + /** + * {@inheritDoc} + * + * @api + */ + public function __construct(ContainerBuilder $container) + { + parent::__construct($container); + + $this->inlinedDefinitions = new \SplObjectStorage; + } + + /** + * Dumps the service container as a PHP class. + * + * Available options: + * + * * class: The class name + * * base_class: The base class name + * + * @param array $options An array of options + * + * @return string A PHP class representing of the service container + * + * @api + */ + public function dump(array $options = array()) + { + $options = array_merge(array( + 'class' => 'ProjectServiceContainer', + 'base_class' => 'Container', + ), $options); + + $code = $this->startClass($options['class'], $options['base_class']); + + if ($this->container->isFrozen()) { + $code .= $this->addFrozenConstructor(); + } else { + $code .= $this->addConstructor(); + } + + $code .= + $this->addServices(). + $this->addDefaultParametersMethod(). + $this->endClass() + ; + + return $code; + } + + /** + * Generates Service local temp variables. + * + * @param string $cId + * @param string $definition + * + * @return string + */ + private function addServiceLocalTempVariables($cId, $definition) + { + static $template = " \$%s = %s;\n"; + + $localDefinitions = array_merge( + array($definition), + $this->getInlinedDefinitions($definition) + ); + + $calls = $behavior = array(); + foreach ($localDefinitions as $iDefinition) { + $this->getServiceCallsFromArguments($iDefinition->getArguments(), $calls, $behavior); + $this->getServiceCallsFromArguments($iDefinition->getMethodCalls(), $calls, $behavior); + $this->getServiceCallsFromArguments($iDefinition->getProperties(), $calls, $behavior); + } + + $code = ''; + foreach ($calls as $id => $callCount) { + if ('service_container' === $id || $id === $cId) { + continue; + } + + if ($callCount > 1) { + $name = $this->getNextVariableName(); + $this->referenceVariables[$id] = new Variable($name); + + if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE === $behavior[$id]) { + $code .= sprintf($template, $name, $this->getServiceCall($id)); + } else { + $code .= sprintf($template, $name, $this->getServiceCall($id, new Reference($id, ContainerInterface::NULL_ON_INVALID_REFERENCE))); + } + } + } + + if ('' !== $code) { + $code .= "\n"; + } + + return $code; + } + + /** + * Generates the require_once statement for service includes. + * + * @param string $id The service id + * @param Definition $definition + * + * @return string + */ + private function addServiceInclude($id, $definition) + { + $template = " require_once %s;\n"; + $code = ''; + + if (null !== $file = $definition->getFile()) { + $code .= sprintf($template, $this->dumpValue($file)); + } + + foreach ($this->getInlinedDefinitions($definition) as $definition) { + if (null !== $file = $definition->getFile()) { + $code .= sprintf($template, $this->dumpValue($file)); + } + } + + if ('' !== $code) { + $code .= "\n"; + } + + return $code; + } + + /** + * Generates the inline definition of a service. + * + * @param string $id + * @param Definition $definition + * + * @return string + */ + private function addServiceInlinedDefinitions($id, $definition) + { + $code = ''; + $variableMap = $this->definitionVariables; + $nbOccurrences = new \SplObjectStorage(); + $processed = new \SplObjectStorage(); + $inlinedDefinitions = $this->getInlinedDefinitions($definition); + + foreach ($inlinedDefinitions as $definition) { + if (false === $nbOccurrences->contains($definition)) { + $nbOccurrences->offsetSet($definition, 1); + } else { + $i = $nbOccurrences->offsetGet($definition); + $nbOccurrences->offsetSet($definition, $i+1); + } + } + + foreach ($inlinedDefinitions as $sDefinition) { + if ($processed->contains($sDefinition)) { + continue; + } + $processed->offsetSet($sDefinition); + + $class = $this->dumpValue($sDefinition->getClass()); + if ($nbOccurrences->offsetGet($sDefinition) > 1 || count($sDefinition->getMethodCalls()) > 0 || $sDefinition->getProperties() || null !== $sDefinition->getConfigurator() || false !== strpos($class, '$')) { + $name = $this->getNextVariableName(); + $variableMap->offsetSet($sDefinition, new Variable($name)); + + // a construct like: + // $a = new ServiceA(ServiceB $b); $b = new ServiceB(ServiceA $a); + // this is an indication for a wrong implementation, you can circumvent this problem + // by setting up your service structure like this: + // $b = new ServiceB(); + // $a = new ServiceA(ServiceB $b); + // $b->setServiceA(ServiceA $a); + if ($this->hasReference($id, $sDefinition->getArguments())) { + throw new ServiceCircularReferenceException($id, array($id)); + } + + $arguments = array(); + foreach ($sDefinition->getArguments() as $argument) { + $arguments[] = $this->dumpValue($argument); + } + + if (null !== $sDefinition->getFactoryMethod()) { + if (null !== $sDefinition->getFactoryClass()) { + $code .= sprintf(" \$%s = call_user_func(array(%s, '%s')%s);\n", $name, $this->dumpValue($sDefinition->getFactoryClass()), $sDefinition->getFactoryMethod(), count($arguments) > 0 ? ', '.implode(', ', $arguments) : ''); + } elseif (null !== $sDefinition->getFactoryService()) { + $code .= sprintf(" \$%s = %s->%s(%s);\n", $name, $this->getServiceCall($sDefinition->getFactoryService()), $sDefinition->getFactoryMethod(), implode(', ', $arguments)); + } else { + throw new RuntimeException('Factory service or factory class must be defined in service definition for '.$id); + } + } elseif (false !== strpos($class, '$')) { + $code .= sprintf(" \$class = %s;\n \$%s = new \$class(%s);\n", $class, $name, implode(', ', $arguments)); + } else { + $code .= sprintf(" \$%s = new \\%s(%s);\n", $name, substr(str_replace('\\\\', '\\', $class), 1, -1), implode(', ', $arguments)); + } + + if (!$this->hasReference($id, $sDefinition->getMethodCalls()) && !$this->hasReference($id, $sDefinition->getProperties())) { + $code .= $this->addServiceMethodCalls(null, $sDefinition, $name); + $code .= $this->addServiceProperties(null, $sDefinition, $name); + $code .= $this->addServiceConfigurator(null, $sDefinition, $name); + } + + $code .= "\n"; + } + } + + return $code; + } + + /** + * Adds the service return statement. + * + * @param string $id Service id + * @param Definition $definition + * + * @return string + */ + private function addServiceReturn($id, $definition) + { + if ($this->isSimpleInstance($id, $definition)) { + return " }\n"; + } + + return "\n return \$instance;\n }\n"; + } + + /** + * Generates the service instance. + * + * @param string $id + * @param Definition $definition + * + * @return string + * + * @throws InvalidArgumentException + * @throws RuntimeException + */ + private function addServiceInstance($id, $definition) + { + $class = $this->dumpValue($definition->getClass()); + + if (0 === strpos($class, "'") && !preg_match('/^\'[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) { + throw new InvalidArgumentException(sprintf('"%s" is not a valid class name for the "%s" service.', $class, $id)); + } + + $arguments = array(); + foreach ($definition->getArguments() as $value) { + $arguments[] = $this->dumpValue($value); + } + + $simple = $this->isSimpleInstance($id, $definition); + + $instantiation = ''; + if (ContainerInterface::SCOPE_CONTAINER === $definition->getScope()) { + $instantiation = "\$this->services['$id'] = ".($simple ? '' : '$instance'); + } elseif (ContainerInterface::SCOPE_PROTOTYPE !== $scope = $definition->getScope()) { + $instantiation = "\$this->services['$id'] = \$this->scopedServices['$scope']['$id'] = ".($simple ? '' : '$instance'); + } elseif (!$simple) { + $instantiation = '$instance'; + } + + $return = ''; + if ($simple) { + $return = 'return '; + } else { + $instantiation .= ' = '; + } + + if (null !== $definition->getFactoryMethod()) { + if (null !== $definition->getFactoryClass()) { + $code = sprintf(" $return{$instantiation}call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($definition->getFactoryClass()), $definition->getFactoryMethod(), $arguments ? ', '.implode(', ', $arguments) : ''); + } elseif (null !== $definition->getFactoryService()) { + $code = sprintf(" $return{$instantiation}%s->%s(%s);\n", $this->getServiceCall($definition->getFactoryService()), $definition->getFactoryMethod(), implode(', ', $arguments)); + } else { + throw new RuntimeException('Factory method requires a factory service or factory class in service definition for '.$id); + } + } elseif (false !== strpos($class, '$')) { + $code = sprintf(" \$class = %s;\n\n $return{$instantiation}new \$class(%s);\n", $class, implode(', ', $arguments)); + } else { + $code = sprintf(" $return{$instantiation}new \\%s(%s);\n", substr(str_replace('\\\\', '\\', $class), 1, -1), implode(', ', $arguments)); + } + + if (!$simple) { + $code .= "\n"; + } + + return $code; + } + + /** + * Checks if the definition is a simple instance. + * + * @param string $id + * @param Definition $definition + * + * @return Boolean + */ + private function isSimpleInstance($id, $definition) + { + foreach (array_merge(array($definition), $this->getInlinedDefinitions($definition)) as $sDefinition) { + if ($definition !== $sDefinition && !$this->hasReference($id, $sDefinition->getMethodCalls())) { + continue; + } + + if ($sDefinition->getMethodCalls() || $sDefinition->getProperties() || $sDefinition->getConfigurator()) { + return false; + } + } + + return true; + } + + /** + * Adds method calls to a service definition. + * + * @param string $id + * @param Definition $definition + * @param string $variableName + * + * @return string + */ + private function addServiceMethodCalls($id, $definition, $variableName = 'instance') + { + $calls = ''; + foreach ($definition->getMethodCalls() as $call) { + $arguments = array(); + foreach ($call[1] as $value) { + $arguments[] = $this->dumpValue($value); + } + + $calls .= $this->wrapServiceConditionals($call[1], sprintf(" \$%s->%s(%s);\n", $variableName, $call[0], implode(', ', $arguments))); + } + + return $calls; + } + + private function addServiceProperties($id, $definition, $variableName = 'instance') + { + $code = ''; + foreach ($definition->getProperties() as $name => $value) { + $code .= sprintf(" \$%s->%s = %s;\n", $variableName, $name, $this->dumpValue($value)); + } + + return $code; + } + + /** + * Generates the inline definition setup. + * + * @param string $id + * @param Definition $definition + * @return string + */ + private function addServiceInlinedDefinitionsSetup($id, $definition) + { + $this->referenceVariables[$id] = new Variable('instance'); + + $code = ''; + $processed = new \SplObjectStorage(); + foreach ($this->getInlinedDefinitions($definition) as $iDefinition) { + if ($processed->contains($iDefinition)) { + continue; + } + $processed->offsetSet($iDefinition); + + if (!$this->hasReference($id, $iDefinition->getMethodCalls())) { + continue; + } + + if ($iDefinition->getMethodCalls()) { + $code .= $this->addServiceMethodCalls(null, $iDefinition, (string) $this->definitionVariables->offsetGet($iDefinition)); + } + if ($iDefinition->getConfigurator()) { + $code .= $this->addServiceConfigurator(null, $iDefinition, (string) $this->definitionVariables->offsetGet($iDefinition)); + } + } + + if ('' !== $code) { + $code .= "\n"; + } + + return $code; + } + + /** + * Adds configurator definition + * + * @param string $id + * @param Definition $definition + * @param string $variableName + * + * @return string + */ + private function addServiceConfigurator($id, $definition, $variableName = 'instance') + { + if (!$callable = $definition->getConfigurator()) { + return ''; + } + + if (is_array($callable)) { + if (is_object($callable[0]) && $callable[0] instanceof Reference) { + return sprintf(" %s->%s(\$%s);\n", $this->getServiceCall((string) $callable[0]), $callable[1], $variableName); + } + + return sprintf(" call_user_func(array(%s, '%s'), \$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); + } + + return sprintf(" %s(\$%s);\n", $callable, $variableName); + } + + /** + * Adds a service + * + * @param string $id + * @param Definition $definition + * + * @return string + */ + private function addService($id, $definition) + { + $name = Container::camelize($id); + $this->definitionVariables = new \SplObjectStorage(); + $this->referenceVariables = array(); + $this->variableCount = 0; + + $return = ''; + if ($definition->isSynthetic()) { + $return = sprintf('@throws RuntimeException always since this service is expected to be injected dynamically'); + } elseif ($class = $definition->getClass()) { + $return = sprintf("@return %s A %s instance.", 0 === strpos($class, '%') ? 'Object' : $class, $class); + } elseif ($definition->getFactoryClass()) { + $return = sprintf('@return Object An instance returned by %s::%s().', $definition->getFactoryClass(), $definition->getFactoryMethod()); + } elseif ($definition->getFactoryService()) { + $return = sprintf('@return Object An instance returned by %s::%s().', $definition->getFactoryService(), $definition->getFactoryMethod()); + } + + $doc = ''; + if (ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope()) { + $doc .= <<isPublic()) { + $doc .= <<getScope(); + if (ContainerInterface::SCOPE_CONTAINER !== $scope && ContainerInterface::SCOPE_PROTOTYPE !== $scope) { + $code .= <<scopedServices['$scope'])) { + throw new InactiveScopeException('$id', '$scope'); + } + + +EOF; + } + + if ($definition->isSynthetic()) { + $code .= sprintf(" throw new RuntimeException('You have requested a synthetic service (\"%s\"). The DIC does not know how to construct this service.');\n }\n", $id); + } else { + $code .= + $this->addServiceInclude($id, $definition). + $this->addServiceLocalTempVariables($id, $definition). + $this->addServiceInlinedDefinitions($id, $definition). + $this->addServiceInstance($id, $definition). + $this->addServiceInlinedDefinitionsSetup($id, $definition). + $this->addServiceMethodCalls($id, $definition). + $this->addServiceProperties($id, $definition). + $this->addServiceConfigurator($id, $definition). + $this->addServiceReturn($id, $definition) + ; + } + + $this->definitionVariables = null; + $this->referenceVariables = null; + + return $code; + } + + /** + * Adds a service alias. + * + * @param string $alias + * @param string $id + * + * @return string + */ + private function addServiceAlias($alias, $id) + { + $name = Container::camelize($alias); + $type = 'Object'; + + if ($this->container->hasDefinition($id)) { + $class = $this->container->getDefinition($id)->getClass(); + $type = 0 === strpos($class, '%') ? 'Object' : $class; + } + + return <<getServiceCall($id)}; + } + +EOF; + } + + /** + * Adds multiple services + * + * @return string + */ + private function addServices() + { + $publicServices = $privateServices = $aliasServices = ''; + $definitions = $this->container->getDefinitions(); + ksort($definitions); + foreach ($definitions as $id => $definition) { + if ($definition->isPublic()) { + $publicServices .= $this->addService($id, $definition); + } else { + $privateServices .= $this->addService($id, $definition); + } + } + + $aliases = $this->container->getAliases(); + ksort($aliases); + foreach ($aliases as $alias => $id) { + $aliasServices .= $this->addServiceAlias($alias, $id); + } + + return $publicServices.$aliasServices.$privateServices; + } + + /** + * Adds the class headers. + * + * @param string $class Class name + * @param string $baseClass The name of the base class + * + * @return string + */ + private function startClass($class, $baseClass) + { + $bagClass = $this->container->isFrozen() ? 'use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;' : 'use Symfony\Component\DependencyInjection\ParameterBag\\ParameterBag;'; + + return <<container->getParameterBag()->all() ? 'new ParameterBag($this->getDefaultParameters())' : null; + + $code = <<container->getScopes()) > 0) { + $code .= "\n"; + $code .= " \$this->scopes = ".$this->dumpValue($scopes).";\n"; + $code .= " \$this->scopeChildren = ".$this->dumpValue($this->container->getScopeChildren()).";\n"; + } + + $code .= <<parameters = \$this->getDefaultParameters(); + + \$this->services = + \$this->scopedServices = + \$this->scopeStacks = array(); + + \$this->set('service_container', \$this); + +EOF; + + $code .= "\n"; + if (count($scopes = $this->container->getScopes()) > 0) { + $code .= " \$this->scopes = ".$this->dumpValue($scopes).";\n"; + $code .= " \$this->scopeChildren = ".$this->dumpValue($this->container->getScopeChildren()).";\n"; + } else { + $code .= " \$this->scopes = array();\n"; + $code .= " \$this->scopeChildren = array();\n"; + } + + $code .= <<container->getParameterBag()->all()) { + return ''; + } + + $parameters = $this->exportParameters($this->container->getParameterBag()->all()); + + $code = ''; + if ($this->container->isFrozen()) { + $code .= <<parameters)) { + throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', \$name)); + } + + return \$this->parameters[\$name]; + } + + /** + * {@inheritdoc} + */ + public function hasParameter(\$name) + { + return array_key_exists(strtolower(\$name), \$this->parameters); + } + + /** + * {@inheritdoc} + */ + public function setParameter(\$name, \$value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + /** + * {@inheritDoc} + */ + public function getParameterBag() + { + if (null === \$this->parameterBag) { + \$this->parameterBag = new FrozenParameterBag(\$this->parameters); + } + + return \$this->parameterBag; + } +EOF; + } + + $code .= << $value) { + if (is_array($value)) { + $value = $this->exportParameters($value, $path.'/'.$key, $indent + 4); + } elseif ($value instanceof Variable) { + throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain variable references. Variable "%s" found in "%s".', $value, $path.'/'.$key)); + } elseif ($value instanceof Definition) { + throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain service definitions. Definition for "%s" found in "%s".', $value->getClass(), $path.'/'.$key)); + } elseif ($value instanceof Reference) { + throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain references to other services (reference to service "%s" found in "%s").', $value, $path.'/'.$key)); + } else { + $value = var_export($value, true); + } + + $php[] = sprintf('%s%s => %s,', str_repeat(' ', $indent), var_export($key, true), $value); + } + + return sprintf("array(\n%s\n%s)", implode("\n", $php), str_repeat(' ', $indent - 4)); + } + + /** + * Ends the class definition. + * + * @return string + */ + private function endClass() + { + return <<has('%s')", $service); + } + + // re-indent the wrapped code + $code = implode("\n", array_map(function ($line) { return $line ? ' '.$line : $line; }, explode("\n", $code))); + + return sprintf(" if (%s) {\n%s }\n", implode(' && ', $conditions), $code); + } + + /** + * Builds service calls from arguments + * + * @param array $arguments + * @param string &$calls By reference + * @param string &$behavior By reference + */ + private function getServiceCallsFromArguments(array $arguments, array &$calls, array &$behavior) + { + foreach ($arguments as $argument) { + if (is_array($argument)) { + $this->getServiceCallsFromArguments($argument, $calls, $behavior); + } elseif ($argument instanceof Reference) { + $id = (string) $argument; + + if (!isset($calls[$id])) { + $calls[$id] = 0; + } + if (!isset($behavior[$id])) { + $behavior[$id] = $argument->getInvalidBehavior(); + } elseif (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $behavior[$id]) { + $behavior[$id] = $argument->getInvalidBehavior(); + } + + $calls[$id] += 1; + } + } + } + + /** + * Returns the inline definition + * + * @param Definition $definition + * + * @return array + */ + private function getInlinedDefinitions(Definition $definition) + { + if (false === $this->inlinedDefinitions->contains($definition)) { + $definitions = array_merge( + $this->getDefinitionsFromArguments($definition->getArguments()), + $this->getDefinitionsFromArguments($definition->getMethodCalls()), + $this->getDefinitionsFromArguments($definition->getProperties()) + ); + + $this->inlinedDefinitions->offsetSet($definition, $definitions); + + return $definitions; + } + + return $this->inlinedDefinitions->offsetGet($definition); + } + + /** + * Gets the definition from arguments + * + * @param array $arguments + * + * @return array + */ + private function getDefinitionsFromArguments(array $arguments) + { + $definitions = array(); + foreach ($arguments as $argument) { + if (is_array($argument)) { + $definitions = array_merge($definitions, $this->getDefinitionsFromArguments($argument)); + } elseif ($argument instanceof Definition) { + $definitions = array_merge( + $definitions, + $this->getInlinedDefinitions($argument), + array($argument) + ); + } + } + + return $definitions; + } + + /** + * Checks if a service id has a reference + * + * @param string $id + * @param array $arguments + * + * @return Boolean + */ + private function hasReference($id, array $arguments) + { + foreach ($arguments as $argument) { + if (is_array($argument)) { + if ($this->hasReference($id, $argument)) { + return true; + } + } elseif ($argument instanceof Reference) { + if ($id === (string) $argument) { + return true; + } + } + } + + return false; + } + + /** + * Dumps values. + * + * @param array $value + * @param Boolean $interpolate + * + * @return string + */ + private function dumpValue($value, $interpolate = true) + { + if (is_array($value)) { + $code = array(); + foreach ($value as $k => $v) { + $code[] = sprintf('%s => %s', $this->dumpValue($k, $interpolate), $this->dumpValue($v, $interpolate)); + } + + return sprintf('array(%s)', implode(', ', $code)); + } elseif (is_object($value) && $value instanceof Definition) { + if (null !== $this->definitionVariables && $this->definitionVariables->contains($value)) { + return $this->dumpValue($this->definitionVariables->offsetGet($value), $interpolate); + } + if (count($value->getMethodCalls()) > 0) { + throw new RuntimeException('Cannot dump definitions which have method calls.'); + } + if (null !== $value->getConfigurator()) { + throw new RuntimeException('Cannot dump definitions which have a configurator.'); + } + + $arguments = array(); + foreach ($value->getArguments() as $argument) { + $arguments[] = $this->dumpValue($argument); + } + $class = $this->dumpValue($value->getClass()); + + if (false !== strpos($class, '$')) { + throw new RuntimeException('Cannot dump definitions which have a variable class name.'); + } + + if (null !== $value->getFactoryMethod()) { + if (null !== $value->getFactoryClass()) { + return sprintf("call_user_func(array(%s, '%s')%s)", $this->dumpValue($value->getFactoryClass()), $value->getFactoryMethod(), count($arguments) > 0 ? ', '.implode(', ', $arguments) : ''); + } elseif (null !== $value->getFactoryService()) { + return sprintf("%s->%s(%s)", $this->getServiceCall($value->getFactoryService()), $value->getFactoryMethod(), implode(', ', $arguments)); + } else { + throw new RuntimeException('Cannot dump definitions which have factory method without factory service or factory class.'); + } + } + + return sprintf("new \\%s(%s)", substr(str_replace('\\\\', '\\', $class), 1, -1), implode(', ', $arguments)); + } elseif (is_object($value) && $value instanceof Variable) { + return '$'.$value; + } elseif (is_object($value) && $value instanceof Reference) { + if (null !== $this->referenceVariables && isset($this->referenceVariables[$id = (string) $value])) { + return $this->dumpValue($this->referenceVariables[$id], $interpolate); + } + + return $this->getServiceCall((string) $value, $value); + } elseif (is_object($value) && $value instanceof Parameter) { + return $this->dumpParameter($value); + } elseif (true === $interpolate && is_string($value)) { + if (preg_match('/^%([^%]+)%$/', $value, $match)) { + // we do this to deal with non string values (Boolean, integer, ...) + // the preg_replace_callback converts them to strings + return $this->dumpParameter(strtolower($match[1])); + } else { + $that = $this; + $replaceParameters = function ($match) use ($that) { + return "'.".$that->dumpParameter(strtolower($match[2])).".'"; + }; + + $code = str_replace('%%', '%', preg_replace_callback('/(?container->isFrozen() && $this->container->hasParameter($name)) { + return $this->dumpValue($this->container->getParameter($name), false); + } + + return sprintf("\$this->getParameter('%s')", strtolower($name)); + } + + /** + * Gets a service call + * + * @param string $id + * @param Reference $reference + * + * @return string + */ + private function getServiceCall($id, Reference $reference = null) + { + if ('service_container' === $id) { + return '$this'; + } + + if (null !== $reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $reference->getInvalidBehavior()) { + return sprintf('$this->get(\'%s\', ContainerInterface::NULL_ON_INVALID_REFERENCE)', $id); + } else { + if ($this->container->hasAlias($id)) { + $id = (string) $this->container->getAlias($id); + } + + return sprintf('$this->get(\'%s\')', $id); + } + } + + /** + * Returns the next name to use + * + * @return string + */ + private function getNextVariableName() + { + $firstChars = self::FIRST_CHARS; + $firstCharsLength = strlen($firstChars); + $nonFirstChars = self::NON_FIRST_CHARS; + $nonFirstCharsLength = strlen($nonFirstChars); + + while (true) { + $name = ''; + $i = $this->variableCount; + + if ('' === $name) { + $name .= $firstChars[$i%$firstCharsLength]; + $i = intval($i/$firstCharsLength); + } + + while ($i > 0) { + $i -= 1; + $name .= $nonFirstChars[$i%$nonFirstCharsLength]; + $i = intval($i/$nonFirstCharsLength); + } + + $this->variableCount += 1; + + // check that the name is not reserved + if (in_array($name, $this->reservedVariables, true)) { + continue; + } + + return $name; + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php new file mode 100644 index 0000000..113a242 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php @@ -0,0 +1,301 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Dumper; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * XmlDumper dumps a service container as an XML string. + * + * @author Fabien Potencier + * @author Martin Hasoň + * + * @api + */ +class XmlDumper extends Dumper +{ + /** + * @var \DOMDocument + */ + private $document; + + /** + * Dumps the service container as an XML string. + * + * @param array $options An array of options + * + * @return string An xml string representing of the service container + * + * @api + */ + public function dump(array $options = array()) + { + $this->document = new \DOMDocument('1.0', 'utf-8'); + $this->document->formatOutput = true; + + $container = $this->document->createElementNS('http://symfony.com/schema/dic/services', 'container'); + $container->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); + $container->setAttribute('xsi:schemaLocation', 'http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd'); + + $this->addParameters($container); + $this->addServices($container); + + $this->document->appendChild($container); + $xml = $this->document->saveXML(); + $this->document = null; + + return $xml; + } + + /** + * Adds parameters. + * + * @param DOMElement $parent + */ + private function addParameters(\DOMElement $parent) + { + $data = $this->container->getParameterBag()->all(); + if (!$data) { + return; + } + + if ($this->container->isFrozen()) { + $data = $this->escape($data); + } + + $parameters = $this->document->createElement('parameters'); + $parent->appendChild($parameters); + $this->convertParameters($data, 'parameter', $parameters); + } + + /** + * Adds method calls. + * + * @param array $methodcalls + * @param DOMElement $parent + */ + private function addMethodCalls(array $methodcalls, \DOMElement $parent) + { + foreach ($methodcalls as $methodcall) { + $call = $this->document->createElement('call'); + $call->setAttribute('method', $methodcall[0]); + if (count($methodcall[1])) { + $this->convertParameters($methodcall[1], 'argument', $call); + } + $parent->appendChild($call); + } + } + + /** + * Adds a service. + * + * @param Definition $definition + * @param string $id + * @param DOMElement $parent + */ + private function addService($definition, $id, \DOMElement $parent) + { + $service = $this->document->createElement('service'); + if (null !== $id) { + $service->setAttribute('id', $id); + } + if ($definition->getClass()) { + $service->setAttribute('class', $definition->getClass()); + } + if ($definition->getFactoryMethod()) { + $service->setAttribute('factory-method', $definition->getFactoryMethod()); + } + if ($definition->getFactoryService()) { + $service->setAttribute('factory-service', $definition->getFactoryService()); + } + if (ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope()) { + $service->setAttribute('scope', $scope); + } + if (!$definition->isPublic()) { + $service->setAttribute('public', 'false'); + } + + foreach ($definition->getTags() as $name => $tags) { + foreach ($tags as $attributes) { + $tag = $this->document->createElement('tag'); + $tag->setAttribute('name', $name); + foreach ($attributes as $key => $value) { + $tag->setAttribute($key, $value); + } + $service->appendChild($tag); + } + } + + if ($definition->getFile()) { + $file = $this->document->createElement('file'); + $file->appendChild($this->document->createTextNode($definition->getFile())); + $service->appendChild($file); + } + + if ($parameters = $definition->getArguments()) { + $this->convertParameters($parameters, 'argument', $service); + } + + if ($parameters = $definition->getProperties()) { + $this->convertParameters($parameters, 'property', $service, 'name'); + } + + $this->addMethodCalls($definition->getMethodCalls(), $service); + + if ($callable = $definition->getConfigurator()) { + $configurator = $this->document->createElement('configurator'); + if (is_array($callable)) { + $configurator->setAttribute((is_object($callable[0]) && $callable[0] instanceof Reference ? 'service' : 'class'), $callable[0]); + $configurator->setAttribute('method', $callable[1]); + } else { + $configurator->setAttribute('function', $callable); + } + $service->appendChild($configurator); + } + + $parent->appendChild($service); + } + + /** + * Adds a service alias. + * + * @param string $alias + * @param string $id + * @param DOMElement $parent + */ + private function addServiceAlias($alias, $id, \DOMElement $parent) + { + $service = $this->document->createElement('service'); + $service->setAttribute('id', $alias); + $service->setAttribute('alias', $id); + if (!$id->isPublic()) { + $service->setAttribute('public', 'false'); + } + $parent->appendChild($service); + } + + /** + * Adds services. + * + * @param DOMElement $parent + */ + private function addServices(\DOMElement $parent) + { + $definitions = $this->container->getDefinitions(); + if (!$definitions) { + return; + } + + $services = $this->document->createElement('services'); + foreach ($definitions as $id => $definition) { + $this->addService($definition, $id, $services); + } + + foreach ($this->container->getAliases() as $alias => $id) { + $this->addServiceAlias($alias, $id, $services); + } + $parent->appendChild($services); + } + + /** + * Converts parameters. + * + * @param array $parameters + * @param string $type + * @param DOMElement $parent + * @param string $keyAttribute + */ + private function convertParameters($parameters, $type, \DOMElement $parent, $keyAttribute = 'key') + { + $withKeys = array_keys($parameters) !== range(0, count($parameters) - 1); + foreach ($parameters as $key => $value) { + $element = $this->document->createElement($type); + if ($withKeys) { + $element->setAttribute($keyAttribute, $key); + } + + if (is_array($value)) { + $element->setAttribute('type', 'collection'); + $this->convertParameters($value, $type, $element, 'key'); + } elseif (is_object($value) && $value instanceof Reference) { + $element->setAttribute('type', 'service'); + $element->setAttribute('id', (string) $value); + $behaviour = $value->getInvalidBehavior(); + if ($behaviour == ContainerInterface::NULL_ON_INVALID_REFERENCE) { + $element->setAttribute('on-invalid', 'null'); + } elseif ($behaviour == ContainerInterface::IGNORE_ON_INVALID_REFERENCE) { + $element->setAttribute('on-invalid', 'ignore'); + } + } elseif (is_object($value) && $value instanceof Definition) { + $element->setAttribute('type', 'service'); + $this->addService($value, null, $element); + } else { + if (in_array($value, array('null', 'true', 'false'), true)) { + $element->setAttribute('type', 'string'); + } + $text = $this->document->createTextNode(self::phpToXml($value)); + $element->appendChild($text); + } + $parent->appendChild($element); + } + } + + /** + * Escapes arguments + * + * @param array $arguments + * + * @return array + */ + private function escape($arguments) + { + $args = array(); + foreach ($arguments as $k => $v) { + if (is_array($v)) { + $args[$k] = $this->escape($v); + } elseif (is_string($v)) { + $args[$k] = str_replace('%', '%%', $v); + } else { + $args[$k] = $v; + } + } + + return $args; + } + + /** + * Converts php types to xml types. + * + * @param mixed $value Value to convert + */ + static public function phpToXml($value) + { + switch (true) { + case null === $value: + return 'null'; + case true === $value: + return 'true'; + case false === $value: + return 'false'; + case is_object($value) && $value instanceof Parameter: + return '%'.$value.'%'; + case is_object($value) || is_resource($value): + throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.'); + default: + return (string) $value; + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php new file mode 100644 index 0000000..9717a25 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php @@ -0,0 +1,295 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Dumper; + +use Symfony\Component\Yaml\Dumper as YmlDumper; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * YamlDumper dumps a service container as a YAML string. + * + * @author Fabien Potencier + * + * @api + */ +class YamlDumper extends Dumper +{ + private $dumper; + + /** + * Constructor. + * + * @param ContainerBuilder $container The service container to dump + * + * @api + */ + public function __construct(ContainerBuilder $container) + { + parent::__construct($container); + + $this->dumper = new YmlDumper(); + } + + /** + * Dumps the service container as an YAML string. + * + * @param array $options An array of options + * + * @return string A YAML string representing of the service container + * + * @api + */ + public function dump(array $options = array()) + { + return $this->addParameters()."\n".$this->addServices(); + } + + /** + * Adds a service + * + * @param string $id + * @param Definition $definition + * + * @return string + */ + private function addService($id, $definition) + { + $code = " $id:\n"; + if ($definition->getClass()) { + $code .= sprintf(" class: %s\n", $definition->getClass()); + } + + $tagsCode = ''; + foreach ($definition->getTags() as $name => $tags) { + foreach ($tags as $attributes) { + $att = array(); + foreach ($attributes as $key => $value) { + $att[] = sprintf('%s: %s', $this->dumper->dump($key), $this->dumper->dump($value)); + } + $att = $att ? ', '.implode(' ', $att) : ''; + + $tagsCode .= sprintf(" - { name: %s%s }\n", $this->dumper->dump($name), $att); + } + } + if ($tagsCode) { + $code .= " tags:\n".$tagsCode; + } + + if ($definition->getFile()) { + $code .= sprintf(" file: %s\n", $definition->getFile()); + } + + if ($definition->getFactoryMethod()) { + $code .= sprintf(" factory_method: %s\n", $definition->getFactoryMethod()); + } + + if ($definition->getFactoryService()) { + $code .= sprintf(" factory_service: %s\n", $definition->getFactoryService()); + } + + if ($definition->getArguments()) { + $code .= sprintf(" arguments: %s\n", $this->dumper->dump($this->dumpValue($definition->getArguments()), 0)); + } + + if ($definition->getProperties()) { + $code .= sprintf(" properties: %s\n", $this->dumper->dump($this->dumpValue($definition->getProperties()), 0)); + } + + if ($definition->getMethodCalls()) { + $code .= sprintf(" calls:\n%s\n", $this->dumper->dump($this->dumpValue($definition->getMethodCalls()), 1, 12)); + } + + if (ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope()) { + $code .= sprintf(" scope: %s\n", $scope); + } + + if ($callable = $definition->getConfigurator()) { + if (is_array($callable)) { + if (is_object($callable[0]) && $callable[0] instanceof Reference) { + $callable = array($this->getServiceCall((string) $callable[0], $callable[0]), $callable[1]); + } else { + $callable = array($callable[0], $callable[1]); + } + } + + $code .= sprintf(" configurator: %s\n", $this->dumper->dump($callable, 0)); + } + + return $code; + } + + /** + * Adds a service alias + * + * @param string $alias + * @param string $id + * + * @return string + */ + private function addServiceAlias($alias, $id) + { + if ($id->isPublic()) { + return sprintf(" %s: @%s\n", $alias, $id); + } else { + return sprintf(" %s:\n alias: %s\n public: false", $alias, $id); + } + } + + /** + * Adds services + * + * @return string + */ + private function addServices() + { + if (!$this->container->getDefinitions()) { + return ''; + } + + $code = "services:\n"; + foreach ($this->container->getDefinitions() as $id => $definition) { + $code .= $this->addService($id, $definition); + } + + foreach ($this->container->getAliases() as $alias => $id) { + $code .= $this->addServiceAlias($alias, $id); + } + + return $code; + } + + /** + * Adds parameters + * + * @return string + */ + private function addParameters() + { + if (!$this->container->getParameterBag()->all()) { + return ''; + } + + if ($this->container->isFrozen()) { + $parameters = $this->prepareParameters($this->container->getParameterBag()->all()); + } else { + $parameters = $this->container->getParameterBag()->all(); + } + + return $this->dumper->dump(array('parameters' => $parameters), 2); + } + + /** + * Dumps the value to YAML format + * + * @param mixed $value + * + * @throws RuntimeException When trying to dump object or resource + */ + private function dumpValue($value) + { + if (is_array($value)) { + $code = array(); + foreach ($value as $k => $v) { + $code[$k] = $this->dumpValue($v); + } + + return $code; + } elseif (is_object($value) && $value instanceof Reference) { + return $this->getServiceCall((string) $value, $value); + } elseif (is_object($value) && $value instanceof Parameter) { + return $this->getParameterCall((string) $value); + } elseif (is_object($value) || is_resource($value)) { + throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.'); + } + + return $value; + } + + /** + * Gets the service call. + * + * @param string $id + * @param Reference $reference + * + * @return string + */ + private function getServiceCall($id, Reference $reference = null) + { + if (null !== $reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $reference->getInvalidBehavior()) { + return sprintf('@?%s', $id); + } + + return sprintf('@%s', $id); + } + + /** + * Gets parameter call. + * + * @param string $id + * + * @return string + */ + private function getParameterCall($id) + { + return sprintf('%%%s%%', $id); + } + + /** + * Prepares parameters + * + * @param array $parameters + * + * @return array + */ + private function prepareParameters($parameters) + { + $filtered = array(); + foreach ($parameters as $key => $value) { + if (is_array($value)) { + $value = $this->prepareParameters($value); + } elseif ($value instanceof Reference) { + $value = '@'.$value; + } + + $filtered[$key] = $value; + } + + return $this->escape($filtered); + } + + /** + * Escapes arguments + * + * @param array $arguments + * + * @return array + */ + private function escape($arguments) + { + $args = array(); + foreach ($arguments as $k => $v) { + if (is_array($v)) { + $args[$k] = $this->escape($v); + } elseif (is_string($v)) { + $args[$k] = str_replace('%', '%%', $v); + } else { + $args[$k] = $v; + } + } + + return $args; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/BadMethodCallException.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/BadMethodCallException.php new file mode 100644 index 0000000..959238e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/BadMethodCallException.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\DependencyInjection\Exception; + +/** + * Base BadMethodCallException for Dependency Injection component. + */ +class BadMethodCallException extends \BadMethodCallException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ExceptionInterface.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ExceptionInterface.php new file mode 100644 index 0000000..f5e9099 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ExceptionInterface.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\DependencyInjection\Exception; + +/** + * Base ExceptionInterface for Dependency Injection component. + * + * @author Fabien Potencier + * @author Bulat Shakirzyanov + */ +interface ExceptionInterface +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/InactiveScopeException.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/InactiveScopeException.php new file mode 100644 index 0000000..24d1ca0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/InactiveScopeException.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\DependencyInjection\Exception; + +/** + * This exception is thrown when you try to create a service of an inactive scope. + * + * @author Johannes M. Schmitt + */ +class InactiveScopeException extends RuntimeException +{ + private $serviceId; + private $scope; + + public function __construct($serviceId, $scope) + { + parent::__construct(sprintf('You cannot create a service ("%s") of an inactive scope ("%s").', $serviceId, $scope)); + + $this->serviceId = $serviceId; + $this->scope = $scope; + } + + public function getServiceId() + { + return $this->serviceId; + } + + public function getScope() + { + return $this->scope; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/InvalidArgumentException.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/InvalidArgumentException.php new file mode 100644 index 0000000..119bb7d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/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\DependencyInjection\Exception; + +/** + * Base InvalidArgumentException for Dependency Injection component. + * + * @author Bulat Shakirzyanov + */ +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/LogicException.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/LogicException.php new file mode 100644 index 0000000..17a070c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/LogicException.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\DependencyInjection\Exception; + +/** + * Base LogicException for Dependency Injection component. + */ +class LogicException extends \LogicException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/OutOfBoundsException.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/OutOfBoundsException.php new file mode 100644 index 0000000..a61f143 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/OutOfBoundsException.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\DependencyInjection\Exception; + +/** + * Base OutOfBoundsException for Dependency Injection component. + */ +class OutOfBoundsException extends \OutOfBoundsException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ParameterCircularReferenceException.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ParameterCircularReferenceException.php new file mode 100644 index 0000000..958ade0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ParameterCircularReferenceException.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\DependencyInjection\Exception; + +/** + * This exception is thrown when a circular reference in a parameter is detected. + * + * @author Fabien Potencier + */ +class ParameterCircularReferenceException extends RuntimeException +{ + private $parameters; + + public function __construct($parameters) + { + parent::__construct(sprintf('Circular reference detected for parameter "%s" ("%s" > "%s").', $parameters[0], implode('" > "', $parameters), $parameters[0])); + + $this->parameters = $parameters; + } + + public function getParameters() + { + return $this->parameters; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ParameterNotFoundException.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ParameterNotFoundException.php new file mode 100644 index 0000000..200fbec --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ParameterNotFoundException.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\DependencyInjection\Exception; + +/** + * This exception is thrown when a non-existent parameter is used. + * + * @author Fabien Potencier + */ +class ParameterNotFoundException extends InvalidArgumentException +{ + private $key; + private $sourceId; + private $sourceKey; + + /** + * Constructor. + * + * @param string $key The requested parameter key + * @param string $sourceId The service id that references the non-existent parameter + * @param string $sourceKey The parameter key that references the non-existent parameter + */ + public function __construct($key, $sourceId = null, $sourceKey = null) + { + $this->key = $key; + $this->sourceId = $sourceId; + $this->sourceKey = $sourceKey; + + $this->updateRepr(); + } + + public function updateRepr() + { + if (null !== $this->sourceId) { + $this->message = sprintf('The service "%s" has a dependency on a non-existent parameter "%s".', $this->sourceId, $this->key); + } elseif (null !== $this->sourceKey) { + $this->message = sprintf('The parameter "%s" has a dependency on a non-existent parameter "%s".', $this->sourceKey, $this->key); + } else { + $this->message = sprintf('You have requested a non-existent parameter "%s".', $this->key); + } + } + + public function getKey() + { + return $this->key; + } + + public function getSourceId() + { + return $this->sourceId; + } + + public function getSourceKey() + { + return $this->sourceKey; + } + + public function setSourceId($sourceId) + { + $this->sourceId = $sourceId; + + $this->updateRepr(); + } + + public function setSourceKey($sourceKey) + { + $this->sourceKey = $sourceKey; + + $this->updateRepr(); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/RuntimeException.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/RuntimeException.php new file mode 100644 index 0000000..5c24541 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/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\DependencyInjection\Exception; + +/** + * Base RuntimeException for Dependency Injection component. + * + * @author Johannes M. Schmitt + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ScopeCrossingInjectionException.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ScopeCrossingInjectionException.php new file mode 100644 index 0000000..f23374f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ScopeCrossingInjectionException.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\DependencyInjection\Exception; + +/** + * This exception is thrown when the a scope crossing injection is detected. + * + * @author Johannes M. Schmitt + */ +class ScopeCrossingInjectionException extends RuntimeException +{ + private $sourceServiceId; + private $sourceScope; + private $destServiceId; + private $destScope; + + public function __construct($sourceServiceId, $sourceScope, $destServiceId, $destScope) + { + parent::__construct(sprintf( + 'Scope Crossing Injection detected: The definition "%s" references the service "%s" which belongs to another scope hierarchy. ' + .'This service might not be available consistently. Generally, it is safer to either move the definition "%s" to scope "%s", or ' + .'declare "%s" as a child scope of "%s". If you can be sure that the other scope is always active, you can set the reference to strict=false to get rid of this error.', + $sourceServiceId, + $destServiceId, + $sourceServiceId, + $destScope, + $sourceScope, + $destScope + )); + + $this->sourceServiceId = $sourceServiceId; + $this->sourceScope = $sourceScope; + $this->destServiceId = $destServiceId; + $this->destScope = $destScope; + } + + public function getSourceServiceId() + { + return $this->sourceServiceId; + } + + public function getSourceScope() + { + return $this->sourceScope; + } + + public function getDestServiceId() + { + return $this->destServiceId; + } + + public function getDestScope() + { + return $this->destScope; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ScopeWideningInjectionException.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ScopeWideningInjectionException.php new file mode 100644 index 0000000..d463453 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ScopeWideningInjectionException.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\DependencyInjection\Exception; + +/** + * Thrown when a scope widening injection is detected. + * + * @author Johannes M. Schmitt + */ +class ScopeWideningInjectionException extends RuntimeException +{ + private $sourceServiceId; + private $sourceScope; + private $destServiceId; + private $destScope; + + public function __construct($sourceServiceId, $sourceScope, $destServiceId, $destScope) + { + parent::__construct(sprintf( + 'Scope Widening Injection detected: The definition "%s" references the service "%s" which belongs to a narrower scope. ' + .'Generally, it is safer to either move "%s" to scope "%s" or alternatively rely on the provider pattern by injecting the container itself, and requesting the service "%s" each time it is needed. ' + .'In rare, special cases however that might not be necessary, then you can set the reference to strict=false to get rid of this error.', + $sourceServiceId, + $destServiceId, + $sourceServiceId, + $destScope, + $destServiceId + )); + + $this->sourceServiceId = $sourceServiceId; + $this->sourceScope = $sourceScope; + $this->destServiceId = $destServiceId; + $this->destScope = $destScope; + } + + public function getSourceServiceId() + { + return $this->sourceServiceId; + } + + public function getSourceScope() + { + return $this->sourceScope; + } + + public function getDestServiceId() + { + return $this->destServiceId; + } + + public function getDestScope() + { + return $this->destScope; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ServiceCircularReferenceException.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ServiceCircularReferenceException.php new file mode 100644 index 0000000..e000001 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ServiceCircularReferenceException.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\DependencyInjection\Exception; + +/** + * This exception is thrown when a circular reference is detected. + * + * @author Johannes M. Schmitt + */ +class ServiceCircularReferenceException extends RuntimeException +{ + private $serviceId; + private $path; + + public function __construct($serviceId, array $path) + { + parent::__construct(sprintf('Circular reference detected for service "%s", path: "%s".', $serviceId, implode(' -> ', $path))); + + $this->serviceId = $serviceId; + $this->path = $path; + } + + public function getServiceId() + { + return $this->serviceId; + } + + public function getPath() + { + return $this->path; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ServiceNotFoundException.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ServiceNotFoundException.php new file mode 100644 index 0000000..f9af1ea --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Exception/ServiceNotFoundException.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\DependencyInjection\Exception; + +/** + * This exception is thrown when a non-existent service is requested. + * + * @author Johannes M. Schmitt + */ +class ServiceNotFoundException extends InvalidArgumentException +{ + private $id; + private $sourceId; + + public function __construct($id, $sourceId = null) + { + if (null === $sourceId) { + $msg = sprintf('You have requested a non-existent service "%s".', $id); + } else { + $msg = sprintf('The service "%s" has a dependency on a non-existent service "%s".', $sourceId, $id); + } + + parent::__construct($msg); + + $this->id = $id; + $this->sourceId = $sourceId; + } + + public function getId() + { + return $this->id; + } + + public function getSourceId() + { + return $this->sourceId; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Extension/ConfigurationExtensionInterface.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Extension/ConfigurationExtensionInterface.php new file mode 100644 index 0000000..4f33a9b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Extension/ConfigurationExtensionInterface.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\DependencyInjection\Extension; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * ConfigurationExtensionInterface is the interface implemented by container extension classes. + * + * @author Kevin Bond + */ +interface ConfigurationExtensionInterface +{ + /** + * Returns extension configuration + * + * @param array $config $config An array of configuration values + * @param ContainerBuilder $container A ContainerBuilder instance + * + * @return ConfigurationInterface|null The configuration or null + */ + function getConfiguration(array $config, ContainerBuilder $container); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Extension/ExtensionInterface.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Extension/ExtensionInterface.php new file mode 100644 index 0000000..09ebcd8 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Extension/ExtensionInterface.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\DependencyInjection\Extension; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * ExtensionInterface is the interface implemented by container extension classes. + * + * @author Fabien Potencier + * + * @api + */ +interface ExtensionInterface +{ + /** + * Loads a specific configuration. + * + * @param array $config An array of configuration values + * @param ContainerBuilder $container A ContainerBuilder instance + * + * @throws InvalidArgumentException When provided tag is not defined in this extension + * + * @api + */ + function load(array $config, ContainerBuilder $container); + + /** + * Returns the namespace to be used for this extension (XML namespace). + * + * @return string The XML namespace + * + * @api + */ + function getNamespace(); + + /** + * Returns the base path for the XSD files. + * + * @return string The XSD base path + * + * @api + */ + function getXsdValidationBasePath(); + + /** + * Returns the recommended alias to use in XML. + * + * This alias is also the mandatory prefix to use when using YAML. + * + * @return string The alias + * + * @api + */ + function getAlias(); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/IntrospectableContainerInterface.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/IntrospectableContainerInterface.php new file mode 100644 index 0000000..0ffc729 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/IntrospectableContainerInterface.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\DependencyInjection; + +/** + * IntrospectableContainerInterface defines additional introspection functionality + * for containers, allowing logic to be implemented based on a Container's state. + * + * @author Evan Villemez + * + */ +interface IntrospectableContainerInterface extends ContainerInterface +{ + /** + * Check for whether or not a service has been initialized. + * + * @param string $id + * + * @return Boolean true if the service has been initialized, false otherwise + * + */ + function initialized($id); + +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/LICENSE b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/LICENSE new file mode 100644 index 0000000..cdffe7a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 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/symfony/src/Symfony/Component/DependencyInjection/Loader/ClosureLoader.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/ClosureLoader.php new file mode 100644 index 0000000..775a352 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/ClosureLoader.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\DependencyInjection\Loader; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Config\Loader\Loader; + +/** + * ClosureLoader loads service definitions from a PHP closure. + * + * The Closure has access to the container as its first argument. + * + * @author Fabien Potencier + */ +class ClosureLoader extends Loader +{ + private $container; + + /** + * Constructor. + * + * @param ContainerBuilder $container A ContainerBuilder instance + */ + public function __construct(ContainerBuilder $container) + { + $this->container = $container; + } + + /** + * Loads a Closure. + * + * @param \Closure $closure The resource + * @param string $type The resource type + */ + public function load($closure, $type = null) + { + call_user_func($closure, $this->container); + } + + /** + * Returns true if this class supports the given resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return Boolean true if this class supports the given resource, false otherwise + */ + public function supports($resource, $type = null) + { + return $resource instanceof \Closure; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php new file mode 100644 index 0000000..0699ab9 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/FileLoader.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\DependencyInjection\Loader; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Config\Loader\FileLoader as BaseFileLoader; +use Symfony\Component\Config\FileLocator; + +/** + * FileLoader is the abstract class used by all built-in loaders that are file based. + * + * @author Fabien Potencier + */ +abstract class FileLoader extends BaseFileLoader +{ + protected $container; + + /** + * Constructor. + * + * @param ContainerBuilder $container A ContainerBuilder instance + * @param FileLocator $locator A FileLocator instance + */ + public function __construct(ContainerBuilder $container, FileLocator $locator) + { + $this->container = $container; + + parent::__construct($locator); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/IniFileLoader.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/IniFileLoader.php new file mode 100644 index 0000000..e4b99f6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/IniFileLoader.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\DependencyInjection\Loader; + +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * IniFileLoader loads parameters from INI files. + * + * @author Fabien Potencier + */ +class IniFileLoader extends FileLoader +{ + /** + * Loads a resource. + * + * @param mixed $file The resource + * @param string $type The resource type + * + * @throws InvalidArgumentException When ini file is not valid + */ + public function load($file, $type = null) + { + $path = $this->locator->locate($file); + + $this->container->addResource(new FileResource($path)); + + $result = parse_ini_file($path, true); + if (false === $result || array() === $result) { + throw new InvalidArgumentException(sprintf('The "%s" file is not valid.', $file)); + } + + if (isset($result['parameters']) && is_array($result['parameters'])) { + foreach ($result['parameters'] as $key => $value) { + $this->container->setParameter($key, $value); + } + } + } + + /** + * Returns true if this class supports the given resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return Boolean true if this class supports the given resource, false otherwise + */ + public function supports($resource, $type = null) + { + return is_string($resource) && 'ini' === pathinfo($resource, PATHINFO_EXTENSION); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/PhpFileLoader.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/PhpFileLoader.php new file mode 100644 index 0000000..f2bf441 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/PhpFileLoader.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\DependencyInjection\Loader; + +use Symfony\Component\Config\Resource\FileResource; + +/** + * PhpFileLoader loads service definitions from a PHP file. + * + * The PHP file is required and the $container variable can be + * used form the file to change the container. + * + * @author Fabien Potencier + */ +class PhpFileLoader extends FileLoader +{ + /** + * Loads a PHP file. + * + * @param mixed $file The resource + * @param string $type The resource type + */ + public function load($file, $type = null) + { + // the container and loader variables are exposed to the included file below + $container = $this->container; + $loader = $this; + + $path = $this->locator->locate($file); + $this->setCurrentDir(dirname($path)); + $this->container->addResource(new FileResource($path)); + + include $path; + } + + /** + * Returns true if this class supports the given resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return Boolean true if this class supports the given resource, false otherwise + */ + public function supports($resource, $type = null) + { + return is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php new file mode 100644 index 0000000..3a27d37 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php @@ -0,0 +1,499 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader; + +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\SimpleXMLElement; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * XmlFileLoader loads XML files service definitions. + * + * @author Fabien Potencier + */ +class XmlFileLoader extends FileLoader +{ + /** + * Loads an XML file. + * + * @param mixed $file The resource + * @param string $type The resource type + */ + public function load($file, $type = null) + { + $path = $this->locator->locate($file); + + $xml = $this->parseFile($path); + $xml->registerXPathNamespace('container', 'http://symfony.com/schema/dic/services'); + + $this->container->addResource(new FileResource($path)); + + // anonymous services + $this->processAnonymousServices($xml, $path); + + // imports + $this->parseImports($xml, $path); + + // parameters + $this->parseParameters($xml, $path); + + // extensions + $this->loadFromExtensions($xml); + + // services + $this->parseDefinitions($xml, $path); + } + + /** + * Returns true if this class supports the given resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return Boolean true if this class supports the given resource, false otherwise + */ + public function supports($resource, $type = null) + { + return is_string($resource) && 'xml' === pathinfo($resource, PATHINFO_EXTENSION); + } + + /** + * Parses parameters + * + * @param SimpleXMLElement $xml + * @param string $file + */ + private function parseParameters(SimpleXMLElement $xml, $file) + { + if (!$xml->parameters) { + return; + } + + $this->container->getParameterBag()->add($xml->parameters->getArgumentsAsPhp('parameter')); + } + + /** + * Parses imports + * + * @param SimpleXMLElement $xml + * @param string $file + */ + private function parseImports(SimpleXMLElement $xml, $file) + { + if (false === $imports = $xml->xpath('//container:imports/container:import')) { + return; + } + + foreach ($imports as $import) { + $this->setCurrentDir(dirname($file)); + $this->import((string) $import['resource'], null, (Boolean) $import->getAttributeAsPhp('ignore-errors'), $file); + } + } + + /** + * Parses multiple definitions + * + * @param SimpleXMLElement $xml + * @param string $file + */ + private function parseDefinitions(SimpleXMLElement $xml, $file) + { + if (false === $services = $xml->xpath('//container:services/container:service')) { + return; + } + + foreach ($services as $service) { + $this->parseDefinition((string) $service['id'], $service, $file); + } + } + + /** + * Parses an individual Definition + * + * @param string $id + * @param SimpleXMLElement $service + * @param string $file + */ + private function parseDefinition($id, $service, $file) + { + if ((string) $service['alias']) { + $public = true; + if (isset($service['public'])) { + $public = $service->getAttributeAsPhp('public'); + } + $this->container->setAlias($id, new Alias((string) $service['alias'], $public)); + + return; + } + + if (isset($service['parent'])) { + $definition = new DefinitionDecorator((string) $service['parent']); + } else { + $definition = new Definition(); + } + + foreach (array('class', 'scope', 'public', 'factory-class', 'factory-method', 'factory-service', 'synthetic', 'abstract') as $key) { + if (isset($service[$key])) { + $method = 'set'.str_replace('-', '', $key); + $definition->$method((string) $service->getAttributeAsPhp($key)); + } + } + + if ($service->file) { + $definition->setFile((string) $service->file); + } + + $definition->setArguments($service->getArgumentsAsPhp('argument')); + $definition->setProperties($service->getArgumentsAsPhp('property')); + + if (isset($service->configurator)) { + if (isset($service->configurator['function'])) { + $definition->setConfigurator((string) $service->configurator['function']); + } else { + if (isset($service->configurator['service'])) { + $class = new Reference((string) $service->configurator['service'], ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, false); + } else { + $class = (string) $service->configurator['class']; + } + + $definition->setConfigurator(array($class, (string) $service->configurator['method'])); + } + } + + foreach ($service->call as $call) { + $definition->addMethodCall((string) $call['method'], $call->getArgumentsAsPhp('argument')); + } + + foreach ($service->tag as $tag) { + $parameters = array(); + foreach ($tag->attributes() as $name => $value) { + if ('name' === $name) { + continue; + } + + $parameters[$name] = SimpleXMLElement::phpize($value); + } + + $definition->addTag((string) $tag['name'], $parameters); + } + + $this->container->setDefinition($id, $definition); + } + + /** + * Parses a XML file. + * + * @param string $file Path to a file + * + * @throws InvalidArgumentException When loading of XML file returns error + */ + private function parseFile($file) + { + $dom = new \DOMDocument(); + libxml_use_internal_errors(true); + if (!$dom->load($file, defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0)) { + throw new InvalidArgumentException(implode("\n", $this->getXmlErrors())); + } + $dom->validateOnParse = true; + $dom->normalizeDocument(); + libxml_use_internal_errors(false); + $this->validate($dom, $file); + + return simplexml_import_dom($dom, 'Symfony\\Component\\DependencyInjection\\SimpleXMLElement'); + } + + /** + * Processes anonymous services + * + * @param SimpleXMLElement $xml + * @param string $file + */ + private function processAnonymousServices(SimpleXMLElement $xml, $file) + { + $definitions = array(); + $count = 0; + + // anonymous services as arguments/properties + if (false !== $nodes = $xml->xpath('//container:argument[@type="service"][not(@id)]|//container:property[@type="service"][not(@id)]')) { + foreach ($nodes as $node) { + // give it a unique name + $node['id'] = sprintf('%s_%d', md5($file), ++$count); + + $definitions[(string) $node['id']] = array($node->service, $file, false); + $node->service['id'] = (string) $node['id']; + } + } + + // anonymous services "in the wild" + if (false !== $nodes = $xml->xpath('//container:services/container:service[not(@id)]')) { + foreach ($nodes as $node) { + // give it a unique name + $node['id'] = sprintf('%s_%d', md5($file), ++$count); + + $definitions[(string) $node['id']] = array($node, $file, true); + $node->service['id'] = (string) $node['id']; + } + } + + // resolve definitions + krsort($definitions); + foreach ($definitions as $id => $def) { + // anonymous services are always private + $def[0]['public'] = false; + + $this->parseDefinition($id, $def[0], $def[1]); + + $oNode = dom_import_simplexml($def[0]); + if (true === $def[2]) { + $nNode = new \DOMElement('_services'); + $oNode->parentNode->replaceChild($nNode, $oNode); + $nNode->setAttribute('id', $id); + } else { + $oNode->parentNode->removeChild($oNode); + } + } + } + + /** + * Validates an XML document. + * + * @param DOMDocument $dom + * @param string $file + */ + private function validate(\DOMDocument $dom, $file) + { + $this->validateSchema($dom, $file); + $this->validateExtensions($dom, $file); + } + + /** + * Validates a documents XML schema. + * + * @param \DOMDocument $dom + * @param string $file + * + * @throws RuntimeException When extension references a non-existent XSD file + * @throws InvalidArgumentException When XML doesn't validate its XSD schema + */ + private function validateSchema(\DOMDocument $dom, $file) + { + $schemaLocations = array('http://symfony.com/schema/dic/services' => str_replace('\\', '/', __DIR__.'/schema/dic/services/services-1.0.xsd')); + + if ($element = $dom->documentElement->getAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'schemaLocation')) { + $items = preg_split('/\s+/', $element); + for ($i = 0, $nb = count($items); $i < $nb; $i += 2) { + if (!$this->container->hasExtension($items[$i])) { + continue; + } + + if (($extension = $this->container->getExtension($items[$i])) && false !== $extension->getXsdValidationBasePath()) { + $path = str_replace($extension->getNamespace(), str_replace('\\', '/', $extension->getXsdValidationBasePath()).'/', $items[$i + 1]); + + if (!is_file($path)) { + throw new RuntimeException(sprintf('Extension "%s" references a non-existent XSD file "%s"', get_class($extension), $path)); + } + + $schemaLocations[$items[$i]] = $path; + } + } + } + + $tmpfiles = array(); + $imports = ''; + foreach ($schemaLocations as $namespace => $location) { + $parts = explode('/', $location); + if (0 === stripos($location, 'phar://')) { + $tmpfile = tempnam(sys_get_temp_dir(), 'sf2'); + if ($tmpfile) { + copy($location, $tmpfile); + $tmpfiles[] = $tmpfile; + $parts = explode('/', str_replace('\\', '/', $tmpfile)); + } + } + $drive = '\\' === DIRECTORY_SEPARATOR ? array_shift($parts).'/' : ''; + $location = 'file:///'.$drive.implode('/', array_map('rawurlencode', $parts)); + + $imports .= sprintf(' '."\n", $namespace, $location); + } + + $source = << + + + +$imports + +EOF + ; + + $current = libxml_use_internal_errors(true); + $valid = $dom->schemaValidateSource($source); + foreach ($tmpfiles as $tmpfile) { + @unlink($tmpfile); + } + if (!$valid) { + throw new InvalidArgumentException(implode("\n", $this->getXmlErrors())); + } + libxml_use_internal_errors($current); + } + + /** + * Validates an extension. + * + * @param \DOMDocument $dom + * @param string $file + * + * @throws InvalidArgumentException When no extension is found corresponding to a tag + */ + private function validateExtensions(\DOMDocument $dom, $file) + { + foreach ($dom->documentElement->childNodes as $node) { + if (!$node instanceof \DOMElement || 'http://symfony.com/schema/dic/services' === $node->namespaceURI) { + continue; + } + + // can it be handled by an extension? + if (!$this->container->hasExtension($node->namespaceURI)) { + $extensionNamespaces = array_filter(array_map(function ($ext) { return $ext->getNamespace(); }, $this->container->getExtensions())); + throw new InvalidArgumentException(sprintf( + 'There is no extension able to load the configuration for "%s" (in %s). Looked for namespace "%s", found %s', + $node->tagName, + $file, + $node->namespaceURI, + $extensionNamespaces ? sprintf('"%s"', implode('", "', $extensionNamespaces)) : 'none' + )); + } + } + } + + /** + * Returns an array of XML errors. + * + * @return array + */ + private function getXmlErrors() + { + $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 ? $error->file : 'n/a', + $error->line, + $error->column + ); + } + + libxml_clear_errors(); + + return $errors; + } + + /** + * Loads from an extension. + * + * @param SimpleXMLElement $xml + */ + private function loadFromExtensions(SimpleXMLElement $xml) + { + foreach (dom_import_simplexml($xml)->childNodes as $node) { + if (!$node instanceof \DOMElement || $node->namespaceURI === 'http://symfony.com/schema/dic/services') { + continue; + } + + $values = static::convertDomElementToArray($node); + if (!is_array($values)) { + $values = array(); + } + + $this->container->loadFromExtension($node->namespaceURI, $values); + } + } + + /** + * 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 + * + * @return array A PHP array + */ + static public function convertDomElementToArray(\DomElement $element) + { + $empty = true; + $config = array(); + foreach ($element->attributes as $name => $node) { + $config[$name] = SimpleXMLElement::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 (!$node instanceof \DOMComment) { + if ($node instanceof \DOMElement && '_services' === $node->nodeName) { + $value = new Reference($node->getAttribute('id')); + } else { + $value = static::convertDomElementToArray($node); + } + + $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 = SimpleXMLElement::phpize($nodeValue); + if (count($config)) { + $config['value'] = $value; + } else { + $config = $value; + } + } + + return !$empty ? $config : null; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php new file mode 100644 index 0000000..63f3893 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.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\DependencyInjection\Loader; + +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Yaml\Yaml; + +/** + * YamlFileLoader loads YAML files service definitions. + * + * The YAML format does not support anonymous services (cf. the XML loader). + * + * @author Fabien Potencier + */ +class YamlFileLoader extends FileLoader +{ + /** + * Loads a Yaml file. + * + * @param mixed $file The resource + * @param string $type The resource type + */ + public function load($file, $type = null) + { + $path = $this->locator->locate($file); + + $content = $this->loadFile($path); + + $this->container->addResource(new FileResource($path)); + + // empty file + if (null === $content) { + return; + } + + // imports + $this->parseImports($content, $file); + + // parameters + if (isset($content['parameters'])) { + foreach ($content['parameters'] as $key => $value) { + $this->container->setParameter($key, $this->resolveServices($value)); + } + } + + // extensions + $this->loadFromExtensions($content); + + // services + $this->parseDefinitions($content, $file); + } + + /** + * Returns true if this class supports the given resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return Boolean true if this class supports the given resource, false otherwise + */ + public function supports($resource, $type = null) + { + return is_string($resource) && 'yml' === pathinfo($resource, PATHINFO_EXTENSION); + } + + /** + * Parses all imports + * + * @param array $content + * @param string $file + */ + private function parseImports($content, $file) + { + if (!isset($content['imports'])) { + return; + } + + foreach ($content['imports'] as $import) { + $this->setCurrentDir(dirname($file)); + $this->import($import['resource'], null, isset($import['ignore_errors']) ? (Boolean) $import['ignore_errors'] : false, $file); + } + } + + /** + * Parses definitions + * + * @param array $content + * @param string $file + */ + private function parseDefinitions($content, $file) + { + if (!isset($content['services'])) { + return; + } + + foreach ($content['services'] as $id => $service) { + $this->parseDefinition($id, $service, $file); + } + } + + /** + * Parses a definition. + * + * @param string $id + * @param array $service + * @param string $file + */ + private function parseDefinition($id, $service, $file) + { + if (is_string($service) && 0 === strpos($service, '@')) { + $this->container->setAlias($id, substr($service, 1)); + + return; + } elseif (isset($service['alias'])) { + $public = !array_key_exists('public', $service) || (Boolean) $service['public']; + $this->container->setAlias($id, new Alias($service['alias'], $public)); + + return; + } + + if (isset($service['parent'])) { + $definition = new DefinitionDecorator($service['parent']); + } else { + $definition = new Definition(); + } + + if (isset($service['class'])) { + $definition->setClass($service['class']); + } + + if (isset($service['scope'])) { + $definition->setScope($service['scope']); + } + + if (isset($service['synthetic'])) { + $definition->setSynthetic($service['synthetic']); + } + + if (isset($service['public'])) { + $definition->setPublic($service['public']); + } + + if (isset($service['abstract'])) { + $definition->setAbstract($service['abstract']); + } + + if (isset($service['factory_class'])) { + $definition->setFactoryClass($service['factory_class']); + } + + if (isset($service['factory_method'])) { + $definition->setFactoryMethod($service['factory_method']); + } + + if (isset($service['factory_service'])) { + $definition->setFactoryService($service['factory_service']); + } + + if (isset($service['file'])) { + $definition->setFile($service['file']); + } + + if (isset($service['arguments'])) { + $definition->setArguments($this->resolveServices($service['arguments'])); + } + + if (isset($service['properties'])) { + $definition->setProperties($this->resolveServices($service['properties'])); + } + + if (isset($service['configurator'])) { + if (is_string($service['configurator'])) { + $definition->setConfigurator($service['configurator']); + } else { + $definition->setConfigurator(array($this->resolveServices($service['configurator'][0]), $service['configurator'][1])); + } + } + + if (isset($service['calls'])) { + foreach ($service['calls'] as $call) { + $args = isset($call[1]) ? $this->resolveServices($call[1]) : array(); + $definition->addMethodCall($call[0], $args); + } + } + + if (isset($service['tags'])) { + if (!is_array($service['tags'])) { + throw new InvalidArgumentException(sprintf('Parameter "tags" must be an array for service "%s" in %s.', $id, $file)); + } + + foreach ($service['tags'] as $tag) { + if (!isset($tag['name'])) { + throw new InvalidArgumentException(sprintf('A "tags" entry is missing a "name" key for service "%s" in %s.', $id, $file)); + } + + $name = $tag['name']; + unset($tag['name']); + + foreach ($tag as $attribute => $value) { + if (!is_scalar($value)) { + throw new InvalidArgumentException(sprintf('A "tags" attribute must be of a scalar-type for service "%s", tag "%s" in %s.', $id, $name, $file)); + } + } + + $definition->addTag($name, $tag); + } + } + + $this->container->setDefinition($id, $definition); + } + + /** + * Loads a YAML file. + * + * @param string $file + * + * @return array The file content + */ + private function loadFile($file) + { + return $this->validate(Yaml::parse($file), $file); + } + + /** + * Validates a YAML file. + * + * @param mixed $content + * @param string $file + * + * @return array + * + * @throws InvalidArgumentException When service file is not valid + */ + private function validate($content, $file) + { + if (null === $content) { + return $content; + } + + if (!is_array($content)) { + throw new InvalidArgumentException(sprintf('The service file "%s" is not valid.', $file)); + } + + foreach (array_keys($content) as $namespace) { + if (in_array($namespace, array('imports', 'parameters', 'services'))) { + continue; + } + + if (!$this->container->hasExtension($namespace)) { + $extensionNamespaces = array_filter(array_map(function ($ext) { return $ext->getAlias(); }, $this->container->getExtensions())); + throw new InvalidArgumentException(sprintf( + 'There is no extension able to load the configuration for "%s" (in %s). Looked for namespace "%s", found %s', + $namespace, + $file, + $namespace, + $extensionNamespaces ? sprintf('"%s"', implode('", "', $extensionNamespaces)) : 'none' + )); + } + } + + return $content; + } + + /** + * Resolves services. + * + * @param string $value + * + * @return Reference + */ + private function resolveServices($value) + { + if (is_array($value)) { + $value = array_map(array($this, 'resolveServices'), $value); + } elseif (is_string($value) && 0 === strpos($value, '@')) { + if (0 === strpos($value, '@?')) { + $value = substr($value, 2); + $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; + } else { + $value = substr($value, 1); + $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + } + + if ('=' === substr($value, -1)) { + $value = substr($value, 0, -1); + $strict = false; + } else { + $strict = true; + } + + $value = new Reference($value, $invalidBehavior, $strict); + } + + return $value; + } + + /** + * Loads from Extensions + * + * @param array $content + */ + private function loadFromExtensions($content) + { + foreach ($content as $namespace => $values) { + if (in_array($namespace, array('imports', 'parameters', 'services'))) { + continue; + } + + if (!is_array($values)) { + $values = array(); + } + + $this->container->loadFromExtension($namespace, $values); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd new file mode 100644 index 0000000..316f2d7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Parameter.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Parameter.php new file mode 100644 index 0000000..7ba8c3a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Parameter.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\DependencyInjection; + +/** + * Parameter represents a parameter reference. + * + * @author Fabien Potencier + * + * @api + */ +class Parameter +{ + private $id; + + /** + * Constructor. + * + * @param string $id The parameter key + */ + public function __construct($id) + { + $this->id = $id; + } + + /** + * __toString. + * + * @return string The parameter key + */ + public function __toString() + { + return (string) $this->id; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ParameterBag/FrozenParameterBag.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ParameterBag/FrozenParameterBag.php new file mode 100644 index 0000000..9664b13 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ParameterBag/FrozenParameterBag.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\DependencyInjection\ParameterBag; + +use Symfony\Component\DependencyInjection\Exception\LogicException; + +/** + * Holds read-only parameters. + * + * @author Fabien Potencier + * + * @api + */ +class FrozenParameterBag extends ParameterBag +{ + /** + * Constructor. + * + * For performance reasons, the constructor assumes that + * all keys are already lowercased. + * + * This is always the case when used internally. + * + * @param array $parameters An array of parameters + * + * @api + */ + public function __construct(array $parameters = array()) + { + $this->parameters = $parameters; + $this->resolved = true; + } + + /** + * {@inheritDoc} + * + * @api + */ + public function clear() + { + throw new LogicException('Impossible to call clear() on a frozen ParameterBag.'); + } + + /** + * {@inheritDoc} + * + * @api + */ + public function add(array $parameters) + { + throw new LogicException('Impossible to call add() on a frozen ParameterBag.'); + } + + /** + * {@inheritDoc} + * + * @api + */ + public function set($name, $value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php new file mode 100644 index 0000000..a83f1fc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php @@ -0,0 +1,273 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\ParameterBag; + +use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; +use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * Holds parameters. + * + * @author Fabien Potencier + * + * @api + */ +class ParameterBag implements ParameterBagInterface +{ + protected $parameters; + protected $resolved; + + /** + * Constructor. + * + * @param array $parameters An array of parameters + * + * @api + */ + public function __construct(array $parameters = array()) + { + $this->parameters = array(); + $this->add($parameters); + $this->resolved = false; + } + + /** + * Clears all parameters. + * + * @api + */ + public function clear() + { + $this->parameters = array(); + } + + /** + * Adds parameters to the service container parameters. + * + * @param array $parameters An array of parameters + * + * @api + */ + public function add(array $parameters) + { + foreach ($parameters as $key => $value) { + $this->parameters[strtolower($key)] = $value; + } + } + + /** + * Gets the service container parameters. + * + * @return array An array of parameters + * + * @api + */ + public function all() + { + return $this->parameters; + } + + /** + * Gets a service container parameter. + * + * @param string $name The parameter name + * + * @return mixed The parameter value + * + * @throws ParameterNotFoundException if the parameter is not defined + * + * @api + */ + public function get($name) + { + $name = strtolower($name); + + if (!array_key_exists($name, $this->parameters)) { + throw new ParameterNotFoundException($name); + } + + return $this->parameters[$name]; + } + + /** + * Sets a service container parameter. + * + * @param string $name The parameter name + * @param mixed $value The parameter value + * + * @api + */ + public function set($name, $value) + { + $this->parameters[strtolower($name)] = $value; + } + + /** + * Returns true if a parameter name is defined. + * + * @param string $name The parameter name + * + * @return Boolean true if the parameter name is defined, false otherwise + * + * @api + */ + public function has($name) + { + return array_key_exists(strtolower($name), $this->parameters); + } + + /** + * Removes a parameter. + * + * @param string $key The key + * + * @api + */ + public function remove($key) + { + unset($this->parameters[$key]); + } + + /** + * Replaces parameter placeholders (%name%) by their values for all parameters. + */ + public function resolve() + { + if ($this->resolved) { + return; + } + + $parameters = array(); + foreach ($this->parameters as $key => $value) { + try { + $value = $this->resolveValue($value); + $parameters[$key] = $this->unescapeValue($value); + } catch (ParameterNotFoundException $e) { + $e->setSourceKey($key); + + throw $e; + } + } + + $this->parameters = $parameters; + $this->resolved = true; + } + + /** + * Replaces parameter placeholders (%name%) by their values. + * + * @param mixed $value A value + * @param array $resolving An array of keys that are being resolved (used internally to detect circular references) + * + * @return mixed The resolved value + * + * @throws ParameterNotFoundException if a placeholder references a parameter that does not exist + * @throws ParameterCircularReferenceException if a circular reference if detected + * @throws RuntimeException when a given parameter has a type problem. + */ + public function resolveValue($value, array $resolving = array()) + { + if (is_array($value)) { + $args = array(); + foreach ($value as $k => $v) { + $args[$this->resolveValue($k, $resolving)] = $this->resolveValue($v, $resolving); + } + + return $args; + } + + if (!is_string($value)) { + return $value; + } + + return $this->resolveString($value, $resolving); + } + + /** + * Resolves parameters inside a string + * + * @param string $value The string to resolve + * @param array $resolving An array of keys that are being resolved (used internally to detect circular references) + * + * @return string The resolved string + * + * @throws ParameterNotFoundException if a placeholder references a parameter that does not exist + * @throws ParameterCircularReferenceException if a circular reference if detected + * @throws RuntimeException when a given parameter has a type problem. + */ + public function resolveString($value, array $resolving = array()) + { + // we do this to deal with non string values (Boolean, integer, ...) + // as the preg_replace_callback throw an exception when trying + // a non-string in a parameter value + if (preg_match('/^%([^%\s]+)%$/', $value, $match)) { + $key = strtolower($match[1]); + + if (isset($resolving[$key])) { + throw new ParameterCircularReferenceException(array_keys($resolving)); + } + + $resolving[$key] = true; + + return $this->resolved ? $this->get($key) : $this->resolveValue($this->get($key), $resolving); + } + + $self = $this; + + return preg_replace_callback('/%%|%([^%\s]+)%/', function ($match) use ($self, $resolving, $value) { + // skip %% + if (!isset($match[1])) { + return '%%'; + } + + $key = strtolower($match[1]); + if (isset($resolving[$key])) { + throw new ParameterCircularReferenceException(array_keys($resolving)); + } + + $resolved = $self->get($key); + + if (!is_string($resolved) && !is_numeric($resolved)) { + throw new RuntimeException(sprintf('A string value must be composed of strings and/or numbers, but found parameter "%s" of type %s inside string value "%s".', $key, gettype($resolved), $value)); + } + + $resolved = (string) $resolved; + $resolving[$key] = true; + + return $self->isResolved() ? $resolved : $self->resolveString($resolved, $resolving); + }, $value); + } + + public function isResolved() + { + return $this->resolved; + } + + private function unescapeValue($value) + { + if (is_string($value)) { + return str_replace('%%', '%', $value); + } + + if (is_array($value)) { + $result = array(); + foreach ($value as $k => $v) { + $result[$k] = $this->unescapeValue($v); + } + + return $result; + } + + return $value; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBagInterface.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBagInterface.php new file mode 100644 index 0000000..da83cbe --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBagInterface.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\DependencyInjection\ParameterBag; + +use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; + +/** + * ParameterBagInterface. + * + * @author Fabien Potencier + * + * @api + */ +interface ParameterBagInterface +{ + /** + * Clears all parameters. + * + * @api + */ + function clear(); + + /** + * Adds parameters to the service container parameters. + * + * @param array $parameters An array of parameters + * + * @api + */ + function add(array $parameters); + + /** + * Gets the service container parameters. + * + * @return array An array of parameters + * + * @api + */ + function all(); + + /** + * Gets a service container parameter. + * + * @param string $name The parameter name + * + * @return mixed The parameter value + * + * @throws ParameterNotFoundException if the parameter is not defined + * + * @api + */ + function get($name); + + /** + * Sets a service container parameter. + * + * @param string $name The parameter name + * @param mixed $value The parameter value + * + * @api + */ + function set($name, $value); + + /** + * Returns true if a parameter name is defined. + * + * @param string $name The parameter name + * + * @return Boolean true if the parameter name is defined, false otherwise + * + * @api + */ + function has($name); + + /** + * Replaces parameter placeholders (%name%) by their values for all parameters. + */ + function resolve(); + + /** + * Replaces parameter placeholders (%name%) by their values. + * + * @param mixed $value A value + * + * @throws ParameterNotFoundException if a placeholder references a parameter that does not exist + */ + function resolveValue($value); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/README.md b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/README.md new file mode 100644 index 0000000..5cb62cf --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/README.md @@ -0,0 +1,76 @@ +DependencyInjection Component +============================= + +DependencyInjection manages your services via a robust and flexible Dependency +Injection Container. + +Here is a simple example that shows how to register services and parameters: + + use Symfony\Component\DependencyInjection\ContainerBuilder; + use Symfony\Component\DependencyInjection\Reference; + + $sc = new ContainerBuilder(); + $sc + ->register('foo', '%foo.class%') + ->addArgument(new Reference('bar')) + ; + $sc->setParameter('foo.class', 'Foo'); + + $sc->get('foo'); + +Method Calls (Setter Injection): + + $sc = new ContainerBuilder(); + + $sc + ->register('bar', '%bar.class%') + ->addMethodCall('setFoo', array(new Reference('foo'))) + ; + $sc->setParameter('bar.class', 'Bar'); + + $sc->get('bar'); + +Factory Class: + +If your service is retrieved by calling a static method: + + $sc = new ContainerBuilder(); + + $sc + ->register('bar', '%bar.class%') + ->setFactoryClass('%bar.class%') + ->setFactoryMethod('getInstance') + ->addArgument('Aarrg!!!') + ; + $sc->setParameter('bar.class', 'Bar'); + + $sc->get('bar'); + +File Include: + +For some services, especially those that are difficult or impossible to +autoload, you may need the container to include a file before +instantiating your class. + + $sc = new ContainerBuilder(); + + $sc + ->register('bar', '%bar.class%') + ->setFile('/path/to/file') + ->addArgument('Aarrg!!!') + ; + $sc->setParameter('bar.class', 'Bar'); + + $sc->get('bar'); + +Resources +--------- + +You can run the unit tests with the following command: + + phpunit + +If you also want to run the unit tests that depend on other Symfony +Components, install dev dependencies before running PHPUnit: + + php composer.phar install --dev diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Reference.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Reference.php new file mode 100644 index 0000000..1517da2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Reference.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\DependencyInjection; + +/** + * Reference represents a service reference. + * + * @author Fabien Potencier + * + * @api + */ +class Reference +{ + private $id; + private $invalidBehavior; + private $strict; + + /** + * Constructor. + * + * @param string $id The service identifier + * @param int $invalidBehavior The behavior when the service does not exist + * @param Boolean $strict Sets how this reference is validated + * + * @see Container + */ + public function __construct($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, $strict = true) + { + $this->id = strtolower($id); + $this->invalidBehavior = $invalidBehavior; + $this->strict = $strict; + } + + /** + * __toString. + * + * @return string The service identifier + */ + public function __toString() + { + return (string) $this->id; + } + + /** + * Returns the behavior to be used when the service does not exist. + * + * @return int + */ + public function getInvalidBehavior() + { + return $this->invalidBehavior; + } + + /** + * Returns true when this Reference is strict + * + * @return Boolean + */ + public function isStrict() + { + return $this->strict; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Scope.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Scope.php new file mode 100644 index 0000000..161229e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Scope.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\DependencyInjection; + +/** + * Scope class. + * + * @author Johannes M. Schmitt + * + * @api + */ +class Scope implements ScopeInterface +{ + private $name; + private $parentName; + + /** + * @api + */ + public function __construct($name, $parentName = ContainerInterface::SCOPE_CONTAINER) + { + $this->name = $name; + $this->parentName = $parentName; + } + + /** + * @api + */ + public function getName() + { + return $this->name; + } + + /** + * @api + */ + public function getParentName() + { + return $this->parentName; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ScopeInterface.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ScopeInterface.php new file mode 100644 index 0000000..44b8c5d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/ScopeInterface.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\DependencyInjection; + +/** + * Scope Interface. + * + * @author Johannes M. Schmitt + * + * @api + */ +interface ScopeInterface +{ + /** + * @api + */ + function getName(); + + /** + * @api + */ + function getParentName(); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/SimpleXMLElement.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/SimpleXMLElement.php new file mode 100644 index 0000000..457d54f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/SimpleXMLElement.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\DependencyInjection; + +/** + * SimpleXMLElement class. + * + * @author Fabien Potencier + */ +class SimpleXMLElement extends \SimpleXMLElement +{ + /** + * Converts an attribute as a php type. + * + * @param string $name + * + * @return mixed + */ + public function getAttributeAsPhp($name) + { + return self::phpize($this[$name]); + } + + /** + * Returns arguments as valid php types. + * + * @param string $name + * @param Boolean $lowercase + * + * @return mixed + */ + public function getArgumentsAsPhp($name, $lowercase = true) + { + $arguments = array(); + foreach ($this->$name as $arg) { + if (isset($arg['name'])) { + $arg['key'] = (string) $arg['name']; + } + $key = isset($arg['key']) ? (string) $arg['key'] : (!$arguments ? 0 : max(array_keys($arguments)) + 1); + + // parameter keys are case insensitive + if ('parameter' == $name && $lowercase) { + $key = strtolower($key); + } + + // this is used by DefinitionDecorator to overwrite a specific + // argument of the parent definition + if (isset($arg['index'])) { + $key = 'index_'.$arg['index']; + } + + switch ($arg['type']) { + case 'service': + $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + if (isset($arg['on-invalid']) && 'ignore' == $arg['on-invalid']) { + $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; + } elseif (isset($arg['on-invalid']) && 'null' == $arg['on-invalid']) { + $invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE; + } + + if (isset($arg['strict'])) { + $strict = self::phpize($arg['strict']); + } else { + $strict = true; + } + + $arguments[$key] = new Reference((string) $arg['id'], $invalidBehavior, $strict); + break; + case 'collection': + $arguments[$key] = $arg->getArgumentsAsPhp($name, false); + break; + case 'string': + $arguments[$key] = (string) $arg; + break; + case 'constant': + $arguments[$key] = constant((string) $arg); + break; + default: + $arguments[$key] = self::phpize($arg); + } + } + + return $arguments; + } + + /** + * Converts an xml value to a php type. + * + * @param mixed $value + * + * @return mixed + */ + static public function phpize($value) + { + $value = (string) $value; + $lowercaseValue = strtolower($value); + + switch (true) { + case 'null' === $lowercaseValue: + return null; + case ctype_digit($value): + $raw = $value; + $cast = intval($value); + + return '0' == $value[0] ? octdec($value) : (((string) $raw == (string) $cast) ? $cast : $raw); + case 'true' === $lowercaseValue: + return true; + case 'false' === $lowercaseValue: + return false; + case is_numeric($value): + return '0x' == $value[0].$value[1] ? hexdec($value) : floatval($value); + case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $value): + return floatval(str_replace(',', '', $value)); + default: + return $value; + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/TaggedContainerInterface.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/TaggedContainerInterface.php new file mode 100644 index 0000000..81adb20 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/TaggedContainerInterface.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\DependencyInjection; + +/** + * TaggedContainerInterface is the interface implemented when a container knows how to deals with tags. + * + * @author Fabien Potencier + * + * @api + */ +interface TaggedContainerInterface extends ContainerInterface +{ + /** + * Returns service ids for a given tag. + * + * @param string $name The tag name + * + * @return array An array of tags + * + * @api + */ + function findTaggedServiceIds($name); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/AnalyzeServiceReferencesPassTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/AnalyzeServiceReferencesPassTest.php new file mode 100644 index 0000000..c99659e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/AnalyzeServiceReferencesPassTest.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\DependencyInjection\Tests\Compiler; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Compiler\Compiler; +use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass; +use Symfony\Component\DependencyInjection\Compiler\RepeatedPass; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +class AnalyzeServiceReferencesPassTest extends \PHPUnit_Framework_TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + + $a = $container + ->register('a') + ->addArgument($ref1 = new Reference('b')) + ; + + $b = $container + ->register('b') + ->addMethodCall('setA', array($ref2 = new Reference('a'))) + ; + + $c = $container + ->register('c') + ->addArgument($ref3 = new Reference('a')) + ->addArgument($ref4 = new Reference('b')) + ; + + $d = $container + ->register('d') + ->setProperty('foo', $ref5 = new Reference('b')) + ; + + $e = $container + ->register('e') + ->setConfigurator(array($ref6 = new Reference('b'), 'methodName')) + ; + + $graph = $this->process($container); + + $this->assertCount(4, $edges = $graph->getNode('b')->getInEdges()); + + $this->assertSame($ref1, $edges[0]->getValue()); + $this->assertSame($ref4, $edges[1]->getValue()); + $this->assertSame($ref5, $edges[2]->getValue()); + $this->assertSame($ref6, $edges[3]->getValue()); + } + + public function testProcessDetectsReferencesFromInlinedDefinitions() + { + $container = new ContainerBuilder(); + + $container + ->register('a') + ; + + $container + ->register('b') + ->addArgument(new Definition(null, array($ref = new Reference('a')))) + ; + + $graph = $this->process($container); + + $this->assertCount(1, $refs = $graph->getNode('a')->getInEdges()); + $this->assertSame($ref, $refs[0]->getValue()); + } + + public function testProcessDoesNotSaveDuplicateReferences() + { + $container = new ContainerBuilder(); + + $container + ->register('a') + ; + $container + ->register('b') + ->addArgument(new Definition(null, array($ref1 = new Reference('a')))) + ->addArgument(new Definition(null, array($ref2 = new Reference('a')))) + ; + + $graph = $this->process($container); + + $this->assertCount(2, $graph->getNode('a')->getInEdges()); + } + + protected function process(ContainerBuilder $container) + { + $pass = new RepeatedPass(array(new AnalyzeServiceReferencesPass())); + $pass->process($container); + + return $container->getCompiler()->getServiceReferenceGraph(); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckCircularReferencesPassTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckCircularReferencesPassTest.php new file mode 100644 index 0000000..25f816b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckCircularReferencesPassTest.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use Symfony\Component\DependencyInjection\Reference; + +use Symfony\Component\DependencyInjection\Compiler\CheckCircularReferencesPass; + +use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass; + +use Symfony\Component\DependencyInjection\Compiler\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +class CheckCircularReferencesPassTest extends \PHPUnit_Framework_TestCase +{ + /** + * @expectedException \RuntimeException + */ + public function testProcess() + { + $container = new ContainerBuilder(); + $container->register('a')->addArgument(new Reference('b')); + $container->register('b')->addArgument(new Reference('a')); + + $this->process($container); + } + + /** + * @expectedException \RuntimeException + */ + public function testProcessWithAliases() + { + $container = new ContainerBuilder(); + $container->register('a')->addArgument(new Reference('b')); + $container->setAlias('b', 'c'); + $container->setAlias('c', 'a'); + + $this->process($container); + } + + /** + * @expectedException \RuntimeException + */ + public function testProcessDetectsIndirectCircularReference() + { + $container = new ContainerBuilder(); + $container->register('a')->addArgument(new Reference('b')); + $container->register('b')->addArgument(new Reference('c')); + $container->register('c')->addArgument(new Reference('a')); + + $this->process($container); + } + + public function testProcessIgnoresMethodCalls() + { + $container = new ContainerBuilder(); + $container->register('a')->addArgument(new Reference('b')); + $container->register('b')->addMethodCall('setA', array(new Reference('a'))); + + $this->process($container); + } + + protected function process(ContainerBuilder $container) + { + $compiler = new Compiler(); + $passConfig = $compiler->getPassConfig(); + $passConfig->setOptimizationPasses(array( + new AnalyzeServiceReferencesPass(true), + new CheckCircularReferencesPass(), + )); + $passConfig->setRemovingPasses(array()); + + $compiler->compile($container); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckDefinitionValidityPassTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckDefinitionValidityPassTest.php new file mode 100644 index 0000000..06845a2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckDefinitionValidityPassTest.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\DependencyInjection\Tests\Compiler; + +use Symfony\Component\DependencyInjection\Compiler\CheckDefinitionValidityPass; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +class CheckDefinitionValidityPassTest extends \PHPUnit_Framework_TestCase +{ + /** + * @expectedException \RuntimeException + */ + public function testProcessDetectsSyntheticNonPublicDefinitions() + { + $container = new ContainerBuilder(); + $container->register('a')->setSynthetic(true)->setPublic(false); + + $this->process($container); + } + + /** + * @expectedException \RuntimeException + */ + public function testProcessDetectsSyntheticPrototypeDefinitions() + { + $container = new ContainerBuilder(); + $container->register('a')->setSynthetic(true)->setScope(ContainerInterface::SCOPE_PROTOTYPE); + + $this->process($container); + } + + /** + * @expectedException \RuntimeException + */ + public function testProcessDetectsNonSyntheticNonAbstractDefinitionWithoutClass() + { + $container = new ContainerBuilder(); + $container->register('a')->setSynthetic(false)->setAbstract(false); + + $this->process($container); + } + + public function testProcess() + { + $container = new ContainerBuilder(); + $container->register('a', 'class'); + $container->register('b', 'class')->setSynthetic(true)->setPublic(true); + $container->register('c', 'class')->setAbstract(true); + $container->register('d', 'class')->setSynthetic(true); + + $this->process($container); + } + + protected function process(ContainerBuilder $container) + { + $pass = new CheckDefinitionValidityPass(); + $pass->process($container); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckExceptionOnInvalidReferenceBehaviorPassTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckExceptionOnInvalidReferenceBehaviorPassTest.php new file mode 100644 index 0000000..cbf9934 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckExceptionOnInvalidReferenceBehaviorPassTest.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\DependencyInjection\Tests\Compiler; + +use Symfony\Component\DependencyInjection\Definition; + +use Symfony\Component\DependencyInjection\Compiler\CheckExceptionOnInvalidReferenceBehaviorPass; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +class CheckExceptionOnInvalidReferenceBehaviorPassTest extends \PHPUnit_Framework_TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + + $container + ->register('a', '\stdClass') + ->addArgument(new Reference('b')) + ; + $container->register('b', '\stdClass'); + } + + /** + * @expectedException Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException + */ + public function testProcessThrowsExceptionOnInvalidReference() + { + $container = new ContainerBuilder(); + + $container + ->register('a', '\stdClass') + ->addArgument(new Reference('b')) + ; + + $this->process($container); + } + + /** + * @expectedException Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException + */ + public function testProcessThrowsExceptionOnInvalidReferenceFromInlinedDefinition() + { + $container = new ContainerBuilder(); + + $def = new Definition(); + $def->addArgument(new Reference('b')); + + $container + ->register('a', '\stdClass') + ->addArgument($def) + ; + + $this->process($container); + } + + private function process(ContainerBuilder $container) + { + $pass = new CheckExceptionOnInvalidReferenceBehaviorPass(); + $pass->process($container); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckReferenceValidityPassTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckReferenceValidityPassTest.php new file mode 100644 index 0000000..ee18e5c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckReferenceValidityPassTest.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\DependencyInjection\Tests\Compiler; + +use Symfony\Component\DependencyInjection\Scope; + +use Symfony\Component\DependencyInjection\Compiler\CheckReferenceValidityPass; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +class CheckReferenceValidityPassTest extends \PHPUnit_Framework_TestCase +{ + public function testProcessIgnoresScopeWideningIfNonStrictReference() + { + $container = new ContainerBuilder(); + $container->register('a')->addArgument(new Reference('b', ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, false)); + $container->register('b')->setScope('prototype'); + + $this->process($container); + } + + /** + * @expectedException \RuntimeException + */ + public function testProcessDetectsScopeWidening() + { + $container = new ContainerBuilder(); + $container->register('a')->addArgument(new Reference('b')); + $container->register('b')->setScope('prototype'); + + $this->process($container); + } + + public function testProcessIgnoresCrossScopeHierarchyReferenceIfNotStrict() + { + $container = new ContainerBuilder(); + $container->addScope(new Scope('a')); + $container->addScope(new Scope('b')); + + $container->register('a')->setScope('a')->addArgument(new Reference('b', ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, false)); + $container->register('b')->setScope('b'); + + $this->process($container); + } + + /** + * @expectedException \RuntimeException + */ + public function testProcessDetectsCrossScopeHierarchyReference() + { + $container = new ContainerBuilder(); + $container->addScope(new Scope('a')); + $container->addScope(new Scope('b')); + + $container->register('a')->setScope('a')->addArgument(new Reference('b')); + $container->register('b')->setScope('b'); + + $this->process($container); + } + + /** + * @expectedException \RuntimeException + */ + public function testProcessDetectsReferenceToAbstractDefinition() + { + $container = new ContainerBuilder(); + + $container->register('a')->setAbstract(true); + $container->register('b')->addArgument(new Reference('a')); + + $this->process($container); + } + + public function testProcess() + { + $container = new ContainerBuilder(); + $container->register('a')->addArgument(new Reference('b')); + $container->register('b'); + + $this->process($container); + } + + protected function process(ContainerBuilder $container) + { + $pass = new CheckReferenceValidityPass(); + $pass->process($container); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php new file mode 100644 index 0000000..f22f0da --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.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\DependencyInjection\Tests\Compiler; + +use Symfony\Component\DependencyInjection\Scope; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass; +use Symfony\Component\DependencyInjection\Compiler\Compiler; +use Symfony\Component\DependencyInjection\Compiler\RepeatedPass; +use Symfony\Component\DependencyInjection\Compiler\InlineServiceDefinitionsPass; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +class InlineServiceDefinitionsPassTest extends \PHPUnit_Framework_TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + $container + ->register('inlinable.service') + ->setPublic(false) + ; + + $container + ->register('service') + ->setArguments(array(new Reference('inlinable.service'))) + ; + + $this->process($container); + + $arguments = $container->getDefinition('service')->getArguments(); + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $arguments[0]); + $this->assertSame($container->getDefinition('inlinable.service'), $arguments[0]); + } + + public function testProcessDoesNotInlineWhenAliasedServiceIsNotOfPrototypeScope() + { + $container = new ContainerBuilder(); + $container + ->register('foo') + ->setPublic(false) + ; + $container->setAlias('moo', 'foo'); + + $container + ->register('service') + ->setArguments(array($ref = new Reference('foo'))) + ; + + $this->process($container); + + $arguments = $container->getDefinition('service')->getArguments(); + $this->assertSame($ref, $arguments[0]); + } + + public function testProcessDoesInlineServiceOfPrototypeScope() + { + $container = new ContainerBuilder(); + $container + ->register('foo') + ->setScope('prototype') + ; + $container + ->register('bar') + ->setPublic(false) + ->setScope('prototype') + ; + $container->setAlias('moo', 'bar'); + + $container + ->register('service') + ->setArguments(array(new Reference('foo'), $ref = new Reference('moo'), new Reference('bar'))) + ; + + $this->process($container); + + $arguments = $container->getDefinition('service')->getArguments(); + $this->assertEquals($container->getDefinition('foo'), $arguments[0]); + $this->assertNotSame($container->getDefinition('foo'), $arguments[0]); + $this->assertSame($ref, $arguments[1]); + $this->assertEquals($container->getDefinition('bar'), $arguments[2]); + $this->assertNotSame($container->getDefinition('bar'), $arguments[2]); + } + + public function testProcessInlinesIfMultipleReferencesButAllFromTheSameDefinition() + { + $container = new ContainerBuilder(); + + $a = $container->register('a')->setPublic(false); + $b = $container + ->register('b') + ->addArgument(new Reference('a')) + ->addArgument(new Definition(null, array(new Reference('a')))) + ; + + $this->process($container); + + $arguments = $b->getArguments(); + $this->assertSame($a, $arguments[0]); + + $inlinedArguments = $arguments[1]->getArguments(); + $this->assertSame($a, $inlinedArguments[0]); + } + + public function testProcessInlinesOnlyIfSameScope() + { + $container = new ContainerBuilder(); + + $container->addScope(new Scope('foo')); + $a = $container->register('a')->setPublic(false)->setScope('foo'); + $b = $container->register('b')->addArgument(new Reference('a')); + + $this->process($container); + $arguments = $b->getArguments(); + $this->assertEquals(new Reference('a'), $arguments[0]); + $this->assertTrue($container->hasDefinition('a')); + } + + protected function process(ContainerBuilder $container) + { + $repeatedPass = new RepeatedPass(array(new AnalyzeServiceReferencesPass(), new InlineServiceDefinitionsPass())); + $repeatedPass->process($container); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php new file mode 100644 index 0000000..c16e9e0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.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\DependencyInjection\Tests\Compiler; + +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * This class tests the integration of the different compiler passes + */ +class IntegrationTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\Config\Resource\FileResource')) { + $this->markTestSkipped('The "Config" component is not available'); + } + } + + /** + * This tests that the following dependencies are correctly processed: + * + * A is public, B/C are private + * A -> C + * B -> C + */ + public function testProcessRemovesAndInlinesRecursively() + { + $container = new ContainerBuilder(); + + $a = $container + ->register('a', '\stdClass') + ->addArgument(new Reference('c')) + ; + + $b = $container + ->register('b', '\stdClass') + ->addArgument(new Reference('c')) + ->setPublic(false) + ; + + $c = $container + ->register('c', '\stdClass') + ->setPublic(false) + ; + + $container->compile(); + + $this->assertTrue($container->hasDefinition('a')); + $arguments = $a->getArguments(); + $this->assertSame($c, $arguments[0]); + $this->assertFalse($container->hasDefinition('b')); + $this->assertFalse($container->hasDefinition('c')); + } + + public function testProcessInlinesReferencesToAliases() + { + $container = new ContainerBuilder(); + + $a = $container + ->register('a', '\stdClass') + ->addArgument(new Reference('b')) + ; + + $container->setAlias('b', new Alias('c', false)); + + $c = $container + ->register('c', '\stdClass') + ->setPublic(false) + ; + + $container->compile(); + + $this->assertTrue($container->hasDefinition('a')); + $arguments = $a->getArguments(); + $this->assertSame($c, $arguments[0]); + $this->assertFalse($container->hasAlias('b')); + $this->assertFalse($container->hasDefinition('c')); + } + + public function testProcessInlinesWhenThereAreMultipleReferencesButFromTheSameDefinition() + { + $container = new ContainerBuilder(); + + $container + ->register('a', '\stdClass') + ->addArgument(new Reference('b')) + ->addMethodCall('setC', array(new Reference('c'))) + ; + + $container + ->register('b', '\stdClass') + ->addArgument(new Reference('c')) + ->setPublic(false) + ; + + $container + ->register('c', '\stdClass') + ->setPublic(false) + ; + + $container->compile(); + + $this->assertTrue($container->hasDefinition('a')); + $this->assertFalse($container->hasDefinition('b')); + $this->assertFalse($container->hasDefinition('c'), 'Service C was not inlined.'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/RemoveUnusedDefinitionsPassTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/RemoveUnusedDefinitionsPassTest.php new file mode 100644 index 0000000..d7e5521 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/RemoveUnusedDefinitionsPassTest.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\DependencyInjection\Tests\Compiler; + +use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass; +use Symfony\Component\DependencyInjection\Compiler\Compiler; +use Symfony\Component\DependencyInjection\Compiler\RepeatedPass; +use Symfony\Component\DependencyInjection\Compiler\RemoveUnusedDefinitionsPass; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +class RemoveUnusedDefinitionsPassTest extends \PHPUnit_Framework_TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + $container + ->register('foo') + ->setPublic(false) + ; + $container + ->register('bar') + ->setPublic(false) + ; + $container + ->register('moo') + ->setArguments(array(new Reference('bar'))) + ; + + $this->process($container); + + $this->assertFalse($container->hasDefinition('foo')); + $this->assertTrue($container->hasDefinition('bar')); + $this->assertTrue($container->hasDefinition('moo')); + } + + public function testProcessRemovesUnusedDefinitionsRecursively() + { + $container = new ContainerBuilder(); + $container + ->register('foo') + ->setPublic(false) + ; + $container + ->register('bar') + ->setArguments(array(new Reference('foo'))) + ->setPublic(false) + ; + + $this->process($container); + + $this->assertFalse($container->hasDefinition('foo')); + $this->assertFalse($container->hasDefinition('bar')); + } + + public function testProcessWorksWithInlinedDefinitions() + { + $container = new ContainerBuilder(); + $container + ->register('foo') + ->setPublic(false) + ; + $container + ->register('bar') + ->setArguments(array(new Definition(null, array(new Reference('foo'))))) + ; + + $this->process($container); + + $this->assertTrue($container->hasDefinition('foo')); + $this->assertTrue($container->hasDefinition('bar')); + } + + protected function process(ContainerBuilder $container) + { + $repeatedPass = new RepeatedPass(array(new AnalyzeServiceReferencesPass(), new RemoveUnusedDefinitionsPass())); + $repeatedPass->process($container); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/ReplaceAliasByActualDefinitionPassTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/ReplaceAliasByActualDefinitionPassTest.php new file mode 100644 index 0000000..a445a20 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/ReplaceAliasByActualDefinitionPassTest.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\DependencyInjection\Tests\Compiler; + +use Symfony\Component\DependencyInjection\Compiler\ReplaceAliasByActualDefinitionPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; + +class ReplaceAliasByActualDefinitionPassTest extends \PHPUnit_Framework_TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + + $container->register('a', '\stdClass'); + + $bDefinition = new Definition('\stdClass'); + $bDefinition->setPublic(false); + $container->setDefinition('b', $bDefinition); + + $container->setAlias('a_alias', 'a'); + $container->setAlias('b_alias', 'b'); + + $this->process($container); + + $this->assertTrue($container->has('a'), '->process() does nothing to public definitions.'); + $this->assertTrue($container->hasAlias('a_alias')); + $this->assertFalse($container->has('b'), '->process() removes non-public definitions.'); + $this->assertTrue( + $container->has('b_alias') && !$container->hasAlias('b_alias'), + '->process() replaces alias to actual.' + ); + } + + protected function process(ContainerBuilder $container) + { + $pass = new ReplaceAliasByActualDefinitionPass(); + $pass->process($container); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php new file mode 100644 index 0000000..f3c5b15 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php @@ -0,0 +1,151 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\Compiler\ResolveDefinitionTemplatesPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + $container->register('parent', 'foo')->setArguments(array('moo', 'b'))->setProperty('foo', 'moo'); + $container->setDefinition('child', new DefinitionDecorator('parent')) + ->replaceArgument(0, 'a') + ->setProperty('foo', 'bar') + ->setClass('bar') + ; + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertNotInstanceOf('Symfony\Component\DependencyInjection\DefinitionDecorator', $def); + $this->assertEquals('bar', $def->getClass()); + $this->assertEquals(array('a', 'b'), $def->getArguments()); + $this->assertEquals(array('foo' => 'bar'), $def->getProperties()); + } + + public function testProcessAppendsMethodCallsAlways() + { + $container = new ContainerBuilder(); + + $container + ->register('parent') + ->addMethodCall('foo', array('bar')) + ; + + $container + ->setDefinition('child', new DefinitionDecorator('parent')) + ->addMethodCall('bar', array('foo')) + ; + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertEquals(array( + array('foo', array('bar')), + array('bar', array('foo')), + ), $def->getMethodCalls()); + } + + public function testProcessDoesNotCopyAbstract() + { + $container = new ContainerBuilder(); + + $container + ->register('parent') + ->setAbstract(true) + ; + + $container + ->setDefinition('child', new DefinitionDecorator('parent')) + ; + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertFalse($def->isAbstract()); + } + + public function testProcessDoesNotCopyScope() + { + $container = new ContainerBuilder(); + + $container + ->register('parent') + ->setScope('foo') + ; + + $container + ->setDefinition('child', new DefinitionDecorator('parent')) + ; + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertEquals(ContainerInterface::SCOPE_CONTAINER, $def->getScope()); + } + + public function testProcessDoesNotCopyTags() + { + $container = new ContainerBuilder(); + + $container + ->register('parent') + ->addTag('foo') + ; + + $container + ->setDefinition('child', new DefinitionDecorator('parent')) + ; + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertEquals(array(), $def->getTags()); + } + + public function testProcessHandlesMultipleInheritance() + { + $container = new ContainerBuilder(); + + $container + ->register('parent', 'foo') + ->setArguments(array('foo', 'bar', 'c')) + ; + + $container + ->setDefinition('child2', new DefinitionDecorator('child1')) + ->replaceArgument(1, 'b') + ; + + $container + ->setDefinition('child1', new DefinitionDecorator('parent')) + ->replaceArgument(0, 'a') + ; + + $this->process($container); + + $def = $container->getDefinition('child2'); + $this->assertEquals(array('a', 'b', 'c'), $def->getArguments()); + $this->assertEquals('foo', $def->getClass()); + } + + protected function process(ContainerBuilder $container) + { + $pass = new ResolveDefinitionTemplatesPass(); + $pass->process($container); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInvalidReferencesPassTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInvalidReferencesPassTest.php new file mode 100644 index 0000000..a18ba73 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInvalidReferencesPassTest.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\DependencyInjection\Tests\Compiler; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Compiler\ResolveInvalidReferencesPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +class ResolveInvalidReferencesPassTest extends \PHPUnit_Framework_TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + $def = $container + ->register('foo') + ->setArguments(array(new Reference('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE))) + ->addMethodCall('foo', array(new Reference('moo', ContainerInterface::IGNORE_ON_INVALID_REFERENCE))) + ; + + $this->process($container); + + $arguments = $def->getArguments(); + $this->assertNull($arguments[0]); + $this->assertCount(0, $def->getMethodCalls()); + } + + public function testProcessIgnoreNonExistentServices() + { + $container = new ContainerBuilder(); + $def = $container + ->register('foo') + ->setArguments(array(new Reference('bar'))) + ; + + $this->process($container); + + $arguments = $def->getArguments(); + $this->assertEquals('bar', (string) $arguments[0]); + } + + public function testProcessRemovesPropertiesOnInvalid() + { + $container = new ContainerBuilder(); + $def = $container + ->register('foo') + ->setProperty('foo', new Reference('bar', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)) + ; + + $this->process($container); + + $this->assertEquals(array(), $def->getProperties()); + } + + protected function process(ContainerBuilder $container) + { + $pass = new ResolveInvalidReferencesPass(); + $pass->process($container); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveReferencesToAliasesPassTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveReferencesToAliasesPassTest.php new file mode 100644 index 0000000..ca089a5 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveReferencesToAliasesPassTest.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\DependencyInjection\Tests\Compiler; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Compiler\ResolveReferencesToAliasesPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +class ResolveReferencesToAliasesPassTest extends \PHPUnit_Framework_TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + $container->setAlias('bar', 'foo'); + $def = $container + ->register('moo') + ->setArguments(array(new Reference('bar'))) + ; + + $this->process($container); + + $arguments = $def->getArguments(); + $this->assertEquals('foo', (string) $arguments[0]); + } + + public function testProcessRecursively() + { + $container = new ContainerBuilder(); + $container->setAlias('bar', 'foo'); + $container->setAlias('moo', 'bar'); + $def = $container + ->register('foobar') + ->setArguments(array(new Reference('moo'))) + ; + + $this->process($container); + + $arguments = $def->getArguments(); + $this->assertEquals('foo', (string) $arguments[0]); + } + + protected function process(ContainerBuilder $container) + { + $pass = new ResolveReferencesToAliasesPass(); + $pass->process($container); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php new file mode 100644 index 0000000..bedcecb --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -0,0 +1,554 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests; + +require_once __DIR__.'/Fixtures/includes/classes.php'; +require_once __DIR__.'/Fixtures/includes/ProjectExtension.php'; + +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\Config\Resource\FileResource; + +class ContainerBuilderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::setDefinitions + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::getDefinitions + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::setDefinition + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::getDefinition + */ + public function testDefinitions() + { + $builder = new ContainerBuilder(); + $definitions = array( + 'foo' => new Definition('FooClass'), + 'bar' => new Definition('BarClass'), + ); + $builder->setDefinitions($definitions); + $this->assertEquals($definitions, $builder->getDefinitions(), '->setDefinitions() sets the service definitions'); + $this->assertTrue($builder->hasDefinition('foo'), '->hasDefinition() returns true if a service definition exists'); + $this->assertFalse($builder->hasDefinition('foobar'), '->hasDefinition() returns false if a service definition does not exist'); + + $builder->setDefinition('foobar', $foo = new Definition('FooBarClass')); + $this->assertEquals($foo, $builder->getDefinition('foobar'), '->getDefinition() returns a service definition if defined'); + $this->assertTrue($builder->setDefinition('foobar', $foo = new Definition('FooBarClass')) === $foo, '->setDefinition() implements a fluid interface by returning the service reference'); + + $builder->addDefinitions($defs = array('foobar' => new Definition('FooBarClass'))); + $this->assertEquals(array_merge($definitions, $defs), $builder->getDefinitions(), '->addDefinitions() adds the service definitions'); + + try { + $builder->getDefinition('baz'); + $this->fail('->getDefinition() throws an InvalidArgumentException if the service definition does not exist'); + } catch (\InvalidArgumentException $e) { + $this->assertEquals('The service definition "baz" does not exist.', $e->getMessage(), '->getDefinition() throws an InvalidArgumentException if the service definition does not exist'); + } + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::register + */ + public function testRegister() + { + $builder = new ContainerBuilder(); + $builder->register('foo', 'FooClass'); + $this->assertTrue($builder->hasDefinition('foo'), '->register() registers a new service definition'); + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $builder->getDefinition('foo'), '->register() returns the newly created Definition instance'); + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::has + */ + public function testHas() + { + $builder = new ContainerBuilder(); + $this->assertFalse($builder->has('foo'), '->has() returns false if the service does not exist'); + $builder->register('foo', 'FooClass'); + $this->assertTrue($builder->has('foo'), '->has() returns true if a service definition exists'); + $builder->set('bar', new \stdClass()); + $this->assertTrue($builder->has('bar'), '->has() returns true if a service exists'); + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::get + */ + public function testGet() + { + $builder = new ContainerBuilder(); + try { + $builder->get('foo'); + $this->fail('->get() throws an InvalidArgumentException if the service does not exist'); + } catch (\InvalidArgumentException $e) { + $this->assertEquals('The service definition "foo" does not exist.', $e->getMessage(), '->get() throws an InvalidArgumentException if the service does not exist'); + } + + $this->assertNull($builder->get('foo', ContainerInterface::NULL_ON_INVALID_REFERENCE), '->get() returns null if the service does not exist and NULL_ON_INVALID_REFERENCE is passed as a second argument'); + + $builder->register('foo', 'stdClass'); + $this->assertInternalType('object', $builder->get('foo'), '->get() returns the service definition associated with the id'); + $builder->set('bar', $bar = new \stdClass()); + $this->assertEquals($bar, $builder->get('bar'), '->get() returns the service associated with the id'); + $builder->register('bar', 'stdClass'); + $this->assertEquals($bar, $builder->get('bar'), '->get() returns the service associated with the id even if a definition has been defined'); + + $builder->register('baz', 'stdClass')->setArguments(array(new Reference('baz'))); + try { + @$builder->get('baz'); + $this->fail('->get() throws a ServiceCircularReferenceException if the service has a circular reference to itself'); + } catch (\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException $e) { + $this->assertEquals('Circular reference detected for service "baz", path: "baz".', $e->getMessage(), '->get() throws a LogicException if the service has a circular reference to itself'); + } + + $builder->register('foobar', 'stdClass')->setScope('container'); + $this->assertTrue($builder->get('bar') === $builder->get('bar'), '->get() always returns the same instance if the service is shared'); + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::getServiceIds + */ + public function testGetServiceIds() + { + $builder = new ContainerBuilder(); + $builder->register('foo', 'stdClass'); + $builder->bar = $bar = new \stdClass(); + $builder->register('bar', 'stdClass'); + $this->assertEquals(array('foo', 'bar', 'service_container'), $builder->getServiceIds(), '->getServiceIds() returns all defined service ids'); + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::setAlias + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::hasAlias + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::getAlias + */ + public function testAliases() + { + $builder = new ContainerBuilder(); + $builder->register('foo', 'stdClass'); + $builder->setAlias('bar', 'foo'); + $this->assertTrue($builder->hasAlias('bar'), '->hasAlias() returns true if the alias exists'); + $this->assertFalse($builder->hasAlias('foobar'), '->hasAlias() returns false if the alias does not exist'); + $this->assertEquals('foo', (string) $builder->getAlias('bar'), '->getAlias() returns the aliased service'); + $this->assertTrue($builder->has('bar'), '->setAlias() defines a new service'); + $this->assertTrue($builder->get('bar') === $builder->get('foo'), '->setAlias() creates a service that is an alias to another one'); + + try { + $builder->getAlias('foobar'); + $this->fail('->getAlias() throws an InvalidArgumentException if the alias does not exist'); + } catch (\InvalidArgumentException $e) { + $this->assertEquals('The service alias "foobar" does not exist.', $e->getMessage(), '->getAlias() throws an InvalidArgumentException if the alias does not exist'); + } + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::getAliases + */ + public function testGetAliases() + { + $builder = new ContainerBuilder(); + $builder->setAlias('bar', 'foo'); + $builder->setAlias('foobar', 'foo'); + $builder->setAlias('moo', new Alias('foo', false)); + + $aliases = $builder->getAliases(); + $this->assertEquals('foo', (string) $aliases['bar']); + $this->assertTrue($aliases['bar']->isPublic()); + $this->assertEquals('foo', (string) $aliases['foobar']); + $this->assertEquals('foo', (string) $aliases['moo']); + $this->assertFalse($aliases['moo']->isPublic()); + + $builder->register('bar', 'stdClass'); + $this->assertFalse($builder->hasAlias('bar')); + + $builder->set('foobar', 'stdClass'); + $builder->set('moo', 'stdClass'); + $this->assertCount(0, $builder->getAliases(), '->getAliases() does not return aliased services that have been overridden'); + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::setAliases + */ + public function testSetAliases() + { + $builder = new ContainerBuilder(); + $builder->setAliases(array('bar' => 'foo', 'foobar' => 'foo')); + + $aliases = $builder->getAliases(); + $this->assertTrue(isset($aliases['bar'])); + $this->assertTrue(isset($aliases['foobar'])); + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::addAliases + */ + public function testAddAliases() + { + $builder = new ContainerBuilder(); + $builder->setAliases(array('bar' => 'foo')); + $builder->addAliases(array('foobar' => 'foo')); + + $aliases = $builder->getAliases(); + $this->assertTrue(isset($aliases['bar'])); + $this->assertTrue(isset($aliases['foobar'])); + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::addCompilerPass + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::getCompilerPassConfig + */ + public function testAddGetCompilerPass() + { + if (!class_exists('Symfony\Component\Config\Resource\FileResource')) { + $this->markTestSkipped('The "Config" component is not available'); + } + + $builder = new ContainerBuilder(); + $builderCompilerPasses = $builder->getCompiler()->getPassConfig()->getPasses(); + $builder->addCompilerPass($this->getMock('Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface')); + $this->assertEquals(sizeof($builderCompilerPasses) + 1, sizeof($builder->getCompiler()->getPassConfig()->getPasses())); + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::createService + */ + public function testCreateService() + { + $builder = new ContainerBuilder(); + $builder->register('foo1', 'FooClass')->setFile(__DIR__.'/Fixtures/includes/foo.php'); + $this->assertInstanceOf('\FooClass', $builder->get('foo1'), '->createService() requires the file defined by the service definition'); + $builder->register('foo2', 'FooClass')->setFile(__DIR__.'/Fixtures/includes/%file%.php'); + $builder->setParameter('file', 'foo'); + $this->assertInstanceOf('\FooClass', $builder->get('foo2'), '->createService() replaces parameters in the file provided by the service definition'); + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::createService + */ + public function testCreateServiceClass() + { + $builder = new ContainerBuilder(); + $builder->register('foo1', '%class%'); + $builder->setParameter('class', 'stdClass'); + $this->assertInstanceOf('\stdClass', $builder->get('foo1'), '->createService() replaces parameters in the class provided by the service definition'); + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::createService + */ + public function testCreateServiceArguments() + { + $builder = new ContainerBuilder(); + $builder->register('bar', 'stdClass'); + $builder->register('foo1', 'FooClass')->addArgument(array('foo' => '%value%', '%value%' => 'foo', new Reference('bar'))); + $builder->setParameter('value', 'bar'); + $this->assertEquals(array('foo' => 'bar', 'bar' => 'foo', $builder->get('bar')), $builder->get('foo1')->arguments, '->createService() replaces parameters and service references in the arguments provided by the service definition'); + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::createService + */ + public function testCreateServiceFactoryMethod() + { + $builder = new ContainerBuilder(); + $builder->register('bar', 'stdClass'); + $builder->register('foo1', 'FooClass')->setFactoryClass('FooClass')->setFactoryMethod('getInstance')->addArgument(array('foo' => '%value%', '%value%' => 'foo', new Reference('bar'))); + $builder->setParameter('value', 'bar'); + $this->assertTrue($builder->get('foo1')->called, '->createService() calls the factory method to create the service instance'); + $this->assertEquals(array('foo' => 'bar', 'bar' => 'foo', $builder->get('bar')), $builder->get('foo1')->arguments, '->createService() passes the arguments to the factory method'); + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::createService + */ + public function testCreateServiceFactoryService() + { + $builder = new ContainerBuilder(); + $builder->register('baz_service')->setFactoryService('baz_factory')->setFactoryMethod('getInstance'); + $builder->register('baz_factory', 'BazClass'); + + $this->assertInstanceOf('BazClass', $builder->get('baz_service')); + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::createService + */ + public function testCreateServiceMethodCalls() + { + $builder = new ContainerBuilder(); + $builder->register('bar', 'stdClass'); + $builder->register('foo1', 'FooClass')->addMethodCall('setBar', array(array('%value%', new Reference('bar')))); + $builder->setParameter('value', 'bar'); + $this->assertEquals(array('bar', $builder->get('bar')), $builder->get('foo1')->bar, '->createService() replaces the values in the method calls arguments'); + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::createService + */ + public function testCreateServiceConfigurator() + { + $builder = new ContainerBuilder(); + $builder->register('foo1', 'FooClass')->setConfigurator('sc_configure'); + $this->assertTrue($builder->get('foo1')->configured, '->createService() calls the configurator'); + + $builder->register('foo2', 'FooClass')->setConfigurator(array('%class%', 'configureStatic')); + $builder->setParameter('class', 'BazClass'); + $this->assertTrue($builder->get('foo2')->configured, '->createService() calls the configurator'); + + $builder->register('baz', 'BazClass'); + $builder->register('foo3', 'FooClass')->setConfigurator(array(new Reference('baz'), 'configure')); + $this->assertTrue($builder->get('foo3')->configured, '->createService() calls the configurator'); + + $builder->register('foo4', 'FooClass')->setConfigurator('foo'); + try { + $builder->get('foo4'); + $this->fail('->createService() throws an InvalidArgumentException if the configure callable is not a valid callable'); + } catch (\InvalidArgumentException $e) { + $this->assertEquals('The configure callable for class "FooClass" is not a callable.', $e->getMessage(), '->createService() throws an InvalidArgumentException if the configure callable is not a valid callable'); + } + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::resolveServices + */ + public function testResolveServices() + { + $builder = new ContainerBuilder(); + $builder->register('foo', 'FooClass'); + $this->assertEquals($builder->get('foo'), $builder->resolveServices(new Reference('foo')), '->resolveServices() resolves service references to service instances'); + $this->assertEquals(array('foo' => array('foo', $builder->get('foo'))), $builder->resolveServices(array('foo' => array('foo', new Reference('foo')))), '->resolveServices() resolves service references to service instances in nested arrays'); + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::merge + */ + public function testMerge() + { + if (!class_exists('Symfony\Component\Config\Resource\FileResource')) { + $this->markTestSkipped('The "Config" component is not available'); + } + + $container = new ContainerBuilder(new ParameterBag(array('bar' => 'foo'))); + $config = new ContainerBuilder(new ParameterBag(array('foo' => 'bar'))); + $container->merge($config); + $this->assertEquals(array('bar' => 'foo', 'foo' => 'bar'), $container->getParameterBag()->all(), '->merge() merges current parameters with the loaded ones'); + + $container = new ContainerBuilder(new ParameterBag(array('bar' => 'foo'))); + $config = new ContainerBuilder(new ParameterBag(array('foo' => '%bar%'))); + $container->merge($config); +////// FIXME + $container->compile(); + $this->assertEquals(array('bar' => 'foo', 'foo' => 'foo'), $container->getParameterBag()->all(), '->merge() evaluates the values of the parameters towards already defined ones'); + + $container = new ContainerBuilder(new ParameterBag(array('bar' => 'foo'))); + $config = new ContainerBuilder(new ParameterBag(array('foo' => '%bar%', 'baz' => '%foo%'))); + $container->merge($config); +////// FIXME + $container->compile(); + $this->assertEquals(array('bar' => 'foo', 'foo' => 'foo', 'baz' => 'foo'), $container->getParameterBag()->all(), '->merge() evaluates the values of the parameters towards already defined ones'); + + $container = new ContainerBuilder(); + $container->register('foo', 'FooClass'); + $container->register('bar', 'BarClass'); + $config = new ContainerBuilder(); + $config->setDefinition('baz', new Definition('BazClass')); + $config->setAlias('alias_for_foo', 'foo'); + $container->merge($config); + $this->assertEquals(array('foo', 'bar', 'baz'), array_keys($container->getDefinitions()), '->merge() merges definitions already defined ones'); + + $aliases = $container->getAliases(); + $this->assertTrue(isset($aliases['alias_for_foo'])); + $this->assertEquals('foo', (string) $aliases['alias_for_foo']); + + $container = new ContainerBuilder(); + $container->register('foo', 'FooClass'); + $config->setDefinition('foo', new Definition('BazClass')); + $container->merge($config); + $this->assertEquals('BazClass', $container->getDefinition('foo')->getClass(), '->merge() overrides already defined services'); + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::merge + * @expectedException LogicException + */ + public function testMergeLogicException() + { + if (!class_exists('Symfony\Component\Config\Resource\FileResource')) { + $this->markTestSkipped('The "Config" component is not available'); + } + + $container = new ContainerBuilder(); + $container->compile(); + $container->merge(new ContainerBuilder()); + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::findTaggedServiceIds + */ + public function testfindTaggedServiceIds() + { + $builder = new ContainerBuilder(); + $builder + ->register('foo', 'FooClass') + ->addTag('foo', array('foo' => 'foo')) + ->addTag('bar', array('bar' => 'bar')) + ->addTag('foo', array('foofoo' => 'foofoo')) + ; + $this->assertEquals($builder->findTaggedServiceIds('foo'), array( + 'foo' => array( + array('foo' => 'foo'), + array('foofoo' => 'foofoo'), + ) + ), '->findTaggedServiceIds() returns an array of service ids and its tag attributes'); + $this->assertEquals(array(), $builder->findTaggedServiceIds('foobar'), '->findTaggedServiceIds() returns an empty array if there is annotated services'); + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::findDefinition + */ + public function testFindDefinition() + { + $container = new ContainerBuilder(); + $container->setDefinition('foo', $definition = new Definition('FooClass')); + $container->setAlias('bar', 'foo'); + $container->setAlias('foobar', 'bar'); + $this->assertEquals($definition, $container->findDefinition('foobar'), '->findDefinition() returns a Definition'); + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::getResources + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::addResource + */ + public function testResources() + { + if (!class_exists('Symfony\Component\Config\Resource\FileResource')) { + $this->markTestSkipped('The "Config" component is not available'); + } + + $container = new ContainerBuilder(); + $container->addResource($a = new FileResource(__DIR__.'/Fixtures/xml/services1.xml')); + $container->addResource($b = new FileResource(__DIR__.'/Fixtures/xml/services2.xml')); + $resources = array(); + foreach ($container->getResources() as $resource) { + if (false === strpos($resource, '.php')) { + $resources[] = $resource; + } + } + $this->assertEquals(array($a, $b), $resources, '->getResources() returns an array of resources read for the current configuration'); + $this->assertSame($container, $container->setResources(array())); + $this->assertEquals(array(), $container->getResources()); + } + + /** + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::registerExtension + * @covers Symfony\Component\DependencyInjection\ContainerBuilder::getExtension + */ + public function testExtension() + { + if (!class_exists('Symfony\Component\Config\Resource\FileResource')) { + $this->markTestSkipped('The "Config" component is not available'); + } + + $container = new ContainerBuilder(); + + $container->registerExtension($extension = new \ProjectExtension()); + $this->assertTrue($container->getExtension('project') === $extension, '->registerExtension() registers an extension'); + + $this->setExpectedException('LogicException'); + $container->getExtension('no_registered'); + } + + public function testRegisteredButNotLoadedExtension() + { + if (!class_exists('Symfony\Component\Config\Resource\FileResource')) { + $this->markTestSkipped('The "Config" component is not available'); + } + + $extension = $this->getMock('Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface'); + $extension->expects($this->once())->method('getAlias')->will($this->returnValue('project')); + $extension->expects($this->never())->method('load'); + + $container = new ContainerBuilder(); + $container->registerExtension($extension); + $container->compile(); + } + + public function testRegisteredAndLoadedExtension() + { + if (!class_exists('Symfony\Component\Config\Resource\FileResource')) { + $this->markTestSkipped('The "Config" component is not available'); + } + + $extension = $this->getMock('Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface'); + $extension->expects($this->exactly(2))->method('getAlias')->will($this->returnValue('project')); + $extension->expects($this->once())->method('load')->with(array(array('foo' => 'bar'))); + + $container = new ContainerBuilder(); + $container->registerExtension($extension); + $container->loadFromExtension('project', array('foo' => 'bar')); + $container->compile(); + } + + public function testPrivateServiceUser() + { + if (!class_exists('Symfony\Component\Config\Resource\FileResource')) { + $this->markTestSkipped('The "Config" component is not available'); + } + + $fooDefinition = new Definition('BarClass'); + $fooUserDefinition = new Definition('BarUserClass', array(new Reference('bar'))); + $container = new ContainerBuilder(); + + $fooDefinition->setPublic(false); + + $container->addDefinitions(array( + 'bar' => $fooDefinition, + 'bar_user' => $fooUserDefinition + )); + + $container->compile(); + $this->assertInstanceOf('BarClass', $container->get('bar_user')->bar); + } + + /** + * @expectedException BadMethodCallException + */ + public function testThrowsExceptionWhenSetServiceOnAFrozenContainer() + { + if (!class_exists('Symfony\Component\Config\Resource\FileResource')) { + $this->markTestSkipped('The "Config" component is not available'); + } + + $container = new ContainerBuilder(); + $container->compile(); + $container->set('a', new \stdClass()); + } + + /** + * @expectedException BadMethodCallException + */ + public function testThrowsExceptionWhenSetDefinitionOnAFrozenContainer() + { + if (!class_exists('Symfony\Component\Config\Resource\FileResource')) { + $this->markTestSkipped('The "Config" component is not available'); + } + + $container = new ContainerBuilder(); + $container->compile(); + $container->setDefinition('a', new Definition()); + } +} + + +class FooClass {} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php new file mode 100644 index 0000000..1be5106 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php @@ -0,0 +1,450 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests; + +use Symfony\Component\DependencyInjection\Scope; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; + +class ContainerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Symfony\Component\DependencyInjection\Container::__construct + */ + public function testConstructor() + { + $sc = new Container(); + $this->assertSame($sc, $sc->get('service_container'), '__construct() automatically registers itself as a service'); + + $sc = new Container(new ParameterBag(array('foo' => 'bar'))); + $this->assertEquals(array('foo' => 'bar'), $sc->getParameterBag()->all(), '__construct() takes an array of parameters as its first argument'); + } + + /** + * @covers Symfony\Component\DependencyInjection\Container::compile + */ + public function testCompile() + { + $sc = new Container(new ParameterBag(array('foo' => 'bar'))); + $sc->compile(); + $this->assertInstanceOf('Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag', $sc->getParameterBag(), '->compile() changes the parameter bag to a FrozenParameterBag instance'); + $this->assertEquals(array('foo' => 'bar'), $sc->getParameterBag()->all(), '->compile() copies the current parameters to the new parameter bag'); + } + + /** + * @covers Symfony\Component\DependencyInjection\Container::isFrozen + */ + public function testIsFrozen() + { + $sc = new Container(new ParameterBag(array('foo' => 'bar'))); + $this->assertFalse($sc->isFrozen(), '->isFrozen() returns false if the parameters are not frozen'); + $sc->compile(); + $this->assertTrue($sc->isFrozen(), '->isFrozen() returns true if the parameters are frozen'); + } + + /** + * @covers Symfony\Component\DependencyInjection\Container::getParameterBag + */ + public function testGetParameterBag() + { + $sc = new Container(); + $this->assertEquals(array(), $sc->getParameterBag()->all(), '->getParameterBag() returns an empty array if no parameter has been defined'); + } + + /** + * @covers Symfony\Component\DependencyInjection\Container::setParameter + * @covers Symfony\Component\DependencyInjection\Container::getParameter + */ + public function testGetSetParameter() + { + $sc = new Container(new ParameterBag(array('foo' => 'bar'))); + $sc->setParameter('bar', 'foo'); + $this->assertEquals('foo', $sc->getParameter('bar'), '->setParameter() sets the value of a new parameter'); + + $sc->setParameter('foo', 'baz'); + $this->assertEquals('baz', $sc->getParameter('foo'), '->setParameter() overrides previously set parameter'); + + $sc->setParameter('Foo', 'baz1'); + $this->assertEquals('baz1', $sc->getParameter('foo'), '->setParameter() converts the key to lowercase'); + $this->assertEquals('baz1', $sc->getParameter('FOO'), '->getParameter() converts the key to lowercase'); + + try { + $sc->getParameter('baba'); + $this->fail('->getParameter() thrown an \InvalidArgumentException if the key does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->getParameter() thrown an \InvalidArgumentException if the key does not exist'); + $this->assertEquals('You have requested a non-existent parameter "baba".', $e->getMessage(), '->getParameter() thrown an \InvalidArgumentException if the key does not exist'); + } + } + + /** + * @covers Symfony\Component\DependencyInjection\Container::getServiceIds + */ + public function testGetServiceIds() + { + $sc = new Container(); + $sc->set('foo', $obj = new \stdClass()); + $sc->set('bar', $obj = new \stdClass()); + $this->assertEquals(array('service_container', 'foo', 'bar'), $sc->getServiceIds(), '->getServiceIds() returns all defined service ids'); + + $sc = new ProjectServiceContainer(); + $this->assertEquals(array('scoped', 'scoped_foo', 'bar', 'foo_bar', 'foo.baz', 'circular', 'throw_exception', 'service_container'), $sc->getServiceIds(), '->getServiceIds() returns defined service ids by getXXXService() methods'); + } + + /** + * @covers Symfony\Component\DependencyInjection\Container::set + */ + public function testSet() + { + $sc = new Container(); + $sc->set('foo', $foo = new \stdClass()); + $this->assertEquals($foo, $sc->get('foo'), '->set() sets a service'); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testSetDoesNotAllowPrototypeScope() + { + $c = new Container(); + $c->set('foo', new \stdClass(), 'prototype'); + } + + /** + * @expectedException \RuntimeException + */ + public function testSetDoesNotAllowInactiveScope() + { + $c = new Container(); + $c->addScope(new Scope('foo')); + $c->set('foo', new \stdClass(), 'foo'); + } + + public function testSetAlsoSetsScopedService() + { + $c = new Container(); + $c->addScope(new Scope('foo')); + $c->enterScope('foo'); + $c->set('foo', $foo = new \stdClass(), 'foo'); + + $services = $this->getField($c, 'scopedServices'); + $this->assertTrue(isset($services['foo']['foo'])); + $this->assertSame($foo, $services['foo']['foo']); + } + + /** + * @covers Symfony\Component\DependencyInjection\Container::get + */ + public function testGet() + { + $sc = new ProjectServiceContainer(); + $sc->set('foo', $foo = new \stdClass()); + $this->assertEquals($foo, $sc->get('foo'), '->get() returns the service for the given id'); + $this->assertEquals($sc->__bar, $sc->get('bar'), '->get() returns the service for the given id'); + $this->assertEquals($sc->__foo_bar, $sc->get('foo_bar'), '->get() returns the service if a get*Method() is defined'); + $this->assertEquals($sc->__foo_baz, $sc->get('foo.baz'), '->get() returns the service if a get*Method() is defined'); + + $sc->set('bar', $bar = new \stdClass()); + $this->assertEquals($bar, $sc->get('bar'), '->get() prefers to return a service defined with set() than one defined with a getXXXMethod()'); + + try { + $sc->get(''); + $this->fail('->get() throws a \InvalidArgumentException exception if the service is empty'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException', $e, '->get() throws a ServiceNotFoundException exception if the service is empty'); + } + $this->assertNull($sc->get('', ContainerInterface::NULL_ON_INVALID_REFERENCE)); + } + + public function testGetCircularReference() + { + + $sc = new ProjectServiceContainer(); + try { + $sc->get('circular'); + $this->fail('->get() throws a ServiceCircularReferenceException if it contains circular reference'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException', $e, '->get() throws a ServiceCircularReferenceException if it contains circular reference'); + $this->assertStringStartsWith('Circular reference detected for service "circular"', $e->getMessage(), '->get() throws a \LogicException if it contains circular reference'); + } + } + + /** + * @covers Symfony\Component\DependencyInjection\Container::has + */ + public function testHas() + { + $sc = new ProjectServiceContainer(); + $sc->set('foo', new \stdClass()); + $this->assertFalse($sc->has('foo1'), '->has() returns false if the service does not exist'); + $this->assertTrue($sc->has('foo'), '->has() returns true if the service exists'); + $this->assertTrue($sc->has('bar'), '->has() returns true if a get*Method() is defined'); + $this->assertTrue($sc->has('foo_bar'), '->has() returns true if a get*Method() is defined'); + $this->assertTrue($sc->has('foo.baz'), '->has() returns true if a get*Method() is defined'); + } + + /** + * @covers Symfony\Component\DependencyInjection\Container::initialized + */ + public function testInitialized() + { + $sc = new ProjectServiceContainer(); + $sc->set('foo', new \stdClass()); + $this->assertTrue($sc->initialized('foo'), '->initialized() returns true if service is loaded'); + $this->assertFalse($sc->initialized('foo1'), '->initialized() returns false if service is not loaded'); + $this->assertFalse($sc->initialized('bar'), '->initialized() returns false if a service is defined, but not currently loaded'); + } + + public function testEnterLeaveCurrentScope() + { + $container = new ProjectServiceContainer(); + $container->addScope(new Scope('foo')); + + $container->enterScope('foo'); + $scoped1 = $container->get('scoped'); + $scopedFoo1 = $container->get('scoped_foo'); + + $container->enterScope('foo'); + $scoped2 = $container->get('scoped'); + $scoped3 = $container->get('scoped'); + $scopedFoo2 = $container->get('scoped_foo'); + + $container->leaveScope('foo'); + $scoped4 = $container->get('scoped'); + $scopedFoo3 = $container->get('scoped_foo'); + + $this->assertNotSame($scoped1, $scoped2); + $this->assertSame($scoped2, $scoped3); + $this->assertSame($scoped1, $scoped4); + $this->assertNotSame($scopedFoo1, $scopedFoo2); + $this->assertSame($scopedFoo1, $scopedFoo3); + } + + public function testEnterLeaveScopeWithChildScopes() + { + $container = new Container(); + $container->addScope(new Scope('foo')); + $container->addScope(new Scope('bar', 'foo')); + + $this->assertFalse($container->isScopeActive('foo')); + + $container->enterScope('foo'); + $container->enterScope('bar'); + + $this->assertTrue($container->isScopeActive('foo')); + $this->assertFalse($container->has('a')); + + $a = new \stdClass(); + $container->set('a', $a, 'bar'); + + $services = $this->getField($container, 'scopedServices'); + $this->assertTrue(isset($services['bar']['a'])); + $this->assertSame($a, $services['bar']['a']); + + $this->assertTrue($container->has('a')); + $container->leaveScope('foo'); + + $services = $this->getField($container, 'scopedServices'); + $this->assertFalse(isset($services['bar'])); + + $this->assertFalse($container->isScopeActive('foo')); + $this->assertFalse($container->has('a')); + } + + public function testLeaveScopeNotActive() + { + $container = new Container(); + $container->addScope(new Scope('foo')); + + try { + $container->leaveScope('foo'); + $this->fail('->leaveScope() throws a \LogicException if the scope is not active yet'); + } catch (\Exception $e) { + $this->assertInstanceOf('\LogicException', $e, '->leaveScope() throws a \LogicException if the scope is not active yet'); + $this->assertEquals('The scope "foo" is not active.', $e->getMessage(), '->leaveScope() throws a \LogicException if the scope is not active yet'); + } + + try { + $container->leaveScope('bar'); + $this->fail('->leaveScope() throws a \LogicException if the scope does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('\LogicException', $e, '->leaveScope() throws a \LogicException if the scope does not exist'); + $this->assertEquals('The scope "bar" is not active.', $e->getMessage(), '->leaveScope() throws a \LogicException if the scope does not exist'); + } + } + + /** + * @expectedException \InvalidArgumentException + * @dataProvider getBuiltInScopes + */ + public function testAddScopeDoesNotAllowBuiltInScopes($scope) + { + $container = new Container(); + $container->addScope(new Scope($scope)); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testAddScopeDoesNotAllowExistingScope() + { + $container = new Container(); + $container->addScope(new Scope('foo')); + $container->addScope(new Scope('foo')); + } + + /** + * @expectedException \InvalidArgumentException + * @dataProvider getInvalidParentScopes + */ + public function testAddScopeDoesNotAllowInvalidParentScope($scope) + { + $c = new Container(); + $c->addScope(new Scope('foo', $scope)); + } + + public function testAddScope() + { + $c = new Container(); + $c->addScope(new Scope('foo')); + $c->addScope(new Scope('bar', 'foo')); + + $this->assertSame(array('foo' => 'container', 'bar' => 'foo'), $this->getField($c, 'scopes')); + $this->assertSame(array('foo' => array('bar'), 'bar' => array()), $this->getField($c, 'scopeChildren')); + } + + public function testHasScope() + { + $c = new Container(); + + $this->assertFalse($c->hasScope('foo')); + $c->addScope(new Scope('foo')); + $this->assertTrue($c->hasScope('foo')); + } + + public function testIsScopeActive() + { + $c = new Container(); + + $this->assertFalse($c->isScopeActive('foo')); + $c->addScope(new Scope('foo')); + + $this->assertFalse($c->isScopeActive('foo')); + $c->enterScope('foo'); + + $this->assertTrue($c->isScopeActive('foo')); + $c->leaveScope('foo'); + + $this->assertFalse($c->isScopeActive('foo')); + } + + public function testGetThrowsException() + { + $c = new ProjectServiceContainer(); + + try { + $c->get('throw_exception'); + $this->fail(); + } catch (\Exception $e) { + $this->assertEquals('Something went terribly wrong!', $e->getMessage()); + } + + try { + $c->get('throw_exception'); + $this->fail(); + } catch (\Exception $e) { + $this->assertEquals('Something went terribly wrong!', $e->getMessage()); + } + } + + public function getInvalidParentScopes() + { + return array( + array(ContainerInterface::SCOPE_PROTOTYPE), + array('bar'), + ); + } + + public function getBuiltInScopes() + { + return array( + array(ContainerInterface::SCOPE_CONTAINER), + array(ContainerInterface::SCOPE_PROTOTYPE), + ); + } + + protected function getField($obj, $field) + { + $reflection = new \ReflectionProperty($obj, $field); + $reflection->setAccessible(true); + + return $reflection->getValue($obj); + } +} + +class ProjectServiceContainer extends Container +{ + public $__bar, $__foo_bar, $__foo_baz; + + public function __construct() + { + parent::__construct(); + + $this->__bar = new \stdClass(); + $this->__foo_bar = new \stdClass(); + $this->__foo_baz = new \stdClass(); + } + + protected function getScopedService() + { + if (!isset($this->scopedServices['foo'])) { + throw new \RuntimeException('Invalid call'); + } + + return $this->services['scoped'] = $this->scopedServices['foo']['scoped'] = new \stdClass(); + } + + protected function getScopedFooService() + { + if (!isset($this->scopedServices['foo'])) { + throw new \RuntimeException('invalid call'); + } + + return $this->services['scoped_foo'] = $this->scopedServices['foo']['scoped_foo'] = new \stdClass(); + } + + protected function getBarService() + { + return $this->__bar; + } + + protected function getFooBarService() + { + return $this->__foo_bar; + } + + protected function getFoo_BazService() + { + return $this->__foo_baz; + } + + protected function getCircularService() + { + return $this->get('circular'); + } + + protected function getThrowExceptionService() + { + throw new \Exception('Something went terribly wrong!'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/CrossCheckTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/CrossCheckTest.php new file mode 100644 index 0000000..557c207 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/CrossCheckTest.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\DependencyInjection\Tests; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Config\FileLocator; + +class CrossCheckTest extends \PHPUnit_Framework_TestCase +{ + static protected $fixturesPath; + + protected function setUp() + { + if (!class_exists('Symfony\Component\Config\Loader\Loader')) { + $this->markTestSkipped('The "Config" component is not available'); + } + } + + static public function setUpBeforeClass() + { + self::$fixturesPath = __DIR__.'/Fixtures/'; + + require_once self::$fixturesPath.'/includes/classes.php'; + require_once self::$fixturesPath.'/includes/foo.php'; + } + + /** + * @dataProvider crossCheckLoadersDumpers + */ + public function testCrossCheck($fixture, $type) + { + $loaderClass = 'Symfony\\Component\\DependencyInjection\\Loader\\'.ucfirst($type).'FileLoader'; + $dumperClass = 'Symfony\\Component\\DependencyInjection\\Dumper\\'.ucfirst($type).'Dumper'; + + $tmp = tempnam('sf_service_container', 'sf'); + + file_put_contents($tmp, file_get_contents(self::$fixturesPath.'/'.$type.'/'.$fixture)); + + $container1 = new ContainerBuilder(); + $loader1 = new $loaderClass($container1, new FileLocator()); + $loader1->load($tmp); + + $dumper = new $dumperClass($container1); + file_put_contents($tmp, $dumper->dump()); + + $container2 = new ContainerBuilder(); + $loader2 = new $loaderClass($container2, new FileLocator()); + $loader2->load($tmp); + + unlink($tmp); + + $this->assertEquals($container2->getAliases(), $container1->getAliases(), 'loading a dump from a previously loaded container returns the same container'); + $this->assertEquals($container2->getDefinitions(), $container1->getDefinitions(), 'loading a dump from a previously loaded container returns the same container'); + $this->assertEquals($container2->getParameterBag()->all(), $container1->getParameterBag()->all(), '->getParameterBag() returns the same value for both containers'); + + $this->assertEquals(serialize($container2), serialize($container1), 'loading a dump from a previously loaded container returns the same container'); + + $services1 = array(); + foreach ($container1 as $id => $service) { + $services1[$id] = serialize($service); + } + $services2 = array(); + foreach ($container2 as $id => $service) { + $services2[$id] = serialize($service); + } + + unset($services1['service_container'], $services2['service_container']); + + $this->assertEquals($services2, $services1, 'Iterator on the containers returns the same services'); + } + + public function crossCheckLoadersDumpers() + { + return array( + array('services1.xml', 'xml'), + array('services2.xml', 'xml'), + array('services6.xml', 'xml'), + array('services8.xml', 'xml'), + array('services9.xml', 'xml'), + + array('services1.yml', 'yaml'), + array('services2.yml', 'yaml'), + array('services6.yml', 'yaml'), + array('services8.yml', 'yaml'), + array('services9.yml', 'yaml'), + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/DefinitionDecoratorTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/DefinitionDecoratorTest.php new file mode 100644 index 0000000..bf1bab1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/DefinitionDecoratorTest.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\DependencyInjection\Tests; + +use Symfony\Component\DependencyInjection\DefinitionDecorator; + +class DefinitionDecoratorTest extends \PHPUnit_Framework_TestCase +{ + public function testConstructor() + { + $def = new DefinitionDecorator('foo'); + + $this->assertEquals('foo', $def->getParent()); + $this->assertEquals(array(), $def->getChanges()); + } + + /** + * @dataProvider getPropertyTests + */ + public function testSetProperty($property, $changeKey) + { + $def = new DefinitionDecorator('foo'); + + $getter = 'get'.ucfirst($property); + $setter = 'set'.ucfirst($property); + + $this->assertNull($def->$getter()); + $this->assertSame($def, $def->$setter('foo')); + $this->assertEquals('foo', $def->$getter()); + $this->assertEquals(array($changeKey => true), $def->getChanges()); + } + + public function getPropertyTests() + { + return array( + array('class', 'class'), + array('factoryClass', 'factory_class'), + array('factoryMethod', 'factory_method'), + array('factoryService', 'factory_service'), + array('configurator', 'configurator'), + array('file', 'file'), + ); + } + + public function testSetPublic() + { + $def = new DefinitionDecorator('foo'); + + $this->assertTrue($def->isPublic()); + $this->assertSame($def, $def->setPublic(false)); + $this->assertFalse($def->isPublic()); + $this->assertEquals(array('public' => true), $def->getChanges()); + } + + public function testSetArgument() + { + $def = new DefinitionDecorator('foo'); + + $this->assertEquals(array(), $def->getArguments()); + $this->assertSame($def, $def->replaceArgument(0, 'foo')); + $this->assertEquals(array('index_0' => 'foo'), $def->getArguments()); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testReplaceArgumentShouldRequireIntegerIndex() + { + $def = new DefinitionDecorator('foo'); + + $def->replaceArgument('0', 'foo'); + } + + public function testReplaceArgument() + { + $def = new DefinitionDecorator('foo'); + + $def->setArguments(array(0 => 'foo', 1 => 'bar')); + $this->assertEquals('foo', $def->getArgument(0)); + $this->assertEquals('bar', $def->getArgument(1)); + + $this->assertSame($def, $def->replaceArgument(1, 'baz')); + $this->assertEquals('foo', $def->getArgument(0)); + $this->assertEquals('baz', $def->getArgument(1)); + + $this->assertEquals(array(0 => 'foo', 1 => 'bar', 'index_1' => 'baz'), $def->getArguments()); + } + + /** + * @expectedException OutOfBoundsException + */ + public function testGetArgumentShouldCheckBounds() + { + $def = new DefinitionDecorator('foo'); + + $def->setArguments(array(0 => 'foo')); + $def->replaceArgument(0, 'foo'); + + $def->getArgument(1); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php new file mode 100644 index 0000000..46ea75d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php @@ -0,0 +1,292 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests; + +use Symfony\Component\DependencyInjection\Definition; + +class DefinitionTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Symfony\Component\DependencyInjection\Definition::__construct + */ + public function testConstructor() + { + $def = new Definition('stdClass'); + $this->assertEquals('stdClass', $def->getClass(), '__construct() takes the class name as its first argument'); + + $def = new Definition('stdClass', array('foo')); + $this->assertEquals(array('foo'), $def->getArguments(), '__construct() takes an optional array of arguments as its second argument'); + } + + public function testSetGetFactoryClass() + { + $def = new Definition('stdClass'); + $this->assertNull($def->getFactoryClass()); + $this->assertSame($def, $def->setFactoryClass('stdClass2'), "->setFactoryClass() implements a fluent interface."); + $this->assertEquals('stdClass2', $def->getFactoryClass(), "->getFactoryClass() returns current class to construct this service."); + } + + public function testSetGetFactoryMethod() + { + $def = new Definition('stdClass'); + $this->assertNull($def->getFactoryMethod()); + $this->assertSame($def, $def->setFactoryMethod('foo'), '->setFactoryMethod() implements a fluent interface'); + $this->assertEquals('foo', $def->getFactoryMethod(), '->getFactoryMethod() returns the factory method name'); + } + + public function testSetGetFactoryService() + { + $def = new Definition('stdClass'); + $this->assertNull($def->getFactoryService()); + $this->assertSame($def, $def->setFactoryService('foo.bar'), "->setFactoryService() implements a fluent interface."); + $this->assertEquals('foo.bar', $def->getFactoryService(), "->getFactoryService() returns current service to construct this service."); + } + + /** + * @covers Symfony\Component\DependencyInjection\Definition::setClass + * @covers Symfony\Component\DependencyInjection\Definition::getClass + */ + public function testSetGetClass() + { + $def = new Definition('stdClass'); + $this->assertSame($def, $def->setClass('foo'), '->setClass() implements a fluent interface'); + $this->assertEquals('foo', $def->getClass(), '->getClass() returns the class name'); + } + + /** + * @covers Symfony\Component\DependencyInjection\Definition::setArguments + * @covers Symfony\Component\DependencyInjection\Definition::getArguments + * @covers Symfony\Component\DependencyInjection\Definition::addArgument + */ + public function testArguments() + { + $def = new Definition('stdClass'); + $this->assertSame($def, $def->setArguments(array('foo')), '->setArguments() implements a fluent interface'); + $this->assertEquals(array('foo'), $def->getArguments(), '->getArguments() returns the arguments'); + $this->assertSame($def, $def->addArgument('bar'), '->addArgument() implements a fluent interface'); + $this->assertEquals(array('foo', 'bar'), $def->getArguments(), '->addArgument() adds an argument'); + } + + /** + * @covers Symfony\Component\DependencyInjection\Definition::setMethodCalls + * @covers Symfony\Component\DependencyInjection\Definition::addMethodCall + * @covers Symfony\Component\DependencyInjection\Definition::hasMethodCall + * @covers Symfony\Component\DependencyInjection\Definition::removeMethodCall + */ + public function testMethodCalls() + { + $def = new Definition('stdClass'); + $this->assertSame($def, $def->setMethodCalls(array(array('foo', array('foo')))), '->setMethodCalls() implements a fluent interface'); + $this->assertEquals(array(array('foo', array('foo'))), $def->getMethodCalls(), '->getMethodCalls() returns the methods to call'); + $this->assertSame($def, $def->addMethodCall('bar', array('bar')), '->addMethodCall() implements a fluent interface'); + $this->assertEquals(array(array('foo', array('foo')), array('bar', array('bar'))), $def->getMethodCalls(), '->addMethodCall() adds a method to call'); + $this->assertTrue($def->hasMethodCall('bar'), '->hasMethodCall() returns true if first argument is a method to call registered'); + $this->assertFalse($def->hasMethodCall('no_registered'), '->hasMethodCall() returns false if first argument is not a method to call registered'); + $this->assertSame($def, $def->removeMethodCall('bar'), '->removeMethodCall() implements a fluent interface'); + $this->assertEquals(array(array('foo', array('foo'))), $def->getMethodCalls(), '->removeMethodCall() removes a method to call'); + } + + /** + * @expectedException Symfony\Component\DependencyInjection\Exception\InvalidArgumentException + * @expectedExceptionMessage Method name cannot be empty. + */ + public function testExceptionOnEmptyMethodCall() + { + $def = new Definition('stdClass'); + $def->addMethodCall(''); + } + + /** + * @covers Symfony\Component\DependencyInjection\Definition::setFile + * @covers Symfony\Component\DependencyInjection\Definition::getFile + */ + public function testSetGetFile() + { + $def = new Definition('stdClass'); + $this->assertSame($def, $def->setFile('foo'), '->setFile() implements a fluent interface'); + $this->assertEquals('foo', $def->getFile(), '->getFile() returns the file to include'); + } + + /** + * @covers Symfony\Component\DependencyInjection\Definition::setScope + * @covers Symfony\Component\DependencyInjection\Definition::getScope + */ + public function testSetGetScope() + { + $def = new Definition('stdClass'); + $this->assertEquals('container', $def->getScope()); + $this->assertSame($def, $def->setScope('foo')); + $this->assertEquals('foo', $def->getScope()); + } + + /** + * @covers Symfony\Component\DependencyInjection\Definition::setPublic + * @covers Symfony\Component\DependencyInjection\Definition::isPublic + */ + public function testSetIsPublic() + { + $def = new Definition('stdClass'); + $this->assertTrue($def->isPublic(), '->isPublic() returns true by default'); + $this->assertSame($def, $def->setPublic(false), '->setPublic() implements a fluent interface'); + $this->assertFalse($def->isPublic(), '->isPublic() returns false if the instance must not be public.'); + } + + /** + * @covers Symfony\Component\DependencyInjection\Definition::setSynthetic + * @covers Symfony\Component\DependencyInjection\Definition::isSynthetic + */ + public function testSetIsSynthetic() + { + $def = new Definition('stdClass'); + $this->assertFalse($def->isSynthetic(), '->isSynthetic() returns false by default'); + $this->assertSame($def, $def->setSynthetic(true), '->setSynthetic() implements a fluent interface'); + $this->assertTrue($def->isSynthetic(), '->isSynthetic() returns true if the instance must not be public.'); + } + + /** + * @covers Symfony\Component\DependencyInjection\Definition::setAbstract + * @covers Symfony\Component\DependencyInjection\Definition::isAbstract + */ + public function testSetIsAbstract() + { + $def = new Definition('stdClass'); + $this->assertFalse($def->isAbstract(), '->isAbstract() returns false by default'); + $this->assertSame($def, $def->setAbstract(true), '->setAbstract() implements a fluent interface'); + $this->assertTrue($def->isAbstract(), '->isAbstract() returns true if the instance must not be public.'); + } + + /** + * @covers Symfony\Component\DependencyInjection\Definition::setConfigurator + * @covers Symfony\Component\DependencyInjection\Definition::getConfigurator + */ + public function testSetGetConfigurator() + { + $def = new Definition('stdClass'); + $this->assertSame($def, $def->setConfigurator('foo'), '->setConfigurator() implements a fluent interface'); + $this->assertEquals('foo', $def->getConfigurator(), '->getConfigurator() returns the configurator'); + } + + /** + * @covers Symfony\Component\DependencyInjection\Definition::clearTags + */ + public function testClearTags() + { + $def = new Definition('stdClass'); + $this->assertSame($def, $def->clearTags(), '->clearTags() implements a fluent interface'); + $def->addTag('foo', array('foo' => 'bar')); + $def->clearTags(); + $this->assertEquals(array(), $def->getTags(), '->clearTags() removes all current tags'); + } + + /** + * @covers Symfony\Component\DependencyInjection\Definition::clearTags + */ + public function testClearTag() + { + $def = new Definition('stdClass'); + $this->assertSame($def, $def->clearTags(), '->clearTags() implements a fluent interface'); + $def->addTag('1foo1', array('foo1' => 'bar1')); + $def->addTag('2foo2', array('foo2' => 'bar2')); + $def->addTag('3foo3', array('foo3' => 'bar3')); + $def->clearTag('2foo2'); + $this->assertTrue($def->hasTag('1foo1')); + $this->assertFalse($def->hasTag('2foo2')); + $this->assertTrue($def->hasTag('3foo3')); + $def->clearTag('1foo1'); + $this->assertFalse($def->hasTag('1foo1')); + $this->assertTrue($def->hasTag('3foo3')); + } + + /** + * @covers Symfony\Component\DependencyInjection\Definition::addTag + * @covers Symfony\Component\DependencyInjection\Definition::getTag + * @covers Symfony\Component\DependencyInjection\Definition::getTags + * @covers Symfony\Component\DependencyInjection\Definition::hasTag + */ + public function testTags() + { + $def = new Definition('stdClass'); + $this->assertEquals(array(), $def->getTag('foo'), '->getTag() returns an empty array if the tag is not defined'); + $this->assertFalse($def->hasTag('foo')); + $this->assertSame($def, $def->addTag('foo'), '->addTag() implements a fluent interface'); + $this->assertTrue($def->hasTag('foo')); + $this->assertEquals(array(array()), $def->getTag('foo'), '->getTag() returns attributes for a tag name'); + $def->addTag('foo', array('foo' => 'bar')); + $this->assertEquals(array(array(), array('foo' => 'bar')), $def->getTag('foo'), '->addTag() can adds the same tag several times'); + $def->addTag('bar', array('bar' => 'bar')); + $this->assertEquals($def->getTags(), array( + 'foo' => array(array(), array('foo' => 'bar')), + 'bar' => array(array('bar' => 'bar')), + ), '->getTags() returns all tags'); + } + + /** + * @covers Symfony\Component\DependencyInjection\Definition::replaceArgument + */ + public function testSetArgument() + { + $def = new Definition('stdClass'); + + $def->addArgument('foo'); + $this->assertSame(array('foo'), $def->getArguments()); + + $this->assertSame($def, $def->replaceArgument(0, 'moo')); + $this->assertSame(array('moo'), $def->getArguments()); + + $def->addArgument('moo'); + $def + ->replaceArgument(0, 'foo') + ->replaceArgument(1, 'bar') + ; + $this->assertSame(array('foo', 'bar'), $def->getArguments()); + } + + /** + * @expectedException OutOfBoundsException + */ + public function testGetArgumentShouldCheckBounds() + { + $def = new Definition('stdClass'); + + $def->addArgument('foo'); + $def->getArgument(1); + } + + /** + * @expectedException OutOfBoundsException + */ + public function testReplaceArgumentShouldCheckBounds() + { + $def = new Definition('stdClass'); + + $def->addArgument('foo'); + $def->replaceArgument(1, 'bar'); + } + + public function testSetGetProperties() + { + $def = new Definition('stdClass'); + + $this->assertEquals(array(), $def->getProperties()); + $this->assertSame($def, $def->setProperties(array('foo' => 'bar'))); + $this->assertEquals(array('foo' => 'bar'), $def->getProperties()); + } + + public function testSetProperty() + { + $def = new Definition('stdClass'); + + $this->assertEquals(array(), $def->getProperties()); + $this->assertSame($def, $def->setProperty('foo', 'bar')); + $this->assertEquals(array('foo' => 'bar'), $def->getProperties()); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Dumper/GraphvizDumperTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Dumper/GraphvizDumperTest.php new file mode 100644 index 0000000..69e775d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Dumper/GraphvizDumperTest.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\DependencyInjection\Tests\Dumper; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Dumper\GraphvizDumper; + +class GraphvizDumperTest extends \PHPUnit_Framework_TestCase +{ + static protected $fixturesPath; + + protected function setUp() + { + if (!class_exists('Symfony\Component\Config\Loader\Loader')) { + $this->markTestSkipped('The "Config" component is not available'); + } + } + + static public function setUpBeforeClass() + { + self::$fixturesPath = __DIR__.'/../Fixtures/'; + } + + public function testDump() + { + $dumper = new GraphvizDumper($container = new ContainerBuilder()); + + $this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services1.dot', $dumper->dump(), '->dump() dumps an empty container as an empty dot file'); + + $container = include self::$fixturesPath.'/containers/container9.php'; + $dumper = new GraphvizDumper($container); + $this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services9.dot')), $dumper->dump(), '->dump() dumps services'); + + $container = include self::$fixturesPath.'/containers/container10.php'; + $dumper = new GraphvizDumper($container); + $this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services10.dot')), $dumper->dump(), '->dump() dumps services'); + + $container = include self::$fixturesPath.'/containers/container10.php'; + $dumper = new GraphvizDumper($container); + $this->assertEquals($dumper->dump(array( + 'graph' => array('ratio' => 'normal'), + 'node' => array('fontsize' => 13, 'fontname' => 'Verdana', 'shape' => 'square'), + 'edge' => array('fontsize' => 12, 'fontname' => 'Verdana', 'color' => 'white', 'arrowhead' => 'closed', 'arrowsize' => 1), + 'node.instance' => array('fillcolor' => 'green', 'style' => 'empty'), + 'node.definition' => array('fillcolor' => 'grey'), + 'node.missing' => array('fillcolor' => 'red', 'style' => 'empty'), + )), str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services10-1.dot')), '->dump() dumps services'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php new file mode 100644 index 0000000..a072356 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.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\DependencyInjection\Tests\Dumper; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Dumper\PhpDumper; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Definition; + +class PhpDumperTest extends \PHPUnit_Framework_TestCase +{ + static protected $fixturesPath; + + protected function setUp() + { + if (!class_exists('Symfony\Component\Config\Loader\Loader')) { + $this->markTestSkipped('The "Config" component is not available'); + } + } + + static public function setUpBeforeClass() + { + self::$fixturesPath = realpath(__DIR__.'/../Fixtures/'); + } + + public function testDump() + { + $dumper = new PhpDumper($container = new ContainerBuilder()); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services1.php', $dumper->dump(), '->dump() dumps an empty container as an empty PHP class'); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services1-1.php', $dumper->dump(array('class' => 'Container', 'base_class' => 'AbstractContainer')), '->dump() takes a class and a base_class options'); + + $container = new ContainerBuilder(); + new PhpDumper($container); + } + + public function testDumpOptimizationString() + { + $definition = new Definition(); + $definition->setClass('stdClass'); + $definition->addArgument(array( + 'only dot' => '.', + 'concatenation as value' => '.\'\'.', + 'concatenation from the start value' => '\'\'.', + '.' => 'dot as a key', + '.\'\'.' => 'concatenation as a key', + '\'\'.' =>'concatenation from the start key', + 'optimize concatenation' => "string1%some_string%string2", + 'optimize concatenation with empty string' => "string1%empty_value%string2", + 'optimize concatenation from the start' => '%empty_value%start', + 'optimize concatenation at the end' => 'end%empty_value%', + )); + + $container = new ContainerBuilder(); + $container->setDefinition('test', $definition); + $container->setParameter('empty_value', ''); + $container->setParameter('some_string', '-'); + $container->compile(); + + $dumper = new PhpDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services10.php', $dumper->dump(), '->dump() dumps an empty container as an empty PHP class'); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testExportParameters() + { + $dumper = new PhpDumper(new ContainerBuilder(new ParameterBag(array('foo' => new Reference('foo'))))); + $dumper->dump(); + } + + public function testAddParameters() + { + $container = include self::$fixturesPath.'/containers/container8.php'; + $dumper = new PhpDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services8.php', $dumper->dump(), '->dump() dumps parameters'); + } + + public function testAddService() + { + $container = include self::$fixturesPath.'/containers/container9.php'; + $dumper = new PhpDumper($container); + $this->assertEquals(str_replace('%path%', str_replace('\\','\\\\',self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), file_get_contents(self::$fixturesPath.'/php/services9.php')), $dumper->dump(), '->dump() dumps services'); + + $dumper = new PhpDumper($container = new ContainerBuilder()); + $container->register('foo', 'FooClass')->addArgument(new \stdClass()); + try { + $dumper->dump(); + $this->fail('->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Symfony\Component\DependencyInjection\Exception\RuntimeException', $e, '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources'); + $this->assertEquals('Unable to dump a service container if a parameter is an object or a resource.', $e->getMessage(), '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources'); + } + } + + public function testOverrideServiceWhenUsingADumpedContainer() + { + require_once self::$fixturesPath.'/php/services9.php'; + require_once self::$fixturesPath.'/includes/foo.php'; + + $container = new \ProjectServiceContainer(); + $container->set('bar', $bar = new \stdClass()); + $container->setParameter('foo_bar', 'foo_bar'); + + $this->assertEquals($bar, $container->get('bar'), '->set() overrides an already defined service'); + } + + public function testOverrideServiceWhenUsingADumpedContainerAndServiceIsUsedFromAnotherOne() + { + require_once self::$fixturesPath.'/php/services9.php'; + require_once self::$fixturesPath.'/includes/foo.php'; + require_once self::$fixturesPath.'/includes/classes.php'; + + $container = new \ProjectServiceContainer(); + $container->set('bar', $bar = new \stdClass()); + + $this->assertSame($bar, $container->get('foo')->bar, '->set() overrides an already defined service'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Dumper/XmlDumperTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Dumper/XmlDumperTest.php new file mode 100644 index 0000000..6618982 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Dumper/XmlDumperTest.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\DependencyInjection\Tests\Dumper; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Dumper\XmlDumper; + +class XmlDumperTest extends \PHPUnit_Framework_TestCase +{ + static protected $fixturesPath; + + protected function setUp() + { + if (!class_exists('Symfony\Component\Config\Loader\Loader')) { + $this->markTestSkipped('The "Config" component is not available'); + } + } + + static public function setUpBeforeClass() + { + self::$fixturesPath = realpath(__DIR__.'/../Fixtures/'); + } + + public function testDump() + { + $dumper = new XmlDumper($container = new ContainerBuilder()); + + $this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/xml/services1.xml', $dumper->dump(), '->dump() dumps an empty container as an empty XML file'); + + $container = new ContainerBuilder(); + $dumper = new XmlDumper($container); + } + + public function testExportParameters() + { + $container = include self::$fixturesPath.'//containers/container8.php'; + $dumper = new XmlDumper($container); + $this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/xml/services8.xml', $dumper->dump(), '->dump() dumps parameters'); + } + + public function testAddParameters() + { + $container = include self::$fixturesPath.'//containers/container8.php'; + $dumper = new XmlDumper($container); + $this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/xml/services8.xml', $dumper->dump(), '->dump() dumps parameters'); + } + + public function testAddService() + { + $container = include self::$fixturesPath.'/containers/container9.php'; + $dumper = new XmlDumper($container); + $this->assertEquals(str_replace('%path%', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR, file_get_contents(self::$fixturesPath.'/xml/services9.xml')), $dumper->dump(), '->dump() dumps services'); + + $dumper = new XmlDumper($container = new ContainerBuilder()); + $container->register('foo', 'FooClass')->addArgument(new \stdClass()); + try { + $dumper->dump(); + $this->fail('->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources'); + } catch (\Exception $e) { + $this->assertInstanceOf('\RuntimeException', $e, '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources'); + $this->assertEquals('Unable to dump a service container if a parameter is an object or a resource.', $e->getMessage(), '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources'); + } + } + + public function testDumpAnonymousServices() + { + include self::$fixturesPath.'/containers/container11.php'; + $dumper = new XmlDumper($container); + $this->assertEquals(" + + + + + + + + + + + + + +", $dumper->dump()); + } + + public function testDumpEntities() + { + include self::$fixturesPath.'/containers/container12.php'; + $dumper = new XmlDumper($container); + $this->assertEquals(" + + + + + foo<>&bar + + + +", $dumper->dump()); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php new file mode 100644 index 0000000..2dcb3b8 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.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\DependencyInjection\Tests\Dumper; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Dumper\YamlDumper; + +class YamlDumperTest extends \PHPUnit_Framework_TestCase +{ + static protected $fixturesPath; + + protected function setUp() + { + if (!class_exists('Symfony\Component\Config\Loader\Loader')) { + $this->markTestSkipped('The "Config" component is not available'); + } + } + + static public function setUpBeforeClass() + { + self::$fixturesPath = realpath(__DIR__.'/../Fixtures/'); + } + + public function testDump() + { + $dumper = new YamlDumper($container = new ContainerBuilder()); + + $this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services1.yml', $dumper->dump(), '->dump() dumps an empty container as an empty YAML file'); + + $container = new ContainerBuilder(); + $dumper = new YamlDumper($container); + } + + public function testAddParameters() + { + $container = include self::$fixturesPath.'/containers/container8.php'; + $dumper = new YamlDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services8.yml', $dumper->dump(), '->dump() dumps parameters'); + } + + public function testAddService() + { + $container = include self::$fixturesPath.'/containers/container9.php'; + $dumper = new YamlDumper($container); + $this->assertEquals(str_replace('%path%', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR, file_get_contents(self::$fixturesPath.'/yaml/services9.yml')), $dumper->dump(), '->dump() dumps services'); + + $dumper = new YamlDumper($container = new ContainerBuilder()); + $container->register('foo', 'FooClass')->addArgument(new \stdClass()); + try { + $dumper->dump(); + $this->fail('->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources'); + } catch (\Exception $e) { + $this->assertInstanceOf('\RuntimeException', $e, '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources'); + $this->assertEquals('Unable to dump a service container if a parameter is an object or a resource.', $e->getMessage(), '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources'); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container10.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container10.php new file mode 100644 index 0000000..a16ca9f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container10.php @@ -0,0 +1,14 @@ + + register('foo', 'FooClass')-> + addArgument(new Reference('bar')) +; + +return $container; diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container11.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container11.php new file mode 100644 index 0000000..3e6cafc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container11.php @@ -0,0 +1,12 @@ + + register('foo', 'FooClass')-> + addArgument(new Definition('BarClass', array(new Definition('BazClass')))) +; + +return $container; diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container12.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container12.php new file mode 100644 index 0000000..0dc8679 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container12.php @@ -0,0 +1,13 @@ + + register('foo', 'FooClass\\Foo')-> + addArgument('foo<>&bar')-> + addTag('foo"bar\\bar', array('foo' => 'foo"barřž€')) +; + +return $container; diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container8.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container8.php new file mode 100644 index 0000000..28c6536 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container8.php @@ -0,0 +1,13 @@ + '%baz%', + 'baz' => 'bar', + 'bar' => 'foo is %%foo bar', + 'values' => array(true, false, null, 0, 1000.3, 'true', 'false', 'null'), +))); + +return $container; diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php new file mode 100644 index 0000000..663f2a7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php @@ -0,0 +1,58 @@ + + register('foo', 'FooClass')-> + addTag('foo', array('foo' => 'foo'))-> + addTag('foo', array('bar' => 'bar'))-> + setFactoryClass('FooClass')-> + setFactoryMethod('getInstance')-> + setArguments(array('foo', new Reference('foo.baz'), array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, new Reference('service_container')))-> + setProperties(array('foo' => 'bar', 'moo' => new Reference('foo.baz')))-> + setScope('prototype')-> + addMethodCall('setBar', array(new Reference('bar')))-> + addMethodCall('initialize')-> + setConfigurator('sc_configure') +; +$container-> + register('bar', 'FooClass')-> + setArguments(array('foo', new Reference('foo.baz'), new Parameter('foo_bar')))-> + setScope('container')-> + setConfigurator(array(new Reference('foo.baz'), 'configure')) +; +$container-> + register('foo.baz', '%baz_class%')-> + setFactoryClass('%baz_class%')-> + setFactoryMethod('getInstance')-> + setConfigurator(array('%baz_class%', 'configureStatic1')) +; +$container->register('foo_bar', '%foo_class%'); +$container->getParameterBag()->clear(); +$container->getParameterBag()->add(array( + 'baz_class' => 'BazClass', + 'foo_class' => 'FooClass', + 'foo' => 'bar', +)); +$container->setAlias('alias_for_foo', 'foo'); +$container-> + register('method_call1', 'FooClass')-> + setFile(realpath(__DIR__.'/../includes/foo.php'))-> + addMethodCall('setBar', array(new Reference('foo')))-> + addMethodCall('setBar', array(new Reference('foo2', ContainerInterface::NULL_ON_INVALID_REFERENCE)))-> + addMethodCall('setBar', array(new Reference('foo3', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)))-> + addMethodCall('setBar', array(new Reference('foobaz', ContainerInterface::IGNORE_ON_INVALID_REFERENCE))) +; +$container-> + register('factory_service')-> + setFactoryService('foo.baz')-> + setFactoryMethod('getInstance') +; + +return $container; diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/interfaces1.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/interfaces1.php new file mode 100644 index 0000000..27503a3 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/interfaces1.php @@ -0,0 +1,25 @@ +setParameter('cla', 'Fo'); +$container->setParameter('ss', 'Class'); + +$definition = new Definition('%cla%o%ss%'); +$container->setDefinition('foo', $definition); + +return $container; + +if (!class_exists('FooClass')) { + class FooClass + { + public $bar; + + public function setBar($bar) + { + $this->bar = $bar; + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/interfaces2.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/interfaces2.php new file mode 100644 index 0000000..a851901 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/interfaces2.php @@ -0,0 +1,34 @@ +setDefinition('barFactory', $factoryDefinition); + +$definition = new Definition(); +$definition->setFactoryService('barFactory'); +$definition->setFactoryMethod('createBarClass'); +$container->setDefinition('bar', $definition); + +return $container; + +class BarClass +{ + public $foo; + + public function setBar($foo) + { + $this->foo = $foo; + } +} + +class BarClassFactory +{ + public function createBarClass() + { + return new BarClass(); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services1.dot b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services1.dot new file mode 100644 index 0000000..1bb7c30 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services1.dot @@ -0,0 +1,7 @@ +digraph sc { + ratio="compress" + node [fontsize="11" fontname="Arial" shape="record"]; + edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"]; + + node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"]; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services10-1.dot b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services10-1.dot new file mode 100644 index 0000000..0e578b1 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services10-1.dot @@ -0,0 +1,10 @@ +digraph sc { + ratio="normal" + node [fontsize="13" fontname="Verdana" shape="square"]; + edge [fontsize="12" fontname="Verdana" color="white" arrowhead="closed" arrowsize="1"]; + + node_foo [label="foo\nFooClass\n", shape=square, fillcolor="grey", style="filled"]; + node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=square, fillcolor="green", style="empty"]; + node_bar [label="bar\n\n", shape=square, fillcolor="red", style="empty"]; + node_foo -> node_bar [label="" style="filled"]; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services10.dot b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services10.dot new file mode 100644 index 0000000..f17857f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services10.dot @@ -0,0 +1,10 @@ +digraph sc { + ratio="compress" + node [fontsize="11" fontname="Arial" shape="record"]; + edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"]; + + node_foo [label="foo\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"]; + node_bar [label="bar\n\n", shape=record, fillcolor="#ff9999", style="filled"]; + node_foo -> node_bar [label="" style="filled"]; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot new file mode 100644 index 0000000..fdff221 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot @@ -0,0 +1,25 @@ +digraph sc { + ratio="compress" + node [fontsize="11" fontname="Arial" shape="record"]; + edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"]; + + node_foo [label="foo (alias_for_foo)\nFooClass\n", shape=record, fillcolor="#eeeeee", style="dotted"]; + node_bar [label="bar\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_foo_baz [label="foo.baz\nBazClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_foo_bar [label="foo_bar\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_method_call1 [label="method_call1\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_factory_service [label="factory_service\n\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"]; + node_foo2 [label="foo2\n\n", shape=record, fillcolor="#ff9999", style="filled"]; + node_foo3 [label="foo3\n\n", shape=record, fillcolor="#ff9999", style="filled"]; + node_foobaz [label="foobaz\n\n", shape=record, fillcolor="#ff9999", style="filled"]; + node_foo -> node_foo_baz [label="" style="filled"]; + node_foo -> node_service_container [label="" style="filled"]; + node_foo -> node_foo_baz [label="" style="dashed"]; + node_foo -> node_bar [label="setBar()" style="dashed"]; + node_bar -> node_foo_baz [label="" style="filled"]; + node_method_call1 -> node_foo [label="setBar()" style="dashed"]; + node_method_call1 -> node_foo2 [label="setBar()" style="dashed"]; + node_method_call1 -> node_foo3 [label="setBar()" style="dashed"]; + node_method_call1 -> node_foobaz [label="setBar()" style="dashed"]; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/ProjectExtension.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/ProjectExtension.php new file mode 100644 index 0000000..81ff7aa --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/ProjectExtension.php @@ -0,0 +1,41 @@ +setDefinition('project.service.bar', new Definition('FooClass')); + $configuration->setParameter('project.parameter.bar', isset($config['foo']) ? $config['foo'] : 'foobar'); + + $configuration->setDefinition('project.service.foo', new Definition('FooClass')); + $configuration->setParameter('project.parameter.foo', isset($config['foo']) ? $config['foo'] : 'foobar'); + + return $configuration; + } + + public function getXsdValidationBasePath() + { + return false; + } + + public function getNamespace() + { + return 'http://www.example.com/schema/project'; + } + + public function getAlias() + { + return 'project'; + } + + public function getConfiguration(array $config, ContainerBuilder $container) + { + return null; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/ProjectWithXsdExtension.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/ProjectWithXsdExtension.php new file mode 100644 index 0000000..2ee2f12 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/ProjectWithXsdExtension.php @@ -0,0 +1,19 @@ +A# zLP8n`gt&9#ui!7>hB(4=l2+ZJTe0LgvcK=W=kI&2?+9NI3CC$5!Hu~GgbJU@s^j!z z{1QBM7%2ZJ8MdYhcoM|C&3kxmYtW?-L2JZy@9%c{?%jvoUc1veSTEPe&bDQq8isKN z=QW&b2F35?`4D8>SOF>Ctr^B&_NuGb-{jBPS6ubDjx+Imh?pbt+ih;y6?>WtzZDF< zJ`$&2W{kSl$1*L`3t5to3u`2xH5$%QbIC08tz{A%A{~T*M@A|46iP|PpitVUEDVNB zZ!}o~J*NEia*i)(nkqr1lB1e??E}}fOHO`|QY}ZG=o*)#c)%h^1oL2d*pjc5K+h+W zi49X0i4bfrj*28Ru_o9Gs8ztV`Kx5!4Fi^3khL&jS=^KQ&NK?iYmmC}8Wg>v1h^Mt z3F8KR(%;{_L$hwO%sLiU%{3uN;z@)4|D9;AVaBgwz;iJsx9nJsotu@)mUGnYJkI*4 zU??Wh%em0!cq{5zM1l|^;A%gX(H@Lg8mb08PO(Eq0SqZV99?2|*#b#8+S{N5CMi*G z#O&8ugrb$`=(LZ=3vfi}j>&>CrDQNj)$Du}$Fp#muz1SHl<26)aP;0nP~6S;as##x fKmGdn{Kwgc7w>OxY?QCIKL337T|f4F&2IA_UuA6u literal 0 HcmV?d00001 diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php new file mode 100644 index 0000000..3c27376 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php @@ -0,0 +1,42 @@ +configure(); +} + +class BarClass +{ +} + +class BazClass +{ + public function configure($instance) + { + $instance->configure(); + } + + static public function getInstance() + { + return new self(); + } + + static public function configureStatic($instance) + { + $instance->configure(); + } + + static public function configureStatic1() + { + } +} + +class BarUserClass +{ + public $bar; + + public function __construct(BarClass $bar) + { + $this->bar = $bar; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/createphar.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/createphar.php new file mode 100644 index 0000000..a593351 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/createphar.php @@ -0,0 +1,47 @@ +addFromString('ProjectWithXsdExtensionInPhar.php',<<addFromString('schema/project-1.0.xsd', << + + + + + + + + + +EOT +); +$phar->setStub(''); diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/foo.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/foo.php new file mode 100644 index 0000000..2c53122 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/foo.php @@ -0,0 +1,36 @@ +arguments = $arguments; + } + + static public function getInstance($arguments = array()) + { + $obj = new self($arguments); + $obj->called = true; + + return $obj; + } + + public function initialize() + { + $this->initialized = true; + } + + public function configure() + { + $this->configured = true; + } + + public function setBar($value = null) + { + $this->bar = $value; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/schema/project-1.0.xsd b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/schema/project-1.0.xsd new file mode 100644 index 0000000..282884e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/schema/project-1.0.xsd @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ini/nonvalid.ini b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ini/nonvalid.ini new file mode 100644 index 0000000..9f84a60 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ini/nonvalid.ini @@ -0,0 +1,2 @@ +{NOT AN INI FILE} +{JUST A PLAIN TEXT FILE} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ini/parameters.ini b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ini/parameters.ini new file mode 100644 index 0000000..df92f75 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ini/parameters.ini @@ -0,0 +1,3 @@ +[parameters] + foo = bar + bar = %foo% diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ini/parameters1.ini b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ini/parameters1.ini new file mode 100644 index 0000000..e50f722 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ini/parameters1.ini @@ -0,0 +1,3 @@ +[parameters] + FOO = foo + baz = baz diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ini/parameters2.ini b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ini/parameters2.ini new file mode 100644 index 0000000..75fbac6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ini/parameters2.ini @@ -0,0 +1,2 @@ +[parameters] + imported_from_ini = true diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php new file mode 100644 index 0000000..de4b642 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php @@ -0,0 +1,28 @@ +parameters = $this->getDefaultParameters(); + + $this->services = + $this->scopedServices = + $this->scopeStacks = array(); + + $this->set('service_container', $this); + + $this->scopes = array(); + $this->scopeChildren = array(); + } + + /** + * Gets the 'test' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return stdClass A stdClass instance. + */ + protected function getTestService() + { + return $this->services['test'] = new \stdClass(array('only dot' => '.', 'concatenation as value' => '.\'\'.', 'concatenation from the start value' => '\'\'.', '.' => 'dot as a key', '.\'\'.' => 'concatenation as a key', '\'\'.' => 'concatenation from the start key', 'optimize concatenation' => 'string1-string2', 'optimize concatenation with empty string' => 'string1string2', 'optimize concatenation from the start' => 'start', 'optimize concatenation at the end' => 'end')); + } + + /** + * {@inheritdoc} + */ + public function getParameter($name) + { + $name = strtolower($name); + + if (!array_key_exists($name, $this->parameters)) { + throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name)); + } + + return $this->parameters[$name]; + } + + /** + * {@inheritdoc} + */ + public function hasParameter($name) + { + return array_key_exists(strtolower($name), $this->parameters); + } + + /** + * {@inheritdoc} + */ + public function setParameter($name, $value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + /** + * {@inheritDoc} + */ + public function getParameterBag() + { + if (null === $this->parameterBag) { + $this->parameterBag = new FrozenParameterBag($this->parameters); + } + + return $this->parameterBag; + } + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return array( + 'empty_value' => '', + 'some_string' => '-', + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services8.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services8.php new file mode 100644 index 0000000..77e4183 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services8.php @@ -0,0 +1,52 @@ +getDefaultParameters())); + } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return array( + 'foo' => '%baz%', + 'baz' => 'bar', + 'bar' => 'foo is %%foo bar', + 'values' => array( + 0 => true, + 1 => false, + 2 => NULL, + 3 => 0, + 4 => 1000.3, + 5 => 'true', + 6 => 'false', + 7 => 'null', + ), + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php new file mode 100644 index 0000000..c1513b6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php @@ -0,0 +1,160 @@ +getDefaultParameters())); + } + + /** + * Gets the 'bar' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return FooClass A FooClass instance. + */ + protected function getBarService() + { + $this->services['bar'] = $instance = new \FooClass('foo', $this->get('foo.baz'), $this->getParameter('foo_bar')); + + $this->get('foo.baz')->configure($instance); + + return $instance; + } + + /** + * Gets the 'factory_service' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return Object An instance returned by foo.baz::getInstance(). + */ + protected function getFactoryServiceService() + { + return $this->services['factory_service'] = $this->get('foo.baz')->getInstance(); + } + + /** + * Gets the 'foo' service. + * + * @return FooClass A FooClass instance. + */ + protected function getFooService() + { + $a = $this->get('foo.baz'); + + $instance = call_user_func(array('FooClass', 'getInstance'), 'foo', $a, array($this->getParameter('foo') => 'foo is '.$this->getParameter('foo'), 'bar' => $this->getParameter('foo')), true, $this); + + $instance->setBar($this->get('bar')); + $instance->initialize(); + $instance->foo = 'bar'; + $instance->moo = $a; + sc_configure($instance); + + return $instance; + } + + /** + * Gets the 'foo.baz' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return Object A %baz_class% instance. + */ + protected function getFoo_BazService() + { + $this->services['foo.baz'] = $instance = call_user_func(array($this->getParameter('baz_class'), 'getInstance')); + + call_user_func(array($this->getParameter('baz_class'), 'configureStatic1'), $instance); + + return $instance; + } + + /** + * Gets the 'foo_bar' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return Object A %foo_class% instance. + */ + protected function getFooBarService() + { + $class = $this->getParameter('foo_class'); + + return $this->services['foo_bar'] = new $class(); + } + + /** + * Gets the 'method_call1' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return FooClass A FooClass instance. + */ + protected function getMethodCall1Service() + { + require_once '%path%foo.php'; + + $this->services['method_call1'] = $instance = new \FooClass(); + + $instance->setBar($this->get('foo')); + $instance->setBar($this->get('foo2', ContainerInterface::NULL_ON_INVALID_REFERENCE)); + if ($this->has('foo3')) { + $instance->setBar($this->get('foo3', ContainerInterface::NULL_ON_INVALID_REFERENCE)); + } + if ($this->has('foobaz')) { + $instance->setBar($this->get('foobaz', ContainerInterface::NULL_ON_INVALID_REFERENCE)); + } + + return $instance; + } + + /** + * Gets the alias_for_foo service alias. + * + * @return FooClass An instance of the foo service + */ + protected function getAliasForFooService() + { + return $this->get('foo'); + } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return array( + 'baz_class' => 'BazClass', + 'foo_class' => 'FooClass', + 'foo' => 'bar', + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/simple.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/simple.php new file mode 100644 index 0000000..aa4df99 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/simple.php @@ -0,0 +1,3 @@ +setParameter('foo', 'foo'); diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extension1/services.xml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extension1/services.xml new file mode 100644 index 0000000..52df38d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extension1/services.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extension2/services.xml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extension2/services.xml new file mode 100644 index 0000000..21a7ef5 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extension2/services.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services1.xml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services1.xml new file mode 100644 index 0000000..792fa07 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services1.xml @@ -0,0 +1,19 @@ + + + + + + BAR + + + + + + + + + %project.parameter.foo% + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services2.xml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services2.xml new file mode 100644 index 0000000..67d462b --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services2.xml @@ -0,0 +1,19 @@ + + + + + + BAR + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services3.xml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services3.xml new file mode 100644 index 0000000..c23f02a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services3.xml @@ -0,0 +1,19 @@ + + + + + + BAR + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services4.xml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services4.xml new file mode 100644 index 0000000..2c33c3a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services4.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services5.xml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services5.xml new file mode 100644 index 0000000..0eaaff2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services5.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services6.xml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services6.xml new file mode 100644 index 0000000..a9c0103 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services6.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services7.xml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services7.xml new file mode 100644 index 0000000..e77780d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/extensions/services7.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/nonvalid.xml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/nonvalid.xml new file mode 100644 index 0000000..e7b5bc9 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/nonvalid.xml @@ -0,0 +1,3 @@ + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services1.xml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services1.xml new file mode 100644 index 0000000..6aa5732 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services1.xml @@ -0,0 +1,2 @@ + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services13.xml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services13.xml new file mode 100644 index 0000000..1ac4938 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services13.xml @@ -0,0 +1,9 @@ + + + + + true + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services2.xml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services2.xml new file mode 100644 index 0000000..bada1c8 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services2.xml @@ -0,0 +1,31 @@ + + + + + a string + bar + + 0 + 4 + null + true + true + false + on + off + 1.3 + 1,000.3 + a string + + foo + bar + + + + + value + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services3.xml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services3.xml new file mode 100644 index 0000000..87bf183 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services3.xml @@ -0,0 +1,13 @@ + + + + + foo + + true + false + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services4.xml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services4.xml new file mode 100644 index 0000000..03ad9f8 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services4_bad_import.xml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services4_bad_import.xml new file mode 100644 index 0000000..0b7f10a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services4_bad_import.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services5.xml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services5.xml new file mode 100644 index 0000000..acb93e7 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services5.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services6.xml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services6.xml new file mode 100644 index 0000000..45bc042 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services6.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + %path%/foo.php + + + foo + + + true + false + + + + + + + + + + + + + + + + + foo + + + true + false + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services7.xml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services7.xml new file mode 100644 index 0000000..824d8b5 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services7.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services8.xml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services8.xml new file mode 100644 index 0000000..f11d606 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services8.xml @@ -0,0 +1,21 @@ + + + + + %baz% + bar + foo is %%foo bar + + true + false + null + 0 + 1000.3 + true + false + null + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml new file mode 100644 index 0000000..a73fb3e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml @@ -0,0 +1,56 @@ + + + + BazClass + FooClass + bar + + + + + + foo + + + foo is %foo% + %foo% + + true + + bar + + + + + + + + + foo + + %foo_bar% + + + + + + + + %path%foo.php + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/badtag1.yml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/badtag1.yml new file mode 100644 index 0000000..14536fd --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/badtag1.yml @@ -0,0 +1,5 @@ +services: + foo_service: + class: FooClass + # tags is not an array + tags: string diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/badtag2.yml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/badtag2.yml new file mode 100644 index 0000000..9028814 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/badtag2.yml @@ -0,0 +1,6 @@ +services: + foo_service: + class: FooClass + tags: + # tag is missing the name key + foo_tag: { foo: bar } diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/badtag3.yml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/badtag3.yml new file mode 100644 index 0000000..8137fab --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/badtag3.yml @@ -0,0 +1,6 @@ +services: + foo_service: + class: FooClass + tags: + # tag-attribute is not a scalar + - { name: foo, foo: { foo: foo, bar: bar } } diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/nonvalid1.yml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/nonvalid1.yml new file mode 100644 index 0000000..4eddb87 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/nonvalid1.yml @@ -0,0 +1,2 @@ +foo: + bar diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/nonvalid2.yml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/nonvalid2.yml new file mode 100644 index 0000000..c508d53 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/nonvalid2.yml @@ -0,0 +1 @@ +false diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services1.yml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services1.yml new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services1.yml @@ -0,0 +1 @@ + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services10.yml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services10.yml new file mode 100644 index 0000000..f2f8d95 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services10.yml @@ -0,0 +1,9 @@ +parameters: + project.parameter.foo: BAR + +services: + project.service.foo: + class: BAR + +project: + test: %project.parameter.foo% diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services11.yml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services11.yml new file mode 100644 index 0000000..40126f0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services11.yml @@ -0,0 +1 @@ +foobarfoobar: {} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services13.yml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services13.yml new file mode 100644 index 0000000..d52d355 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services13.yml @@ -0,0 +1,3 @@ +# used to test imports in XML +parameters: + imported_from_yaml: true diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services2.yml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services2.yml new file mode 100644 index 0000000..8ddfe0d --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services2.yml @@ -0,0 +1,11 @@ +parameters: + FOO: bar + values: + - true + - false + - 0 + - 1000.3 + bar: foo + foo_bar: @foo_bar + MixedCase: + MixedCaseKey: value diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services3.yml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services3.yml new file mode 100644 index 0000000..0e92cdf --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services3.yml @@ -0,0 +1,5 @@ +parameters: + foo: foo + values: + - true + - false diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services4.yml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services4.yml new file mode 100644 index 0000000..18f1065 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services4.yml @@ -0,0 +1,6 @@ +imports: + - { resource: services2.yml } + - { resource: services3.yml } + - { resource: "../ini/parameters.ini", class: Symfony\Component\DependencyInjection\Loader\IniFileLoader } + - { resource: "../ini/parameters2.ini" } + - { resource: "../xml/services13.xml" } diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services4_bad_import.yml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services4_bad_import.yml new file mode 100644 index 0000000..f7089fc --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services4_bad_import.yml @@ -0,0 +1,2 @@ +imports: + - { resource: foo_fake.yml, ignore_errors: true } diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services6.yml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services6.yml new file mode 100644 index 0000000..eaa52bd --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services6.yml @@ -0,0 +1,26 @@ +services: + foo: { class: FooClass } + baz: { class: BazClass } + scope.container: { class: FooClass, scope: container } + scope.custom: { class: FooClass, scope: custom } + scope.prototype: { class: FooClass, scope: prototype } + constructor: { class: FooClass, factory_method: getInstance } + file: { class: FooClass, file: %path%/foo.php } + arguments: { class: FooClass, arguments: [foo, @foo, [true, false]] } + configurator1: { class: FooClass, configurator: sc_configure } + configurator2: { class: FooClass, configurator: [@baz, configure] } + configurator3: { class: FooClass, configurator: [BazClass, configureStatic] } + method_call1: + class: FooClass + calls: + - [ setBar, [] ] + - [ setBar ] + method_call2: + class: FooClass + calls: + - [ setBar, [ foo, @foo, [true, false] ] ] + alias_for_foo: @foo + another_alias_for_foo: + alias: foo + public: false + factory_service: { class: BazClass, factory_method: getInstance, factory_service: baz_factory } diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services7.yml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services7.yml new file mode 100644 index 0000000..09064f2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services7.yml @@ -0,0 +1,2 @@ +services: + foo: { class: BarClass } diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services8.yml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services8.yml new file mode 100644 index 0000000..5e74748 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services8.yml @@ -0,0 +1,6 @@ +parameters: + foo: '%baz%' + baz: bar + bar: 'foo is %%foo bar' + values: [true, false, null, 0, 1000.3, 'true', 'false', 'null'] + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml new file mode 100644 index 0000000..0fd2ae3 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml @@ -0,0 +1,43 @@ +parameters: + baz_class: BazClass + foo_class: FooClass + foo: bar + +services: + foo: + class: FooClass + tags: + - { name: foo, foo: foo } + - { name: foo, bar: bar } + factory_method: getInstance + arguments: [foo, '@foo.baz', { '%foo%': 'foo is %foo%', bar: '%foo%' }, true, '@service_container'] + properties: { foo: bar, moo: '@foo.baz' } + calls: + - [setBar, ['@bar']] + - [initialize, { }] + + scope: prototype + configurator: sc_configure + bar: + class: FooClass + arguments: [foo, '@foo.baz', '%foo_bar%'] + configurator: ['@foo.baz', configure] + foo.baz: + class: %baz_class% + factory_method: getInstance + configurator: ['%baz_class%', configureStatic1] + foo_bar: + class: %foo_class% + method_call1: + class: FooClass + file: %path%foo.php + calls: + - [setBar, ['@foo']] + - [setBar, ['@?foo2']] + - [setBar, ['@?foo3']] + - [setBar, ['@?foobaz']] + + factory_service: + factory_method: getInstance + factory_service: foo.baz + alias_for_foo: @foo diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Loader/ClosureLoaderTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Loader/ClosureLoaderTest.php new file mode 100644 index 0000000..33594d6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Loader/ClosureLoaderTest.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\DependencyInjection\Tests\Loader; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\ClosureLoader; + +class ClosureLoaderTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\Config\Loader\Loader')) { + $this->markTestSkipped('The "Config" component is not available'); + } + } + + /** + * @covers Symfony\Component\DependencyInjection\Loader\ClosureLoader::supports + */ + public function testSupports() + { + $loader = new ClosureLoader(new ContainerBuilder()); + + $this->assertTrue($loader->supports(function ($container) {}), '->supports() returns true if the resource is loadable'); + $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable'); + } + + /** + * @covers Symfony\Component\DependencyInjection\Loader\ClosureLoader::load + */ + public function testLoad() + { + $loader = new ClosureLoader($container = new ContainerBuilder()); + + $loader->load(function ($container) { + $container->setParameter('foo', 'foo'); + }); + + $this->assertEquals('foo', $container->getParameter('foo'), '->load() loads a \Closure resource'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Loader/IniFileLoaderTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Loader/IniFileLoaderTest.php new file mode 100644 index 0000000..448934c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Loader/IniFileLoaderTest.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\DependencyInjection\Tests\Loader; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\IniFileLoader; +use Symfony\Component\Config\FileLocator; + +class IniFileLoaderTest extends \PHPUnit_Framework_TestCase +{ + static protected $fixturesPath; + + protected $container; + protected $loader; + + static public function setUpBeforeClass() + { + self::$fixturesPath = realpath(__DIR__.'/../Fixtures/'); + } + + protected function setUp() + { + if (!class_exists('Symfony\Component\Config\Loader\Loader')) { + $this->markTestSkipped('The "Config" component is not available'); + } + + $this->container = new ContainerBuilder(); + $this->loader = new IniFileLoader($this->container, new FileLocator(self::$fixturesPath.'/ini')); + } + + /** + * @covers Symfony\Component\DependencyInjection\Loader\IniFileLoader::__construct + * @covers Symfony\Component\DependencyInjection\Loader\IniFileLoader::load + */ + public function testIniFileCanBeLoaded() + { + $this->loader->load('parameters.ini'); + $this->assertEquals(array('foo' => 'bar', 'bar' => '%foo%'), $this->container->getParameterBag()->all(), '->load() takes a single file name as its first argument'); + } + + /** + * @covers Symfony\Component\DependencyInjection\Loader\IniFileLoader::__construct + * @covers Symfony\Component\DependencyInjection\Loader\IniFileLoader::load + */ + public function testExceptionIsRaisedWhenIniFileDoesNotExist() + { + try { + $this->loader->load('foo.ini'); + $this->fail('->load() throws an InvalidArgumentException if the loaded file does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the loaded file does not exist'); + $this->assertStringStartsWith('The file "foo.ini" does not exist (in: ', $e->getMessage(), '->load() throws an InvalidArgumentException if the loaded file does not exist'); + } + } + + /** + * @covers Symfony\Component\DependencyInjection\Loader\IniFileLoader::__construct + * @covers Symfony\Component\DependencyInjection\Loader\IniFileLoader::load + */ + public function testExceptionIsRaisedWhenIniFileCannotBeParsed() + { + try { + @$this->loader->load('nonvalid.ini'); + $this->fail('->load() throws an InvalidArgumentException if the loaded file is not parseable'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the loaded file is not parseable'); + $this->assertEquals('The "nonvalid.ini" file is not valid.', $e->getMessage(), '->load() throws an InvalidArgumentException if the loaded file is not parseable'); + } + } + + /** + * @covers Symfony\Component\DependencyInjection\Loader\IniFileLoader::supports + */ + public function testSupports() + { + $loader = new IniFileLoader(new ContainerBuilder(), new FileLocator()); + + $this->assertTrue($loader->supports('foo.ini'), '->supports() returns true if the resource is loadable'); + $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Loader/PhpFileLoaderTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Loader/PhpFileLoaderTest.php new file mode 100644 index 0000000..3a97dc2 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Loader/PhpFileLoaderTest.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\DependencyInjection\Tests\Loader; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Config\Loader\Loader; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use Symfony\Component\Config\FileLocator; + +class PhpFileLoaderTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\Config\Loader\Loader')) { + $this->markTestSkipped('The "Config" component is not available'); + } + } + + /** + * @covers Symfony\Component\DependencyInjection\Loader\PhpFileLoader::supports + */ + public function testSupports() + { + $loader = new PhpFileLoader(new ContainerBuilder(), new FileLocator()); + + $this->assertTrue($loader->supports('foo.php'), '->supports() returns true if the resource is loadable'); + $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable'); + } + + /** + * @covers Symfony\Component\DependencyInjection\Loader\PhpFileLoader::load + */ + public function testLoad() + { + $loader = new PhpFileLoader($container = new ContainerBuilder(), new FileLocator()); + + $loader->load(__DIR__.'/../Fixtures/php/simple.php'); + + $this->assertEquals('foo', $container->getParameter('foo'), '->load() loads a PHP file resource'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php new file mode 100644 index 0000000..1a157e6 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.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\DependencyInjection\Tests\Loader; + +use Symfony\Component\DependencyInjection\ContainerInterface; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\Config\Loader\Loader; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\DependencyInjection\Loader\IniFileLoader; +use Symfony\Component\Config\Loader\LoaderResolver; +use Symfony\Component\Config\FileLocator; + +class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase +{ + static protected $fixturesPath; + + protected function setUp() + { + if (!class_exists('Symfony\Component\Config\Loader\Loader')) { + $this->markTestSkipped('The "Config" component is not available'); + } + } + + static public function setUpBeforeClass() + { + self::$fixturesPath = realpath(__DIR__.'/../Fixtures/'); + require_once self::$fixturesPath.'/includes/foo.php'; + require_once self::$fixturesPath.'/includes/ProjectExtension.php'; + require_once self::$fixturesPath.'/includes/ProjectWithXsdExtension.php'; + } + + public function testLoad() + { + $loader = new XmlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/ini')); + + try { + $loader->load('foo.xml'); + $this->fail('->load() throws an InvalidArgumentException if the loaded file does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the loaded file does not exist'); + $this->assertStringStartsWith('The file "foo.xml" does not exist (in:', $e->getMessage(), '->load() throws an InvalidArgumentException if the loaded file does not exist'); + } + } + + public function testParseFile() + { + $loader = new XmlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/ini')); + $r = new \ReflectionObject($loader); + $m = $r->getMethod('parseFile'); + $m->setAccessible(true); + + try { + $m->invoke($loader, self::$fixturesPath.'/ini/parameters.ini'); + $this->fail('->parseFile() throws an InvalidArgumentException if the loaded file is not a valid XML file'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->parseFile() throws an InvalidArgumentException if the loaded file is not a valid XML file'); + $this->assertStringStartsWith('[ERROR 4] Start tag expected, \'<\' not found (in', $e->getMessage(), '->parseFile() throws an InvalidArgumentException if the loaded file is not a valid XML file'); + } + + $loader = new XmlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/xml')); + + try { + $m->invoke($loader, self::$fixturesPath.'/xml/nonvalid.xml'); + $this->fail('->parseFile() throws an InvalidArgumentException if the loaded file does not validate the XSD'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->parseFile() throws an InvalidArgumentException if the loaded file does not validate the XSD'); + $this->assertStringStartsWith('[ERROR 1845] Element \'nonvalid\': No matching global declaration available for the validation root. (in', $e->getMessage(), '->parseFile() throws an InvalidArgumentException if the loaded file does not validate the XSD'); + } + + $xml = $m->invoke($loader, self::$fixturesPath.'/xml/services1.xml'); + $this->assertEquals('Symfony\\Component\\DependencyInjection\\SimpleXMLElement', get_class($xml), '->parseFile() returns an SimpleXMLElement object'); + } + + public function testLoadParameters() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services2.xml'); + + $actual = $container->getParameterBag()->all(); + $expected = array('a string', 'foo' => 'bar', 'values' => array(0, 'integer' => 4, 100 => null, 'true', true, false, 'on', 'off', 'float' => 1.3, 1000.3, 'a string', array('foo', 'bar')), 'foo_bar' => new Reference('foo_bar'), 'mixedcase' => array('MixedCaseKey' => 'value')); + + $this->assertEquals($expected, $actual, '->load() converts XML values to PHP ones'); + } + + public function testLoadImports() + { + $container = new ContainerBuilder(); + $resolver = new LoaderResolver(array( + new IniFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')), + new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')), + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')), + )); + $loader->setResolver($resolver); + $loader->load('services4.xml'); + + $actual = $container->getParameterBag()->all(); + $expected = array('a string', 'foo' => 'bar', 'values' => array(true, false), 'foo_bar' => new Reference('foo_bar'), 'mixedcase' => array('MixedCaseKey' => 'value'), 'bar' => '%foo%', 'imported_from_ini' => true, 'imported_from_yaml' => true); + + $this->assertEquals(array_keys($expected), array_keys($actual), '->load() imports and merges imported files'); + + // Bad import throws no exception due to ignore_errors value. + $loader->load('services4_bad_import.xml'); + } + + public function testLoadAnonymousServices() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services5.xml'); + $services = $container->getDefinitions(); + $this->assertEquals(4, count($services), '->load() attributes unique ids to anonymous services'); + + // anonymous service as an argument + $args = $services['foo']->getArguments(); + $this->assertEquals(1, count($args), '->load() references anonymous services as "normal" ones'); + $this->assertEquals('Symfony\\Component\\DependencyInjection\\Reference', get_class($args[0]), '->load() converts anonymous services to references to "normal" services'); + $this->assertTrue(isset($services[(string) $args[0]]), '->load() makes a reference to the created ones'); + $inner = $services[(string) $args[0]]; + $this->assertEquals('BarClass', $inner->getClass(), '->load() uses the same configuration as for the anonymous ones'); + + // inner anonymous services + $args = $inner->getArguments(); + $this->assertEquals(1, count($args), '->load() references anonymous services as "normal" ones'); + $this->assertEquals('Symfony\\Component\\DependencyInjection\\Reference', get_class($args[0]), '->load() converts anonymous services to references to "normal" services'); + $this->assertTrue(isset($services[(string) $args[0]]), '->load() makes a reference to the created ones'); + $inner = $services[(string) $args[0]]; + $this->assertEquals('BazClass', $inner->getClass(), '->load() uses the same configuration as for the anonymous ones'); + + // anonymous service as a property + $properties = $services['foo']->getProperties(); + $property = $properties['p']; + $this->assertEquals('Symfony\\Component\\DependencyInjection\\Reference', get_class($property), '->load() converts anonymous services to references to "normal" services'); + $this->assertTrue(isset($services[(string) $property]), '->load() makes a reference to the created ones'); + $inner = $services[(string) $property]; + $this->assertEquals('BazClass', $inner->getClass(), '->load() uses the same configuration as for the anonymous ones'); + } + + public function testLoadServices() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services6.xml'); + $services = $container->getDefinitions(); + $this->assertTrue(isset($services['foo']), '->load() parses elements'); + $this->assertEquals('Symfony\\Component\\DependencyInjection\\Definition', get_class($services['foo']), '->load() converts element to Definition instances'); + $this->assertEquals('FooClass', $services['foo']->getClass(), '->load() parses the class attribute'); + $this->assertEquals('container', $services['scope.container']->getScope()); + $this->assertEquals('custom', $services['scope.custom']->getScope()); + $this->assertEquals('prototype', $services['scope.prototype']->getScope()); + $this->assertEquals('getInstance', $services['constructor']->getFactoryMethod(), '->load() parses the factory-method attribute'); + $this->assertEquals('%path%/foo.php', $services['file']->getFile(), '->load() parses the file tag'); + $this->assertEquals(array('foo', new Reference('foo'), array(true, false)), $services['arguments']->getArguments(), '->load() parses the argument tags'); + $this->assertEquals('sc_configure', $services['configurator1']->getConfigurator(), '->load() parses the configurator tag'); + $this->assertEquals(array(new Reference('baz', ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, false), 'configure'), $services['configurator2']->getConfigurator(), '->load() parses the configurator tag'); + $this->assertEquals(array('BazClass', 'configureStatic'), $services['configurator3']->getConfigurator(), '->load() parses the configurator tag'); + $this->assertEquals(array(array('setBar', array())), $services['method_call1']->getMethodCalls(), '->load() parses the method_call tag'); + $this->assertEquals(array(array('setBar', array('foo', new Reference('foo'), array(true, false)))), $services['method_call2']->getMethodCalls(), '->load() parses the method_call tag'); + $this->assertNull($services['factory_service']->getClass()); + $this->assertEquals('getInstance', $services['factory_service']->getFactoryMethod()); + $this->assertEquals('baz_factory', $services['factory_service']->getFactoryService()); + + $aliases = $container->getAliases(); + $this->assertTrue(isset($aliases['alias_for_foo']), '->load() parses elements'); + $this->assertEquals('foo', (string) $aliases['alias_for_foo'], '->load() parses aliases'); + $this->assertTrue($aliases['alias_for_foo']->isPublic()); + $this->assertTrue(isset($aliases['another_alias_for_foo'])); + $this->assertEquals('foo', (string) $aliases['another_alias_for_foo']); + $this->assertFalse($aliases['another_alias_for_foo']->isPublic()); + } + + public function testConvertDomElementToArray() + { + $doc = new \DOMDocument("1.0"); + $doc->loadXML('bar'); + $this->assertEquals('bar', XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array'); + + $doc = new \DOMDocument("1.0"); + $doc->loadXML(''); + $this->assertEquals(array('foo' => 'bar'), XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array'); + + $doc = new \DOMDocument("1.0"); + $doc->loadXML('bar'); + $this->assertEquals(array('foo' => 'bar'), XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array'); + + $doc = new \DOMDocument("1.0"); + $doc->loadXML('barbar'); + $this->assertEquals(array('foo' => array('value' => 'bar', 'foo' => 'bar')), XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array'); + + $doc = new \DOMDocument("1.0"); + $doc->loadXML(''); + $this->assertEquals(array('foo' => null), XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array'); + + $doc = new \DOMDocument("1.0"); + $doc->loadXML(''); + $this->assertEquals(array('foo' => null), XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array'); + + $doc = new \DOMDocument("1.0"); + $doc->loadXML(''); + $this->assertEquals(array('foo' => array(array('foo' => 'bar'), array('foo' => 'bar'))), XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array'); + } + + public function testExtensions() + { + $container = new ContainerBuilder(); + $container->registerExtension(new \ProjectExtension()); + $container->registerExtension(new \ProjectWithXsdExtension()); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + + // extension without an XSD + $loader->load('extensions/services1.xml'); + $container->compile(); + $services = $container->getDefinitions(); + $parameters = $container->getParameterBag()->all(); + + $this->assertTrue(isset($services['project.service.bar']), '->load() parses extension elements'); + $this->assertTrue(isset($parameters['project.parameter.bar']), '->load() parses extension elements'); + + $this->assertEquals('BAR', $services['project.service.foo']->getClass(), '->load() parses extension elements'); + $this->assertEquals('BAR', $parameters['project.parameter.foo'], '->load() parses extension elements'); + + // extension with an XSD + $container = new ContainerBuilder(); + $container->registerExtension(new \ProjectExtension()); + $container->registerExtension(new \ProjectWithXsdExtension()); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('extensions/services2.xml'); + $container->compile(); + $services = $container->getDefinitions(); + $parameters = $container->getParameterBag()->all(); + + $this->assertTrue(isset($services['project.service.bar']), '->load() parses extension elements'); + $this->assertTrue(isset($parameters['project.parameter.bar']), '->load() parses extension elements'); + + $this->assertEquals('BAR', $services['project.service.foo']->getClass(), '->load() parses extension elements'); + $this->assertEquals('BAR', $parameters['project.parameter.foo'], '->load() parses extension elements'); + + $container = new ContainerBuilder(); + $container->registerExtension(new \ProjectExtension()); + $container->registerExtension(new \ProjectWithXsdExtension()); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + + // extension with an XSD (does not validate) + try { + $loader->load('extensions/services3.xml'); + $this->fail('->load() throws an InvalidArgumentException if the configuration does not validate the XSD'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the configuration does not validate the XSD'); + $this->assertRegexp('/The attribute \'bar\' is not allowed/', $e->getMessage(), '->load() throws an InvalidArgumentException if the configuration does not validate the XSD'); + } + + // non-registered extension + try { + $loader->load('extensions/services4.xml'); + $this->fail('->load() throws an InvalidArgumentException if the tag is not valid'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the tag is not valid'); + $this->assertStringStartsWith('There is no extension able to load the configuration for "project:bar" (in', $e->getMessage(), '->load() throws an InvalidArgumentException if the tag is not valid'); + } + } + + public function testExtensionInPhar() + { + if (extension_loaded('suhosin') && false === strpos(ini_get('suhosin.executor.include.whitelist'), 'phar')) { + $this->markTestSkipped('To run this test, add "phar" to the "suhosin.executor.include.whitelist" settings in your php.ini file.'); + } + + require_once self::$fixturesPath.'/includes/ProjectWithXsdExtensionInPhar.phar'; + + // extension with an XSD in PHAR archive + $container = new ContainerBuilder(); + $container->registerExtension(new \ProjectWithXsdExtensionInPhar()); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('extensions/services6.xml'); + + // extension with an XSD in PHAR archive (does not validate) + try { + $loader->load('extensions/services7.xml'); + $this->fail('->load() throws an InvalidArgumentException if the configuration does not validate the XSD'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the configuration does not validate the XSD'); + $this->assertRegexp('/The attribute \'bar\' is not allowed/', $e->getMessage(), '->load() throws an InvalidArgumentException if the configuration does not validate the XSD'); + } + } + + /** + * @covers Symfony\Component\DependencyInjection\Loader\XmlFileLoader::supports + */ + public function testSupports() + { + $loader = new XmlFileLoader(new ContainerBuilder(), new FileLocator()); + + $this->assertTrue($loader->supports('foo.xml'), '->supports() returns true if the resource is loadable'); + $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable'); + } + + public function testNoNamingConflictsForAnonymousServices() + { + $container = new ContainerBuilder(); + + $loader1 = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml/extension1')); + $loader1->load('services.xml'); + $services = $container->getDefinitions(); + $this->assertEquals(2, count($services), '->load() attributes unique ids to anonymous services'); + $loader2 = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml/extension2')); + $loader2->load('services.xml'); + $services = $container->getDefinitions(); + $this->assertEquals(4, count($services), '->load() attributes unique ids to anonymous services'); + + $services = $container->getDefinitions(); + $args1 = $services['extension1.foo']->getArguments(); + $inner1 = $services[(string) $args1[0]]; + $this->assertEquals('BarClass1', $inner1->getClass(), '->load() uses the same configuration as for the anonymous ones'); + $args2 = $services['extension2.foo']->getArguments(); + $inner2 = $services[(string) $args2[0]]; + $this->assertEquals('BarClass2', $inner2->getClass(), '->load() uses the same configuration as for the anonymous ones'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php new file mode 100644 index 0000000..35b5985 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.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\DependencyInjection\Tests\Loader; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\Config\Loader\Loader; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\DependencyInjection\Loader\IniFileLoader; +use Symfony\Component\Config\Loader\LoaderResolver; +use Symfony\Component\Config\FileLocator; + +class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase +{ + static protected $fixturesPath; + + protected function setUp() + { + if (!class_exists('Symfony\Component\Config\Loader\Loader')) { + $this->markTestSkipped('The "Config" component is not available'); + } + + if (!class_exists('Symfony\Component\Yaml\Yaml')) { + $this->markTestSkipped('The "Yaml" component is not available'); + } + } + + static public function setUpBeforeClass() + { + self::$fixturesPath = realpath(__DIR__.'/../Fixtures/'); + require_once self::$fixturesPath.'/includes/foo.php'; + require_once self::$fixturesPath.'/includes/ProjectExtension.php'; + } + + public function testLoadFile() + { + $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/ini')); + $r = new \ReflectionObject($loader); + $m = $r->getMethod('loadFile'); + $m->setAccessible(true); + + try { + $m->invoke($loader, 'foo.yml'); + $this->fail('->load() throws an InvalidArgumentException if the loaded file does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the loaded file does not exist'); + $this->assertEquals('The service file "foo.yml" is not valid.', $e->getMessage(), '->load() throws an InvalidArgumentException if the loaded file does not exist'); + } + + try { + $m->invoke($loader, 'parameters.ini'); + $this->fail('->load() throws an InvalidArgumentException if the loaded file is not a valid YAML file'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the loaded file is not a valid YAML file'); + $this->assertEquals('The service file "parameters.ini" is not valid.', $e->getMessage(), '->load() throws an InvalidArgumentException if the loaded file is not a valid YAML file'); + } + + $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml')); + + foreach (array('nonvalid1', 'nonvalid2') as $fixture) { + try { + $m->invoke($loader, $fixture.'.yml'); + $this->fail('->load() throws an InvalidArgumentException if the loaded file does not validate'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the loaded file does not validate'); + $this->assertStringMatchesFormat('The service file "nonvalid%d.yml" is not valid.', $e->getMessage(), '->load() throws an InvalidArgumentException if the loaded file does not validate'); + } + } + } + + public function testLoadParameters() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services2.yml'); + $this->assertEquals(array('foo' => 'bar', 'mixedcase' => array('MixedCaseKey' => 'value'), 'values' => array(true, false, 0, 1000.3), 'bar' => 'foo', 'foo_bar' => new Reference('foo_bar')), $container->getParameterBag()->all(), '->load() converts YAML keys to lowercase'); + } + + public function testLoadImports() + { + $container = new ContainerBuilder(); + $resolver = new LoaderResolver(array( + new IniFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')), + new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')), + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')), + )); + $loader->setResolver($resolver); + $loader->load('services4.yml'); + + $actual = $container->getParameterBag()->all(); + $expected = array('foo' => 'bar', 'values' => array(true, false), 'bar' => '%foo%', 'foo_bar' => new Reference('foo_bar'), 'mixedcase' => array('MixedCaseKey' => 'value'), 'imported_from_ini' => true, 'imported_from_xml' => true); + $this->assertEquals(array_keys($expected), array_keys($actual), '->load() imports and merges imported files'); + + // Bad import throws no exception due to ignore_errors value. + $loader->load('services4_bad_import.yml'); + } + + public function testLoadServices() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services6.yml'); + $services = $container->getDefinitions(); + $this->assertTrue(isset($services['foo']), '->load() parses service elements'); + $this->assertEquals('Symfony\\Component\\DependencyInjection\\Definition', get_class($services['foo']), '->load() converts service element to Definition instances'); + $this->assertEquals('FooClass', $services['foo']->getClass(), '->load() parses the class attribute'); + $this->assertEquals('container', $services['scope.container']->getScope()); + $this->assertEquals('custom', $services['scope.custom']->getScope()); + $this->assertEquals('prototype', $services['scope.prototype']->getScope()); + $this->assertEquals('getInstance', $services['constructor']->getFactoryMethod(), '->load() parses the factory_method attribute'); + $this->assertEquals('%path%/foo.php', $services['file']->getFile(), '->load() parses the file tag'); + $this->assertEquals(array('foo', new Reference('foo'), array(true, false)), $services['arguments']->getArguments(), '->load() parses the argument tags'); + $this->assertEquals('sc_configure', $services['configurator1']->getConfigurator(), '->load() parses the configurator tag'); + $this->assertEquals(array(new Reference('baz'), 'configure'), $services['configurator2']->getConfigurator(), '->load() parses the configurator tag'); + $this->assertEquals(array('BazClass', 'configureStatic'), $services['configurator3']->getConfigurator(), '->load() parses the configurator tag'); + $this->assertEquals(array(array('setBar', array()), array('setBar', array())), $services['method_call1']->getMethodCalls(), '->load() parses the method_call tag'); + $this->assertEquals(array(array('setBar', array('foo', new Reference('foo'), array(true, false)))), $services['method_call2']->getMethodCalls(), '->load() parses the method_call tag'); + $this->assertEquals('baz_factory', $services['factory_service']->getFactoryService()); + + $aliases = $container->getAliases(); + $this->assertTrue(isset($aliases['alias_for_foo']), '->load() parses aliases'); + $this->assertEquals('foo', (string) $aliases['alias_for_foo'], '->load() parses aliases'); + $this->assertTrue($aliases['alias_for_foo']->isPublic()); + $this->assertTrue(isset($aliases['another_alias_for_foo'])); + $this->assertEquals('foo', (string) $aliases['another_alias_for_foo']); + $this->assertFalse($aliases['another_alias_for_foo']->isPublic()); + } + + public function testExtensions() + { + $container = new ContainerBuilder(); + $container->registerExtension(new \ProjectExtension()); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services10.yml'); + $container->compile(); + $services = $container->getDefinitions(); + $parameters = $container->getParameterBag()->all(); + + $this->assertTrue(isset($services['project.service.bar']), '->load() parses extension elements'); + $this->assertTrue(isset($parameters['project.parameter.bar']), '->load() parses extension elements'); + + $this->assertEquals('BAR', $services['project.service.foo']->getClass(), '->load() parses extension elements'); + $this->assertEquals('BAR', $parameters['project.parameter.foo'], '->load() parses extension elements'); + + try { + $loader->load('services11.yml'); + $this->fail('->load() throws an InvalidArgumentException if the tag is not valid'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the tag is not valid'); + $this->assertStringStartsWith('There is no extension able to load the configuration for "foobarfoobar" (in', $e->getMessage(), '->load() throws an InvalidArgumentException if the tag is not valid'); + } + } + + /** + * @covers Symfony\Component\DependencyInjection\Loader\YamlFileLoader::supports + */ + public function testSupports() + { + $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator()); + + $this->assertTrue($loader->supports('foo.yml'), '->supports() returns true if the resource is loadable'); + $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable'); + } + + public function testNonArrayTagThrowsException() + { + $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml')); + try { + $loader->load('badtag1.yml'); + $this->fail('->load() should throw an exception when the tags key of a service is not an array'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the tags key is not an array'); + $this->assertStringStartsWith('Parameter "tags" must be an array for service', $e->getMessage(), '->load() throws an InvalidArgumentException if the tags key is not an array'); + } + } + + public function testTagWithoutNameThrowsException() + { + $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml')); + try { + $loader->load('badtag2.yml'); + $this->fail('->load() should throw an exception when a tag is missing the name key'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if a tag is missing the name key'); + $this->assertStringStartsWith('A "tags" entry is missing a "name" key for service ', $e->getMessage(), '->load() throws an InvalidArgumentException if a tag is missing the name key'); + } + } + + public function testTagWithAttributeArrayThrowsException() + { + $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml')); + try { + $loader->load('badtag3.yml'); + $this->fail('->load() should throw an exception when a tag-attribute is not a scalar'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if a tag-attribute is not a scalar'); + $this->assertStringStartsWith('A "tags" attribute must be of a scalar-type for service ', $e->getMessage(), '->load() throws an InvalidArgumentException if a tag-attribute is not a scalar'); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ParameterBag/FrozenParameterBagTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ParameterBag/FrozenParameterBagTest.php new file mode 100644 index 0000000..e6e7fea --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ParameterBag/FrozenParameterBagTest.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\DependencyInjection\Tests\ParameterBag; + +use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; + +class FrozenParameterBagTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag::__construct + */ + public function testConstructor() + { + $parameters = array( + 'foo' => 'foo', + 'bar' => 'bar', + ); + $bag = new FrozenParameterBag($parameters); + $this->assertEquals($parameters, $bag->all(), '__construct() takes an array of parameters as its first argument'); + } + + /** + * @covers Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag::clear + * @expectedException \LogicException + */ + public function testClear() + { + $bag = new FrozenParameterBag(array()); + $bag->clear(); + } + + /** + * @covers Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag::set + * @expectedException \LogicException + */ + public function testSet() + { + $bag = new FrozenParameterBag(array()); + $bag->set('foo', 'bar'); + } + + /** + * @covers Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag::add + * @expectedException \LogicException + */ + public function testAdd() + { + $bag = new FrozenParameterBag(array()); + $bag->add(array()); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ParameterBag/ParameterBagTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ParameterBag/ParameterBagTest.php new file mode 100644 index 0000000..29d2380 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ParameterBag/ParameterBagTest.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\DependencyInjection\Tests\ParameterBag; + +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; +use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +class ParameterBagTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Symfony\Component\DependencyInjection\ParameterBag\ParameterBag::__construct + */ + public function testConstructor() + { + $bag = new ParameterBag($parameters = array( + 'foo' => 'foo', + 'bar' => 'bar', + )); + $this->assertEquals($parameters, $bag->all(), '__construct() takes an array of parameters as its first argument'); + } + + /** + * @covers Symfony\Component\DependencyInjection\ParameterBag\ParameterBag::clear + */ + public function testClear() + { + $bag = new ParameterBag($parameters = array( + 'foo' => 'foo', + 'bar' => 'bar', + )); + $bag->clear(); + $this->assertEquals(array(), $bag->all(), '->clear() removes all parameters'); + } + + /** + * @covers Symfony\Component\DependencyInjection\ParameterBag\ParameterBag::remove + */ + public function testRemove() + { + $bag = new ParameterBag(array( + 'foo' => 'foo', + 'bar' => 'bar', + )); + $bag->remove('foo'); + $this->assertEquals(array('bar' => 'bar'), $bag->all(), '->remove() removes a parameter'); + } + + /** + * @covers Symfony\Component\DependencyInjection\ParameterBag\ParameterBag::get + * @covers Symfony\Component\DependencyInjection\ParameterBag\ParameterBag::set + */ + public function testGetSet() + { + $bag = new ParameterBag(array('foo' => 'bar')); + $bag->set('bar', 'foo'); + $this->assertEquals('foo', $bag->get('bar'), '->set() sets the value of a new parameter'); + + $bag->set('foo', 'baz'); + $this->assertEquals('baz', $bag->get('foo'), '->set() overrides previously set parameter'); + + $bag->set('Foo', 'baz1'); + $this->assertEquals('baz1', $bag->get('foo'), '->set() converts the key to lowercase'); + $this->assertEquals('baz1', $bag->get('FOO'), '->get() converts the key to lowercase'); + + try { + $bag->get('baba'); + $this->fail('->get() throws an \InvalidArgumentException if the key does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->get() throws an \InvalidArgumentException if the key does not exist'); + $this->assertEquals('You have requested a non-existent parameter "baba".', $e->getMessage(), '->get() throws an \InvalidArgumentException if the key does not exist'); + } + } + + /** + * @covers Symfony\Component\DependencyInjection\ParameterBag\ParameterBag::has + */ + public function testHas() + { + $bag = new ParameterBag(array('foo' => 'bar')); + $this->assertTrue($bag->has('foo'), '->has() returns true if a parameter is defined'); + $this->assertTrue($bag->has('Foo'), '->has() converts the key to lowercase'); + $this->assertFalse($bag->has('bar'), '->has() returns false if a parameter is not defined'); + } + + /** + * @covers Symfony\Component\DependencyInjection\ParameterBag\ParameterBag::resolveValue + */ + public function testResolveValue() + { + $bag = new ParameterBag(array()); + $this->assertEquals('foo', $bag->resolveValue('foo'), '->resolveValue() returns its argument unmodified if no placeholders are found'); + + $bag = new ParameterBag(array('foo' => 'bar')); + $this->assertEquals('I\'m a bar', $bag->resolveValue('I\'m a %foo%'), '->resolveValue() replaces placeholders by their values'); + $this->assertEquals(array('bar' => 'bar'), $bag->resolveValue(array('%foo%' => '%foo%')), '->resolveValue() replaces placeholders in keys and values of arrays'); + $this->assertEquals(array('bar' => array('bar' => array('bar' => 'bar'))), $bag->resolveValue(array('%foo%' => array('%foo%' => array('%foo%' => '%foo%')))), '->resolveValue() replaces placeholders in nested arrays'); + $this->assertEquals('I\'m a %%foo%%', $bag->resolveValue('I\'m a %%foo%%'), '->resolveValue() supports % escaping by doubling it'); + $this->assertEquals('I\'m a bar %%foo bar', $bag->resolveValue('I\'m a %foo% %%foo %foo%'), '->resolveValue() supports % escaping by doubling it'); + $this->assertEquals(array('foo' => array('bar' => array('ding' => 'I\'m a bar %%foo %%bar'))), $bag->resolveValue(array('foo' => array('bar' => array('ding' => 'I\'m a bar %%foo %%bar')))), '->resolveValue() supports % escaping by doubling it'); + + $bag = new ParameterBag(array('foo' => true)); + $this->assertTrue($bag->resolveValue('%foo%'), '->resolveValue() replaces arguments that are just a placeholder by their value without casting them to strings'); + $bag = new ParameterBag(array('foo' => null)); + $this->assertNull($bag->resolveValue('%foo%'), '->resolveValue() replaces arguments that are just a placeholder by their value without casting them to strings'); + + $bag = new ParameterBag(array('foo' => 'bar', 'baz' => '%%%foo% %foo%%% %%foo%% %%%foo%%%')); + $this->assertEquals('%%bar bar%% %%foo%% %%bar%%', $bag->resolveValue('%baz%'), '->resolveValue() replaces params placed besides escaped %'); + + $bag = new ParameterBag(array('baz' => '%%s?%%s')); + $this->assertEquals('%%s?%%s', $bag->resolveValue('%baz%'), '->resolveValue() is not replacing greedily'); + + $bag = new ParameterBag(array()); + try { + $bag->resolveValue('%foobar%'); + $this->fail('->resolveValue() throws an InvalidArgumentException if a placeholder references a non-existent parameter'); + } catch (ParameterNotFoundException $e) { + $this->assertEquals('You have requested a non-existent parameter "foobar".', $e->getMessage(), '->resolveValue() throws a ParameterNotFoundException if a placeholder references a non-existent parameter'); + } + + try { + $bag->resolveValue('foo %foobar% bar'); + $this->fail('->resolveValue() throws a ParameterNotFoundException if a placeholder references a non-existent parameter'); + } catch (ParameterNotFoundException $e) { + $this->assertEquals('You have requested a non-existent parameter "foobar".', $e->getMessage(), '->resolveValue() throws a ParameterNotFoundException if a placeholder references a non-existent parameter'); + } + + $bag = new ParameterBag(array('foo' => 'a %bar%', 'bar' => array())); + try { + $bag->resolveValue('%foo%'); + $this->fail('->resolveValue() throws a RuntimeException when a parameter embeds another non-string parameter'); + } catch (RuntimeException $e) { + $this->assertEquals('A string value must be composed of strings and/or numbers, but found parameter "bar" of type array inside string value "a %bar%".', $e->getMessage(), '->resolveValue() throws a RuntimeException when a parameter embeds another non-string parameter'); + } + + $bag = new ParameterBag(array('foo' => '%bar%', 'bar' => '%foobar%', 'foobar' => '%foo%')); + try { + $bag->resolveValue('%foo%'); + $this->fail('->resolveValue() throws a ParameterCircularReferenceException when a parameter has a circular reference'); + } catch (ParameterCircularReferenceException $e) { + $this->assertEquals('Circular reference detected for parameter "foo" ("foo" > "bar" > "foobar" > "foo").', $e->getMessage(), '->resolveValue() throws a ParameterCircularReferenceException when a parameter has a circular reference'); + } + + $bag = new ParameterBag(array('foo' => 'a %bar%', 'bar' => 'a %foobar%', 'foobar' => 'a %foo%')); + try { + $bag->resolveValue('%foo%'); + $this->fail('->resolveValue() throws a ParameterCircularReferenceException when a parameter has a circular reference'); + } catch (ParameterCircularReferenceException $e) { + $this->assertEquals('Circular reference detected for parameter "foo" ("foo" > "bar" > "foobar" > "foo").', $e->getMessage(), '->resolveValue() throws a ParameterCircularReferenceException when a parameter has a circular reference'); + } + + $bag = new ParameterBag(array('host' => 'foo.bar', 'port' => 1337)); + $this->assertEquals('foo.bar:1337', $bag->resolveValue('%host%:%port%')); + } + + /** + * @covers Symfony\Component\DependencyInjection\ParameterBag\ParameterBag::resolve + */ + public function testResolveIndicatesWhyAParameterIsNeeded() + { + $bag = new ParameterBag(array('foo' => '%bar%')); + + try { + $bag->resolve(); + } catch (ParameterNotFoundException $e) { + $this->assertEquals('The parameter "foo" has a dependency on a non-existent parameter "bar".', $e->getMessage()); + } + + $bag = new ParameterBag(array('foo' => '%bar%')); + + try { + $bag->resolve(); + } catch (ParameterNotFoundException $e) { + $this->assertEquals('The parameter "foo" has a dependency on a non-existent parameter "bar".', $e->getMessage()); + } + } + + /** + * @covers Symfony\Component\DependencyInjection\ParameterBag\ParameterBag::resolve + */ + public function testResolveUnescapesValue() + { + $bag = new ParameterBag(array( + 'foo' => array('bar' => array('ding' => 'I\'m a bar %%foo %%bar')), + 'bar' => 'I\'m a %%foo%%', + )); + + $bag->resolve(); + + $this->assertEquals('I\'m a %foo%', $bag->get('bar'), '->resolveValue() supports % escaping by doubling it'); + $this->assertEquals(array('bar' => array('ding' => 'I\'m a bar %foo %bar')), $bag->get('foo'), '->resolveValue() supports % escaping by doubling it'); + } + + /** + * @covers Symfony\Component\DependencyInjection\ParameterBag\ParameterBag::resolve + * @dataProvider stringsWithSpacesProvider + */ + public function testResolveStringWithSpacesReturnsString($expected, $test, $description) + { + $bag = new ParameterBag(array('foo' => 'bar')); + + try { + $this->assertEquals($expected, $bag->resolveString($test), $description); + } catch (ParameterNotFoundException $e) { + $this->fail(sprintf('%s - "%s"', $description, $expected)); + } + } + + public function stringsWithSpacesProvider() + { + return array( + array('bar', '%foo%', 'Parameters must be wrapped by %.'), + array('% foo %', '% foo %', 'Parameters should not have spaces.'), + array('{% set my_template = "foo" %}', '{% set my_template = "foo" %}', 'Twig-like strings are not parameters.'), + array('50% is less than 100%', '50% is less than 100%', 'Text between % signs is allowed, if there are spaces.'), + ); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ParameterTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ParameterTest.php new file mode 100644 index 0000000..bed188e --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ParameterTest.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\DependencyInjection\Tests; + +use Symfony\Component\DependencyInjection\Parameter; + +class ParameterTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Symfony\Component\DependencyInjection\Parameter::__construct + */ + public function testConstructor() + { + $ref = new Parameter('foo'); + $this->assertEquals('foo', (string) $ref, '__construct() sets the id of the parameter, which is used for the __toString() method'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ReferenceTest.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ReferenceTest.php new file mode 100644 index 0000000..f14e99f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/ReferenceTest.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\DependencyInjection\Tests; + +use Symfony\Component\DependencyInjection\Reference; + +class ReferenceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Symfony\Component\DependencyInjection\Reference::__construct + */ + public function testConstructor() + { + $ref = new Reference('foo'); + $this->assertEquals('foo', (string) $ref, '__construct() sets the id of the reference, which is used for the __toString() method'); + } + + public function testCaseInsensitive() + { + $ref = new Reference('FooBar'); + $this->assertEquals('foobar', (string) $ref, 'the id is lowercased as the container is case insensitive'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/bootstrap.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/bootstrap.php new file mode 100644 index 0000000..fd3118f --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Tests/bootstrap.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +spl_autoload_register(function ($class) { + if (0 === strpos(ltrim($class, '/'), 'Symfony\Component\DependencyInjection')) { + if (file_exists($file = __DIR__.'/../'.substr(str_replace('\\', '/', $class), strlen('Symfony\Component\DependencyInjection')).'.php')) { + require_once $file; + } + } +}); + +if (file_exists($loader = __DIR__.'/../vendor/autoload.php')) { + require_once $loader; +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Variable.php b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Variable.php new file mode 100644 index 0000000..c84b8fd --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Variable.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\DependencyInjection; + +/** + * Represents a variable. + * + * $var = new Variable('a'); + * + * will be dumped as + * + * $a + * + * by the PHP dumper. + * + * @author Johannes M. Schmitt + */ +class Variable +{ + private $name; + + /** + * Constructor + * + * @param string $name + */ + public function __construct($name) + { + $this->name = $name; + } + + /** + * Converts the object to a string + * + * @return string + */ + public function __toString() + { + return $this->name; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/composer.json b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/composer.json new file mode 100644 index 0000000..7238bd0 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/composer.json @@ -0,0 +1,38 @@ +{ + "name": "symfony/dependency-injection", + "type": "library", + "description": "Symfony DependencyInjection 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/yaml": "2.1.*", + "symfony/config": "2.1.*" + }, + "suggest": { + "symfony/yaml": "self.version", + "symfony/config": "self.version" + }, + "autoload": { + "psr-0": { "Symfony\\Component\\DependencyInjection": "" } + }, + "target-dir": "Symfony/Component/DependencyInjection", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/phpunit.xml.dist b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/phpunit.xml.dist new file mode 100644 index 0000000..554d104 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/phpunit.xml.dist @@ -0,0 +1,30 @@ + + + + + + ./Tests/ + + + + + + ./ + + ./Resources + ./Tests + ./vendor + + + + diff --git a/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/CHANGELOG.md b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/CHANGELOG.md new file mode 100644 index 0000000..50edf20 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/CHANGELOG.md @@ -0,0 +1,12 @@ +CHANGELOG +========= + +2.1.0 +----- + + * added support for the HTTP PATCH method + * refactored the Form class internals to support multi-dimensional fields + (the public API is backward compatible) + * added a way to get parsing errors for Crawler::addHtmlContent() and + Crawler::addXmlContent() via libxml functions + * added support for submitting a form without a submit button diff --git a/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Crawler.php b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Crawler.php new file mode 100644 index 0000000..03c1dc5 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Crawler.php @@ -0,0 +1,721 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DomCrawler; + +use Symfony\Component\CssSelector\CssSelector; + +/** + * Crawler eases navigation of a list of \DOMNode objects. + * + * @author Fabien Potencier + * + * @api + */ +class Crawler extends \SplObjectStorage +{ + /** + * @var string The current URI or the base href value + */ + private $uri; + + /** + * Constructor. + * + * @param mixed $node A Node to use as the base for the crawling + * @param string $uri The current URI or the base href value + * + * @api + */ + public function __construct($node = null, $uri = null) + { + $this->uri = $uri; + + $this->add($node); + } + + /** + * Removes all the nodes. + * + * @api + */ + public function clear() + { + $this->removeAll($this); + } + + /** + * Adds a node to the current list of nodes. + * + * This method uses the appropriate specialized add*() method based + * on the type of the argument. + * + * @param null|\DOMNodeList|array|\DOMNode $node A node + * + * @api + */ + public function add($node) + { + if ($node instanceof \DOMNodeList) { + $this->addNodeList($node); + } elseif (is_array($node)) { + $this->addNodes($node); + } elseif (is_string($node)) { + $this->addContent($node); + } elseif (is_object($node)) { + $this->addNode($node); + } + } + + /** + * Adds HTML/XML content. + * + * @param string $content A string to parse as HTML/XML + * @param null|string $type The content type of the string + * + * @return null|void + */ + public function addContent($content, $type = null) + { + if (empty($type)) { + $type = 'text/html'; + } + + // DOM only for HTML/XML content + if (!preg_match('/(x|ht)ml/i', $type, $matches)) { + return null; + } + + $charset = 'ISO-8859-1'; + if (false !== $pos = strpos($type, 'charset=')) { + $charset = substr($type, $pos + 8); + if (false !== $pos = strpos($charset, ';')) { + $charset = substr($charset, 0, $pos); + } + } + + if ('x' === $matches[1]) { + $this->addXmlContent($content, $charset); + } else { + $this->addHtmlContent($content, $charset); + } + } + + /** + * Adds an HTML content to the list of nodes. + * + * The libxml errors are disabled when the content is parsed. + * + * If you want to get parsing errors, be sure to enable + * internal errors via libxml_use_internal_errors(true) + * and then, get the errors via libxml_get_errors(). Be + * sure to clear errors with libxml_clear_errors() afterward. + * + * @param string $content The HTML content + * @param string $charset The charset + * + * @api + */ + public function addHtmlContent($content, $charset = 'UTF-8') + { + $dom = new \DOMDocument('1.0', $charset); + $dom->validateOnParse = true; + + if (function_exists('mb_convert_encoding')) { + $content = mb_convert_encoding($content, 'HTML-ENTITIES', $charset); + } + + $current = libxml_use_internal_errors(true); + @$dom->loadHTML($content); + libxml_use_internal_errors($current); + + $this->addDocument($dom); + + $base = $this->filterXPath('descendant-or-self::base')->extract(array('href')); + + if (count($base)) { + $this->uri = current($base); + } + } + + /** + * Adds an XML content to the list of nodes. + * + * The libxml errors are disabled when the content is parsed. + * + * If you want to get parsing errors, be sure to enable + * internal errors via libxml_use_internal_errors(true) + * and then, get the errors via libxml_get_errors(). Be + * sure to clear errors with libxml_clear_errors() afterward. + * + * @param string $content The XML content + * @param string $charset The charset + * + * @api + */ + public function addXmlContent($content, $charset = 'UTF-8') + { + $dom = new \DOMDocument('1.0', $charset); + $dom->validateOnParse = true; + + // remove the default namespace to make XPath expressions simpler + $current = libxml_use_internal_errors(true); + @$dom->loadXML(str_replace('xmlns', 'ns', $content)); + libxml_use_internal_errors($current); + + $this->addDocument($dom); + } + + /** + * Adds a \DOMDocument to the list of nodes. + * + * @param \DOMDocument $dom A \DOMDocument instance + * + * @api + */ + public function addDocument(\DOMDocument $dom) + { + if ($dom->documentElement) { + $this->addNode($dom->documentElement); + } + } + + /** + * Adds a \DOMNodeList to the list of nodes. + * + * @param \DOMNodeList $nodes A \DOMNodeList instance + * + * @api + */ + public function addNodeList(\DOMNodeList $nodes) + { + foreach ($nodes as $node) { + $this->addNode($node); + } + } + + /** + * Adds an array of \DOMNode instances to the list of nodes. + * + * @param array $nodes An array of \DOMNode instances + * + * @api + */ + public function addNodes(array $nodes) + { + foreach ($nodes as $node) { + $this->add($node); + } + } + + /** + * Adds a \DOMNode instance to the list of nodes. + * + * @param \DOMNode $node A \DOMNode instance + * + * @api + */ + public function addNode(\DOMNode $node) + { + if ($node instanceof \DOMDocument) { + $this->attach($node->documentElement); + } else { + $this->attach($node); + } + } + + /** + * Returns a node given its position in the node list. + * + * @param integer $position The position + * + * @return Crawler A new instance of the Crawler with the selected node, or an empty Crawler if it does not exist. + * + * @api + */ + public function eq($position) + { + foreach ($this as $i => $node) { + if ($i == $position) { + return new static($node, $this->uri); + } + } + + return new static(null, $this->uri); + } + + /** + * Calls an anonymous function on each node of the list. + * + * The anonymous function receives the position and the node as arguments. + * + * Example: + * + * $crawler->filter('h1')->each(function ($node, $i) + * { + * return $node->nodeValue; + * }); + * + * @param \Closure $closure An anonymous function + * + * @return array An array of values returned by the anonymous function + * + * @api + */ + public function each(\Closure $closure) + { + $data = array(); + foreach ($this as $i => $node) { + $data[] = $closure($node, $i); + } + + return $data; + } + + /** + * Reduces the list of nodes by calling an anonymous function. + * + * To remove a node from the list, the anonymous function must return false. + * + * @param \Closure $closure An anonymous function + * + * @return Crawler A Crawler instance with the selected nodes. + * + * @api + */ + public function reduce(\Closure $closure) + { + $nodes = array(); + foreach ($this as $i => $node) { + if (false !== $closure($node, $i)) { + $nodes[] = $node; + } + } + + return new static($nodes, $this->uri); + } + + /** + * Returns the first node of the current selection + * + * @return Crawler A Crawler instance with the first selected node + * + * @api + */ + public function first() + { + return $this->eq(0); + } + + /** + * Returns the last node of the current selection + * + * @return Crawler A Crawler instance with the last selected node + * + * @api + */ + public function last() + { + return $this->eq(count($this) - 1); + } + + /** + * Returns the siblings nodes of the current selection + * + * @return Crawler A Crawler instance with the sibling nodes + * + * @throws \InvalidArgumentException When current node is empty + * + * @api + */ + public function siblings() + { + if (!count($this)) { + throw new \InvalidArgumentException('The current node list is empty.'); + } + + return new static($this->sibling($this->getNode(0)->parentNode->firstChild), $this->uri); + } + + /** + * Returns the next siblings nodes of the current selection + * + * @return Crawler A Crawler instance with the next sibling nodes + * + * @throws \InvalidArgumentException When current node is empty + * + * @api + */ + public function nextAll() + { + if (!count($this)) { + throw new \InvalidArgumentException('The current node list is empty.'); + } + + return new static($this->sibling($this->getNode(0)), $this->uri); + } + + /** + * Returns the previous sibling nodes of the current selection + * + * @return Crawler A Crawler instance with the previous sibling nodes + * + * @api + */ + public function previousAll() + { + if (!count($this)) { + throw new \InvalidArgumentException('The current node list is empty.'); + } + + return new static($this->sibling($this->getNode(0), 'previousSibling'), $this->uri); + } + + /** + * Returns the parents nodes of the current selection + * + * @return Crawler A Crawler instance with the parents nodes of the current selection + * + * @throws \InvalidArgumentException When current node is empty + * + * @api + */ + public function parents() + { + if (!count($this)) { + throw new \InvalidArgumentException('The current node list is empty.'); + } + + $node = $this->getNode(0); + $nodes = array(); + + while ($node = $node->parentNode) { + if (1 === $node->nodeType && '_root' !== $node->nodeName) { + $nodes[] = $node; + } + } + + return new static($nodes, $this->uri); + } + + /** + * Returns the children nodes of the current selection + * + * @return Crawler A Crawler instance with the children nodes + * + * @throws \InvalidArgumentException When current node is empty + * + * @api + */ + public function children() + { + if (!count($this)) { + throw new \InvalidArgumentException('The current node list is empty.'); + } + + return new static($this->sibling($this->getNode(0)->firstChild), $this->uri); + } + + /** + * Returns the attribute value of the first node of the list. + * + * @param string $attribute The attribute name + * + * @return string The attribute value + * + * @throws \InvalidArgumentException When current node is empty + * + * @api + */ + public function attr($attribute) + { + if (!count($this)) { + throw new \InvalidArgumentException('The current node list is empty.'); + } + + return $this->getNode(0)->getAttribute($attribute); + } + + /** + * Returns the node value of the first node of the list. + * + * @return string The node value + * + * @throws \InvalidArgumentException When current node is empty + * + * @api + */ + public function text() + { + if (!count($this)) { + throw new \InvalidArgumentException('The current node list is empty.'); + } + + return $this->getNode(0)->nodeValue; + } + + /** + * Extracts information from the list of nodes. + * + * You can extract attributes or/and the node value (_text). + * + * Example: + * + * $crawler->filter('h1 a')->extract(array('_text', 'href')); + * + * @param array $attributes An array of attributes + * + * @return array An array of extracted values + * + * @api + */ + public function extract($attributes) + { + $attributes = (array) $attributes; + + $data = array(); + foreach ($this as $node) { + $elements = array(); + foreach ($attributes as $attribute) { + if ('_text' === $attribute) { + $elements[] = $node->nodeValue; + } else { + $elements[] = $node->getAttribute($attribute); + } + } + + $data[] = count($attributes) > 1 ? $elements : $elements[0]; + } + + return $data; + } + + /** + * Filters the list of nodes with an XPath expression. + * + * @param string $xpath An XPath expression + * + * @return Crawler A new instance of Crawler with the filtered list of nodes + * + * @api + */ + public function filterXPath($xpath) + { + $document = new \DOMDocument('1.0', 'UTF-8'); + $root = $document->appendChild($document->createElement('_root')); + foreach ($this as $node) { + $root->appendChild($document->importNode($node, true)); + } + + $domxpath = new \DOMXPath($document); + + return new static($domxpath->query($xpath), $this->uri); + } + + /** + * Filters the list of nodes with a CSS selector. + * + * This method only works if you have installed the CssSelector Symfony Component. + * + * @param string $selector A CSS selector + * + * @return Crawler A new instance of Crawler with the filtered list of nodes + * + * @throws \RuntimeException if the CssSelector Component is not available + * + * @api + */ + public function filter($selector) + { + if (!class_exists('Symfony\\Component\\CssSelector\\CssSelector')) { + // @codeCoverageIgnoreStart + throw new \RuntimeException('Unable to filter with a CSS selector as the Symfony CssSelector is not installed (you can use filterXPath instead).'); + // @codeCoverageIgnoreEnd + } + + return $this->filterXPath(CssSelector::toXPath($selector)); + } + + /** + * Selects links by name or alt value for clickable images. + * + * @param string $value The link text + * + * @return Crawler A new instance of Crawler with the filtered list of nodes + * + * @api + */ + public function selectLink($value) + { + $xpath = sprintf('//a[contains(concat(\' \', normalize-space(string(.)), \' \'), %s)] ', static::xpathLiteral(' '.$value.' ')). + sprintf('| //a/img[contains(concat(\' \', normalize-space(string(@alt)), \' \'), %s)]/ancestor::a', static::xpathLiteral(' '.$value.' ')); + + return $this->filterXPath($xpath); + } + + /** + * Selects a button by name or alt value for images. + * + * @param string $value The button text + * + * @return Crawler A new instance of Crawler with the filtered list of nodes + * + * @api + */ + public function selectButton($value) + { + $xpath = sprintf('//input[((@type="submit" or @type="button") and contains(concat(\' \', normalize-space(string(@value)), \' \'), %s)) ', static::xpathLiteral(' '.$value.' ')). + sprintf('or (@type="image" and contains(concat(\' \', normalize-space(string(@alt)), \' \'), %s)) or @id="%s" or @name="%s"] ', static::xpathLiteral(' '.$value.' '), $value, $value). + sprintf('| //button[contains(concat(\' \', normalize-space(string(.)), \' \'), %s) or @id="%s" or @name="%s"]', static::xpathLiteral(' '.$value.' '), $value, $value); + + return $this->filterXPath($xpath); + } + + /** + * Returns a Link object for the first node in the list. + * + * @param string $method The method for the link (get by default) + * + * @return Link A Link instance + * + * @throws \InvalidArgumentException If the current node list is empty + * + * @api + */ + public function link($method = 'get') + { + if (!count($this)) { + throw new \InvalidArgumentException('The current node list is empty.'); + } + + $node = $this->getNode(0); + + return new Link($node, $this->uri, $method); + } + + /** + * Returns an array of Link objects for the nodes in the list. + * + * @return array An array of Link instances + * + * @api + */ + public function links() + { + $links = array(); + foreach ($this as $node) { + $links[] = new Link($node, $this->uri, 'get'); + } + + return $links; + } + + /** + * Returns a Form object for the first node in the list. + * + * @param array $values An array of values for the form fields + * @param string $method The method for the form + * + * @return Form A Form instance + * + * @throws \InvalidArgumentException If the current node list is empty + * + * @api + */ + public function form(array $values = null, $method = null) + { + if (!count($this)) { + throw new \InvalidArgumentException('The current node list is empty.'); + } + + $form = new Form($this->getNode(0), $this->uri, $method); + + if (null !== $values) { + $form->setValues($values); + } + + return $form; + } + + /** + * Converts string for XPath expressions. + * + * Escaped characters are: quotes (") and apostrophe ('). + * + * Examples: + * + * echo Crawler::xpathLiteral('foo " bar'); + * //prints 'foo " bar' + * + * echo Crawler::xpathLiteral("foo ' bar"); + * //prints "foo ' bar" + * + * echo Crawler::xpathLiteral('a\'b"c'); + * //prints concat('a', "'", 'b"c') + * + * + * @param string $s String to be escaped + * + * @return string Converted string + * + */ + static public function xpathLiteral($s) + { + if (false === strpos($s, "'")) { + return sprintf("'%s'", $s); + } + + if (false === strpos($s, '"')) { + return sprintf('"%s"', $s); + } + + $string = $s; + $parts = array(); + while (true) { + if (false !== $pos = strpos($string, "'")) { + $parts[] = sprintf("'%s'", substr($string, 0, $pos)); + $parts[] = "\"'\""; + $string = substr($string, $pos + 1); + } else { + $parts[] = "'$string'"; + break; + } + } + + return sprintf("concat(%s)", implode($parts, ', ')); + } + + private function getNode($position) + { + foreach ($this as $i => $node) { + if ($i == $position) { + return $node; + } + // @codeCoverageIgnoreStart + } + + return null; + // @codeCoverageIgnoreEnd + } + + private function sibling($node, $siblingDir = 'nextSibling') + { + $nodes = array(); + + do { + if ($node !== $this->getNode(0) && $node->nodeType === 1) { + $nodes[] = $node; + } + } while ($node = $node->$siblingDir); + + return $nodes; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php new file mode 100644 index 0000000..2e192cb --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php @@ -0,0 +1,307 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DomCrawler\Field; + +/** + * ChoiceFormField represents a choice form field. + * + * It is constructed from a HTML select tag, or a HTML checkbox, or radio inputs. + * + * @author Fabien Potencier + * + * @api + */ +class ChoiceFormField extends FormField +{ + /** + * @var string + */ + private $type; + /** + * @var Boolean + */ + private $multiple; + /** + * @var array + */ + private $options; + + /** + * Returns true if the field should be included in the submitted values. + * + * @return Boolean true if the field should be included in the submitted values, false otherwise + */ + public function hasValue() + { + // don't send a value for unchecked checkboxes + if (in_array($this->type, array('checkbox', 'radio')) && null === $this->value) { + return false; + } + + return true; + } + + /** + * Check if the current selected option is disabled + * + * @return Boolean + */ + public function isDisabled() + { + foreach ($this->options as $option) { + if ($option['value'] == $this->value && $option['disabled']) { + return true; + } + } + + return false; + } + + /** + * Sets the value of the field. + * + * @param string $value The value of the field + * + * @api + */ + public function select($value) + { + $this->setValue($value); + } + + /** + * Ticks a checkbox. + * + * @throws \LogicException When the type provided is not correct + * + * @api + */ + public function tick() + { + if ('checkbox' !== $this->type) { + throw new \LogicException(sprintf('You cannot tick "%s" as it is not a checkbox (%s).', $this->name, $this->type)); + } + + $this->setValue(true); + } + + /** + * Ticks a checkbox. + * + * @throws \LogicException When the type provided is not correct + * + * @api + */ + public function untick() + { + if ('checkbox' !== $this->type) { + throw new \LogicException(sprintf('You cannot tick "%s" as it is not a checkbox (%s).', $this->name, $this->type)); + } + + $this->setValue(false); + } + + /** + * Sets the value of the field. + * + * @param string $value The value of the field + * + * @throws \InvalidArgumentException When value type provided is not correct + */ + public function setValue($value) + { + if ('checkbox' == $this->type && false === $value) { + // uncheck + $this->value = null; + } elseif ('checkbox' == $this->type && true === $value) { + // check + $this->value = $this->options[0]['value']; + } else { + if (is_array($value)) { + if (!$this->multiple) { + throw new \InvalidArgumentException(sprintf('The value for "%s" cannot be an array.', $this->name)); + } + + foreach ($value as $v) { + if (!$this->containsOption($v, $this->options)) { + throw new \InvalidArgumentException(sprintf('Input "%s" cannot take "%s" as a value (possible values: %s).', $this->name, $v, implode(', ', $this->availableOptionValues()))); + } + } + } elseif (!$this->containsOption($value, $this->options)) { + throw new \InvalidArgumentException(sprintf('Input "%s" cannot take "%s" as a value (possible values: %s).', $this->name, $value, implode(', ', $this->availableOptionValues()))); + } + + if ($this->multiple) { + $value = (array) $value; + } + + if (is_array($value)) { + $this->value = $value; + } else { + parent::setValue($value); + } + } + } + + /** + * Adds a choice to the current ones. + * + * This method should only be used internally. + * + * @param \DOMNode $node A \DOMNode + * + * @throws \LogicException When choice provided is not multiple nor radio + */ + public function addChoice(\DOMNode $node) + { + if (!$this->multiple && 'radio' != $this->type) { + throw new \LogicException(sprintf('Unable to add a choice for "%s" as it is not multiple or is not a radio button.', $this->name)); + } + + $option = $this->buildOptionValue($node); + $this->options[] = $option; + + if ($node->getAttribute('checked')) { + $this->value = $option['value']; + } + } + + /** + * Returns the type of the choice field (radio, select, or checkbox). + * + * @return string The type + */ + public function getType() + { + return $this->type; + } + + /** + * Returns true if the field accepts multiple values. + * + * @return Boolean true if the field accepts multiple values, false otherwise + */ + public function isMultiple() + { + return $this->multiple; + } + + /** + * Initializes the form field. + * + * @throws \LogicException When node type is incorrect + */ + protected function initialize() + { + if ('input' != $this->node->nodeName && 'select' != $this->node->nodeName) { + throw new \LogicException(sprintf('A ChoiceFormField can only be created from an input or select tag (%s given).', $this->node->nodeName)); + } + + if ('input' == $this->node->nodeName && 'checkbox' != $this->node->getAttribute('type') && 'radio' != $this->node->getAttribute('type')) { + throw new \LogicException(sprintf('A ChoiceFormField can only be created from an input tag with a type of checkbox or radio (given type is %s).', $this->node->getAttribute('type'))); + } + + $this->value = null; + $this->options = array(); + $this->multiple = false; + + if ('input' == $this->node->nodeName) { + $this->type = $this->node->getAttribute('type'); + $optionValue = $this->buildOptionValue($this->node); + $this->options[] = $optionValue; + + if ($this->node->getAttribute('checked')) { + $this->value = $optionValue['value']; + } + } else { + $this->type = 'select'; + if ($this->node->hasAttribute('multiple')) { + $this->multiple = true; + $this->value = array(); + $this->name = str_replace('[]', '', $this->name); + } + + $found = false; + foreach ($this->xpath->query('descendant::option', $this->node) as $option) { + $this->options[] = $this->buildOptionValue($option); + + if ($option->getAttribute('selected')) { + $found = true; + if ($this->multiple) { + $this->value[] = $option->getAttribute('value'); + } else { + $this->value = $option->getAttribute('value'); + } + } + } + + // if no option is selected and if it is a simple select box, take the first option as the value + $option = $this->xpath->query('descendant::option', $this->node)->item(0); + if (!$found && !$this->multiple && $option instanceof \DOMElement) { + $this->value = $option->getAttribute('value'); + } + } + } + + /** + * Returns option value with associated disabled flag + * + * @param \DOMNode $node + * + * @return array + */ + private function buildOptionValue($node) + { + $option = array(); + + $defaultValue = (isset($node->nodeValue) && !empty($node->nodeValue)) ? $node->nodeValue : '1'; + $option['value'] = $node->hasAttribute('value') ? $node->getAttribute('value') : $defaultValue; + $option['disabled'] = ($node->hasAttribute('disabled') && $node->getAttribute('disabled') == 'disabled'); + + return $option; + } + + /** + * Checks whether given vale is in the existing options + * + * @param string $optionValue + * @param array $options + * + * @return bool + */ + public function containsOption($optionValue, $options) + { + foreach ($options as $option) { + if ($option['value'] == $optionValue) { + return true; + } + } + + return false; + } + + /** + * Returns list of available field options + * + * @return array + */ + public function availableOptionValues() + { + $values = array(); + + foreach ($this->options as $option) { + $values[] = $option['value']; + } + + return $values; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Field/FileFormField.php b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Field/FileFormField.php new file mode 100644 index 0000000..1bb08af --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Field/FileFormField.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\DomCrawler\Field; + +/** + * FileFormField represents a file form field (an HTML file input tag). + * + * @author Fabien Potencier + * + * @api + */ +class FileFormField extends FormField +{ + /** + * Sets the PHP error code associated with the field. + * + * @param integer $error The error code (one of UPLOAD_ERR_INI_SIZE, UPLOAD_ERR_FORM_SIZE, UPLOAD_ERR_PARTIAL, UPLOAD_ERR_NO_FILE, UPLOAD_ERR_NO_TMP_DIR, UPLOAD_ERR_CANT_WRITE, or UPLOAD_ERR_EXTENSION) + * + * @throws \InvalidArgumentException When error code doesn't exist + */ + public function setErrorCode($error) + { + $codes = array(UPLOAD_ERR_INI_SIZE, UPLOAD_ERR_FORM_SIZE, UPLOAD_ERR_PARTIAL, UPLOAD_ERR_NO_FILE, UPLOAD_ERR_NO_TMP_DIR, UPLOAD_ERR_CANT_WRITE, UPLOAD_ERR_EXTENSION); + if (!in_array($error, $codes)) { + throw new \InvalidArgumentException(sprintf('The error code %s is not valid.', $error)); + } + + $this->value = array('name' => '', 'type' => '', 'tmp_name' => '', 'error' => $error, 'size' => 0); + } + + /** + * Sets the value of the field. + * + * @param string $value The value of the field + * + * @api + */ + public function upload($value) + { + $this->setValue($value); + } + + /** + * Sets the value of the field. + * + * @param string $value The value of the field + */ + public function setValue($value) + { + if (null !== $value && is_readable($value)) { + $error = UPLOAD_ERR_OK; + $size = filesize($value); + $name = basename($value); + + // copy to a tmp location + $tmp = tempnam(sys_get_temp_dir(), 'upload'); + unlink($tmp); + copy($value, $tmp); + $value = $tmp; + } else { + $error = UPLOAD_ERR_NO_FILE; + $size = 0; + $name = ''; + $value = ''; + } + + $this->value = array('name' => $name, 'type' => '', 'tmp_name' => $value, 'error' => $error, 'size' => $size); + } + + /** + * Initializes the form field. + * + * @throws \LogicException When node type is incorrect + */ + protected function initialize() + { + if ('input' != $this->node->nodeName) { + throw new \LogicException(sprintf('A FileFormField can only be created from an input tag (%s given).', $this->node->nodeName)); + } + + if ('file' != $this->node->getAttribute('type')) { + throw new \LogicException(sprintf('A FileFormField can only be created from an input tag with a type of file (given type is %s).', $this->node->getAttribute('type'))); + } + + $this->setValue(null); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Field/FormField.php b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Field/FormField.php new file mode 100644 index 0000000..6412272 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Field/FormField.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\DomCrawler\Field; + +/** + * FormField is the abstract class for all form fields. + * + * @author Fabien Potencier + */ +abstract class FormField +{ + /** + * @var \DOMNode + */ + protected $node; + /** + * @var string + */ + protected $name; + /** + * @var string + */ + protected $value; + /** + * @var \DOMDocument + */ + protected $document; + /** + * @var \DOMXPath + */ + protected $xpath; + /** + * @var Boolean + */ + protected $disabled; + + /** + * Constructor. + * + * @param \DOMNode $node The node associated with this field + */ + public function __construct(\DOMNode $node) + { + $this->node = $node; + $this->name = $node->getAttribute('name'); + + $this->document = new \DOMDocument('1.0', 'UTF-8'); + $this->node = $this->document->importNode($this->node, true); + + $root = $this->document->appendChild($this->document->createElement('_root')); + $root->appendChild($this->node); + $this->xpath = new \DOMXPath($this->document); + + $this->initialize(); + } + + /** + * Returns the name of the field. + * + * @return string The name of the field + */ + public function getName() + { + return $this->name; + } + + /** + * Gets the value of the field. + * + * @return string|array The value of the field + */ + public function getValue() + { + return $this->value; + } + + /** + * Sets the value of the field. + * + * @param string $value The value of the field + * + * @api + */ + public function setValue($value) + { + $this->value = (string) $value; + } + + /** + * Returns true if the field should be included in the submitted values. + * + * @return Boolean true if the field should be included in the submitted values, false otherwise + */ + public function hasValue() + { + return true; + } + + /** + * Check if the current field is disabled + * + * @return Boolean + */ + public function isDisabled() + { + return $this->node->hasAttribute('disabled'); + } + + /** + * Initializes the form field. + */ + abstract protected function initialize(); +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Field/InputFormField.php b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Field/InputFormField.php new file mode 100644 index 0000000..251873c --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Field/InputFormField.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\DomCrawler\Field; + +/** + * InputFormField represents an input form field (an HTML input tag). + * + * For inputs with type of file, checkbox, or radio, there are other more + * specialized classes (cf. FileFormField and ChoiceFormField). + * + * @author Fabien Potencier + * + * @api + */ +class InputFormField extends FormField +{ + /** + * Initializes the form field. + * + * @throws \LogicException When node type is incorrect + */ + protected function initialize() + { + if ('input' != $this->node->nodeName) { + throw new \LogicException(sprintf('An InputFormField can only be created from an input tag (%s given).', $this->node->nodeName)); + } + + if ('checkbox' == $this->node->getAttribute('type')) { + throw new \LogicException('Checkboxes should be instances of ChoiceFormField.'); + } + + if ('file' == $this->node->getAttribute('type')) { + throw new \LogicException('File inputs should be instances of FileFormField.'); + } + + $this->value = $this->node->getAttribute('value'); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Field/TextareaFormField.php b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Field/TextareaFormField.php new file mode 100644 index 0000000..794e966 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Field/TextareaFormField.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\DomCrawler\Field; + +/** + * TextareaFormField represents a textarea form field (an HTML textarea tag). + * + * @author Fabien Potencier + * + * @api + */ +class TextareaFormField extends FormField +{ + /** + * Initializes the form field. + * + * @throws \LogicException When node type is incorrect + */ + protected function initialize() + { + if ('textarea' != $this->node->nodeName) { + throw new \LogicException(sprintf('A TextareaFormField can only be created from a textarea tag (%s given).', $this->node->nodeName)); + } + + $this->value = null; + foreach ($this->node->childNodes as $node) { + $this->value .= $this->document->saveXML($node); + } + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Form.php b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Form.php new file mode 100644 index 0000000..9e60711 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Form.php @@ -0,0 +1,586 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DomCrawler; + +use Symfony\Component\DomCrawler\Field\FormField; + +/** + * Form represents an HTML form. + * + * @author Fabien Potencier + * + * @api + */ +class Form extends Link implements \ArrayAccess +{ + /** + * @var \DOMNode + */ + private $button; + /** + * @var Field\FormField[] + */ + private $fields; + + /** + * Constructor. + * + * @param \DOMNode $node A \DOMNode instance + * @param string $currentUri The URI of the page where the form is embedded + * @param string $method The method to use for the link (if null, it defaults to the method defined by the form) + * + * @throws \LogicException if the node is not a button inside a form tag + * + * @api + */ + public function __construct(\DOMNode $node, $currentUri, $method = null) + { + parent::__construct($node, $currentUri, $method); + + $this->initialize(); + } + + /** + * Gets the form node associated with this form. + * + * @return \DOMNode A \DOMNode instance + */ + public function getFormNode() + { + return $this->node; + } + + /** + * Sets the value of the fields. + * + * @param array $values An array of field values + * + * @return Form + * + * @api + */ + public function setValues(array $values) + { + foreach ($values as $name => $value) { + $this->fields->set($name, $value); + } + + return $this; + } + + /** + * Gets the field values. + * + * The returned array does not include file fields (@see getFiles). + * + * @return array An array of field values. + * + * @api + */ + public function getValues() + { + $values = array(); + foreach ($this->fields->all() as $name => $field) { + if ($field->isDisabled()) { + continue; + } + + if (!$field instanceof Field\FileFormField && $field->hasValue()) { + $values[$name] = $field->getValue(); + } + } + + return $values; + } + + /** + * Gets the file field values. + * + * @return array An array of file field values. + * + * @api + */ + public function getFiles() + { + if (!in_array($this->getMethod(), array('POST', 'PUT', 'DELETE', 'PATCH'))) { + return array(); + } + + $files = array(); + + foreach ($this->fields->all() as $name => $field) { + if ($field->isDisabled()) { + continue; + } + + if ($field instanceof Field\FileFormField) { + $files[$name] = $field->getValue(); + } + } + + return $files; + } + + /** + * Gets the field values as PHP. + * + * This method converts fields with the array notation + * (like foo[bar] to arrays) like PHP does. + * + * @return array An array of field values. + * + * @api + */ + public function getPhpValues() + { + $qs = http_build_query($this->getValues(), '', '&'); + parse_str($qs, $values); + + return $values; + } + + /** + * Gets the file field values as PHP. + * + * This method converts fields with the array notation + * (like foo[bar] to arrays) like PHP does. + * + * @return array An array of field values. + * + * @api + */ + public function getPhpFiles() + { + $qs = http_build_query($this->getFiles(), '', '&'); + parse_str($qs, $values); + + return $values; + } + + /** + * Gets the URI of the form. + * + * The returned URI is not the same as the form "action" attribute. + * This method merges the value if the method is GET to mimics + * browser behavior. + * + * @return string The URI + * + * @api + */ + public function getUri() + { + $uri = parent::getUri(); + + if (!in_array($this->getMethod(), array('POST', 'PUT', 'DELETE', 'PATCH')) && $queryString = http_build_query($this->getValues(), null, '&')) { + $sep = false === strpos($uri, '?') ? '?' : '&'; + $uri .= $sep.$queryString; + } + + return $uri; + } + + protected function getRawUri() + { + return $this->node->getAttribute('action'); + } + + /** + * Gets the form method. + * + * If no method is defined in the form, GET is returned. + * + * @return string The method + * + * @api + */ + public function getMethod() + { + if (null !== $this->method) { + return $this->method; + } + + return $this->node->getAttribute('method') ? strtoupper($this->node->getAttribute('method')) : 'GET'; + } + + /** + * Returns true if the named field exists. + * + * @param string $name The field name + * + * @return Boolean true if the field exists, false otherwise + * + * @api + */ + public function has($name) + { + return $this->fields->has($name); + } + + /** + * Removes a field from the form. + * + * @param string $name The field name + * + * @throws \InvalidArgumentException when the name is malformed + * + * @api + */ + public function remove($name) + { + $this->fields->remove($name); + } + + /** + * Gets a named field. + * + * @param string $name The field name + * + * @return FormField The field instance + * + * @throws \InvalidArgumentException When field is not present in this form + * + * @api + */ + public function get($name) + { + return $this->fields->get($name); + } + + /** + * Sets a named field. + * + * @param FormField $field The field + * + * @api + */ + public function set(FormField $field) + { + $this->fields->add($field); + } + + /** + * Gets all fields. + * + * @return array An array of fields + * + * @api + */ + public function all() + { + return $this->fields->all(); + } + + /** + * Returns true if the named field exists. + * + * @param string $name The field name + * + * @return Boolean true if the field exists, false otherwise + */ + public function offsetExists($name) + { + return $this->has($name); + } + + /** + * Gets the value of a field. + * + * @param string $name The field name + * + * @return FormField The associated Field instance + * + * @throws \InvalidArgumentException if the field does not exist + */ + public function offsetGet($name) + { + return $this->fields->get($name); + } + + /** + * Sets the value of a field. + * + * @param string $name The field name + * @param string|array $value The value of the field + * + * @throws \InvalidArgumentException if the field does not exist + */ + public function offsetSet($name, $value) + { + $this->fields->set($name, $value); + } + + /** + * Removes a field from the form. + * + * @param string $name The field name + */ + public function offsetUnset($name) + { + $this->fields->remove($name); + } + + protected function setNode(\DOMNode $node) + { + $this->button = $node; + if ('button' == $node->nodeName || ('input' == $node->nodeName && in_array($node->getAttribute('type'), array('submit', 'button', 'image')))) { + do { + // use the ancestor form element + if (null === $node = $node->parentNode) { + throw new \LogicException('The selected node does not have a form ancestor.'); + } + } while ('form' != $node->nodeName); + } elseif ('form' != $node->nodeName) { + throw new \LogicException(sprintf('Unable to submit on a "%s" tag.', $node->nodeName)); + } + + $this->node = $node; + } + + private function initialize() + { + $this->fields = new FormFieldRegistry(); + + $document = new \DOMDocument('1.0', 'UTF-8'); + $node = $document->importNode($this->node, true); + $button = $document->importNode($this->button, true); + $root = $document->appendChild($document->createElement('_root')); + $root->appendChild($node); + $root->appendChild($button); + $xpath = new \DOMXPath($document); + + foreach ($xpath->query('descendant::input | descendant::textarea | descendant::select', $root) as $node) { + if (!$node->hasAttribute('name')) { + continue; + } + + $nodeName = $node->nodeName; + + if ($node === $button) { + $this->set(new Field\InputFormField($node)); + } elseif ('select' == $nodeName || 'input' == $nodeName && 'checkbox' == $node->getAttribute('type')) { + $this->set(new Field\ChoiceFormField($node)); + } elseif ('input' == $nodeName && 'radio' == $node->getAttribute('type')) { + if ($this->has($node->getAttribute('name'))) { + $this->get($node->getAttribute('name'))->addChoice($node); + } else { + $this->set(new Field\ChoiceFormField($node)); + } + } elseif ('input' == $nodeName && 'file' == $node->getAttribute('type')) { + $this->set(new Field\FileFormField($node)); + } elseif ('input' == $nodeName && !in_array($node->getAttribute('type'), array('submit', 'button', 'image'))) { + $this->set(new Field\InputFormField($node)); + } elseif ('textarea' == $nodeName) { + $this->set(new Field\TextareaFormField($node)); + } + } + } +} + +class FormFieldRegistry +{ + private $fields = array(); + + private $base; + + /** + * Adds a field to the registry. + * + * @param FormField $field The field + * + * @throws \InvalidArgumentException when the name is malformed + */ + public function add(FormField $field) + { + $segments = $this->getSegments($field->getName()); + + $target =& $this->fields; + while ($segments) { + if (!is_array($target)) { + $target = array(); + } + $path = array_shift($segments); + if ('' === $path) { + $target =& $target[]; + } else { + $target =& $target[$path]; + } + } + $target = $field; + } + + /** + * Removes a field and its children from the registry. + * + * @param string $name The fully qualified name of the base field + * + * @throws \InvalidArgumentException when the name is malformed + */ + public function remove($name) + { + $segments = $this->getSegments($name); + $target =& $this->fields; + while (count($segments) > 1) { + $path = array_shift($segments); + if (!array_key_exists($path, $target)) { + return; + } + $target =& $target[$path]; + } + unset($target[array_shift($segments)]); + } + + /** + * Returns the value of the field and its children. + * + * @param string $name The fully qualified name of the field + * + * @return mixed The value of the field + * + * @throws \InvalidArgumentException when the name is malformed + * @throws \InvalidArgumentException if the field does not exist + */ + public function &get($name) + { + $segments = $this->getSegments($name); + $target =& $this->fields; + while ($segments) { + $path = array_shift($segments); + if (!array_key_exists($path, $target)) { + throw new \InvalidArgumentException(sprintf('Unreachable field "%s"', $path)); + } + $target =& $target[$path]; + } + + return $target; + } + + /** + * Tests whether the form has the given field. + * + * @param string $name The fully qualified name of the field + * + * @return Boolean Whether the form has the given field + */ + public function has($name) + { + try { + $this->get($name); + + return true; + } catch (\InvalidArgumentException $e) { + return false; + } + } + + /** + * Set the value of a field and its children. + * + * @param string $name The fully qualified name of the field + * @param mixed $value The value + * + * @throws \InvalidArgumentException when the name is malformed + * @throws \InvalidArgumentException if the field does not exist + */ + public function set($name, $value) + { + $target =& $this->get($name); + if (is_array($value)) { + $fields = self::create($name, $value); + foreach ($fields->all() as $k => $v) { + $this->set($k, $v); + } + } else { + $target->setValue($value); + } + } + + /** + * Returns the list of field with their value. + * + * @return array The list of fields as array((string) Fully qualified name => (mixed) value) + */ + public function all() + { + return $this->walk($this->fields, $this->base); + } + + /** + * Creates an instance of the class. + * + * This function is made private because it allows overriding the $base and + * the $values properties without any type checking. + * + * @param string $base The fully qualified name of the base field + * @param array $values The values of the fields + * + * @return FormFieldRegistry + */ + static private function create($base, array $values) + { + $registry = new static(); + $registry->base = $base; + $registry->fields = $values; + + return $registry; + } + + /** + * Transforms a PHP array in a list of fully qualified name / value. + * + * @param array $array The PHP array + * @param string $base The name of the base field + * @param array $output The initial values + * + * @return array The list of fields as array((string) Fully qualified name => (mixed) value) + */ + private function walk(array $array, $base = '', array &$output = array()) + { + foreach ($array as $k => $v) { + $path = empty($base) ? $k : sprintf("%s[%s]", $base, $k); + if (is_array($v)) { + $this->walk($v, $path, $output); + } else { + $output[$path] = $v; + } + } + + return $output; + } + + /** + * Splits a field name into segments as a web browser would do. + * + * + * getSegments('base[foo][3][]') = array('base', 'foo, '3', ''); + * + * + * @param string $name The name of the field + * + * @return array The list of segments + * + * @throws \InvalidArgumentException when the name is malformed + */ + private function getSegments($name) + { + if (preg_match('/^(?P[^[]+)(?P(\[.*)|$)/', $name, $m)) { + $segments = array($m['base']); + while (preg_match('/^\[(?P.*?)\](?P.*)$/', $m['extra'], $m)) { + $segments[] = $m['segment']; + } + + return $segments; + } + + throw new \InvalidArgumentException(sprintf('Malformed field path "%s"', $name)); + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/LICENSE b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/LICENSE new file mode 100644 index 0000000..cdffe7a --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 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/symfony/src/Symfony/Component/DomCrawler/Link.php b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Link.php new file mode 100644 index 0000000..1804111 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Link.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\DomCrawler; + +/** + * Link represents an HTML link (an HTML a tag). + * + * @author Fabien Potencier + * + * @api + */ +class Link +{ + /** + * @var \DOMNode A \DOMNode instance + */ + protected $node; + /** + * @var string The method to use for the link + */ + protected $method; + /** + * @var string The URI of the page where the link is embedded (or the base href) + */ + protected $currentUri; + + /** + * Constructor. + * + * @param \DOMNode $node A \DOMNode instance + * @param string $currentUri The URI of the page where the link is embedded (or the base href) + * @param string $method The method to use for the link (get by default) + * + * @throws \InvalidArgumentException if the node is not a link + * + * @api + */ + public function __construct(\DOMNode $node, $currentUri, $method = 'GET') + { + if (!in_array(substr($currentUri, 0, 4), array('http', 'file'))) { + throw new \InvalidArgumentException(sprintf('Current URI must be an absolute URL ("%s").', $currentUri)); + } + + $this->setNode($node); + $this->method = $method ? strtoupper($method) : null; + $this->currentUri = $currentUri; + } + + /** + * Gets the node associated with this link. + * + * @return \DOMNode A \DOMNode instance + */ + public function getNode() + { + return $this->node; + } + + /** + * Gets the method associated with this link. + * + * @return string The method + * + * @api + */ + public function getMethod() + { + return $this->method; + } + + /** + * Gets the URI associated with this link. + * + * @return string The URI + * + * @api + */ + public function getUri() + { + $uri = trim($this->getRawUri()); + + // absolute URL? + if (0 === strpos($uri, 'http')) { + return $uri; + } + + // empty URI + if (!$uri) { + return $this->currentUri; + } + + // only an anchor + if ('#' === $uri[0]) { + $baseUri = $this->currentUri; + if (false !== $pos = strpos($baseUri, '#')) { + $baseUri = substr($baseUri, 0, $pos); + } + + return $baseUri.$uri; + } + + // only a query string + if ('?' === $uri[0]) { + $baseUri = $this->currentUri; + + // remove the query string from the current uri + if (false !== $pos = strpos($baseUri, '?')) { + $baseUri = substr($baseUri, 0, $pos); + } + + return $baseUri.$uri; + } + + // absolute path + if ('/' === $uri[0]) { + return preg_replace('#^(.*?//[^/]+)(?:\/.*)?$#', '$1', $this->currentUri).$uri; + } + + // relative path + return substr($this->currentUri, 0, strrpos($this->currentUri, '/') + 1).$uri; + } + + /** + * Returns raw uri data + * + * @return string + */ + protected function getRawUri() + { + return $this->node->getAttribute('href'); + } + + /** + * Sets current \DOMNode instance + * + * @param \DOMNode $node A \DOMNode instance + * + * @throws \LogicException If given node is not an anchor + */ + protected function setNode(\DOMNode $node) + { + if ('a' != $node->nodeName) { + throw new \LogicException(sprintf('Unable to click on a "%s" tag.', $node->nodeName)); + } + + $this->node = $node; + } +} diff --git a/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/README.md b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/README.md new file mode 100644 index 0000000..b383b51 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/README.md @@ -0,0 +1,35 @@ +DomCrawler Component +==================== + +DomCrawler eases DOM navigation for HTML and XML documents. + +If you are familiar with jQuery, DomCrawler is a PHP equivalent: + + use Symfony\Component\DomCrawler\Crawler; + + $crawler = new Crawler(); + $crawler->addContent('

    Hello World!

    '); + + print $crawler->filterXPath('descendant-or-self::body/p')->text(); + +If you are also using the CssSelector component, you can use CSS Selectors +instead of XPath expressions: + + use Symfony\Component\DomCrawler\Crawler; + + $crawler = new Crawler(); + $crawler->addContent('

    Hello World!

    '); + + print $crawler->filter('body > p')->text(); + +Resources +--------- + +You can run the unit tests with the following command: + + phpunit + +If you also want to run the unit tests that depend on other Symfony +Components, install dev dependencies before running PHPUnit: + + php composer.phar install --dev diff --git a/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php new file mode 100644 index 0000000..8ccab61 --- /dev/null +++ b/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php @@ -0,0 +1,595 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DomCrawler\Tests; + +use Symfony\Component\DomCrawler\Crawler; + +class CrawlerTest extends \PHPUnit_Framework_TestCase +{ + public function testConstructor() + { + $crawler = new Crawler(); + $this->assertCount(0, $crawler, '__construct() returns an empty crawler'); + + $crawler = new Crawler(new \DOMNode()); + $this->assertCount(1, $crawler, '__construct() takes a node as a first argument'); + } + + /** + * @covers Symfony\Component\DomCrawler\Crawler::add + */ + public function testAdd() + { + $crawler = new Crawler(); + $crawler->add($this->createDomDocument()); + $this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->add() adds nodes from a \DOMDocument'); + + $crawler = new Crawler(); + $crawler->add($this->createNodeList()); + $this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->add() adds nodes from a \DOMNodeList'); + + foreach ($this->createNodeList() as $node) { + $list[] = $node; + } + $crawler = new Crawler(); + $crawler->add($list); + $this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->add() adds nodes from an array of nodes'); + + $crawler = new Crawler(); + $crawler->add($this->createNodeList()->item(0)); + $this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->add() adds nodes from an \DOMNode'); + + $crawler = new Crawler(); + $crawler->add('Foo'); + $this->assertEquals('Foo', $crawler->filterXPath('//body')->text(), '->add() adds nodes from a string'); + } + + /** + * @covers Symfony\Component\DomCrawler\Crawler::addHtmlContent + */ + public function testAddHtmlContent() + { + $crawler = new Crawler(); + $crawler->addHtmlContent('
    ', 'UTF-8'); + + $this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->addHtmlContent() adds nodes from an HTML string'); + + $crawler->addHtmlContent('', 'UTF-8'); + + $this->assertEquals('http://symfony.com', $crawler->filterXPath('//base')->attr('href'), '->addHtmlContent() adds nodes from an HTML string'); + $this->assertEquals('http://symfony.com/contact', $crawler->filterXPath('//a')->link()->getUri(), '->addHtmlContent() adds nodes from an HTML string'); + } + + /** + * @covers Symfony\Component\DomCrawler\Crawler::addHtmlContent + */ + public function testAddHtmlContentCharset() + { + $crawler = new Crawler(); + $crawler->addHtmlContent('
    Tiếng Việt', 'UTF-8'); + + $this->assertEquals('Tiếng Việt', $crawler->filterXPath('//div')->text()); + } + + /** + * @covers Symfony\Component\DomCrawler\Crawler::addHtmlContent + */ + public function testAddHtmlContentWithErrors() + { + libxml_use_internal_errors(true); + + $crawler = new Crawler(); + $crawler->addHtmlContent(<< + + + + + + + +EOF + , 'UTF-8'); + + $errors = libxml_get_errors(); + $this->assertCount(1, $errors); + $this->assertEquals("Tag nav invalid\n", $errors[0]->message); + + libxml_clear_errors(); + libxml_use_internal_errors(false); + } + + /** + * @covers Symfony\Component\DomCrawler\Crawler::addXmlContent + */ + public function testAddXmlContent() + { + $crawler = new Crawler(); + $crawler->addXmlContent('
    ', 'UTF-8'); + + $this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->addXmlContent() adds nodes from an XML string'); + } + + /** + * @covers Symfony\Component\DomCrawler\Crawler::addXmlContent + */ + public function testAddXmlContentCharset() + { + $crawler = new Crawler(); + $crawler->addXmlContent('
    Tiếng Việt
    ', 'UTF-8'); + + $this->assertEquals('Tiếng Việt', $crawler->filterXPath('//div')->text()); + } + + /** + * @covers Symfony\Component\DomCrawler\Crawler::addXmlContent + */ + public function testAddXmlContentWithErrors() + { + libxml_use_internal_errors(true); + + $crawler = new Crawler(); + $crawler->addXmlContent(<< + + + + +
    + + +EOF + , 'UTF-8'); + + $this->assertTrue(count(libxml_get_errors()) > 1); + + libxml_clear_errors(); + libxml_use_internal_errors(false); + } + + /** + * @covers Symfony\Component\DomCrawler\Crawler::addContent + */ + public function testAddContent() + { + $crawler = new Crawler(); + $crawler->addContent('
    ', 'text/html; charset=UTF-8'); + $this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->addContent() adds nodes from an HTML string'); + + $crawler = new Crawler(); + $crawler->addContent('
    ', 'text/html; charset=UTF-8; dir=RTL'); + $this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->addContent() adds nodes from an HTML string with extended content type'); + + $crawler = new Crawler(); + $crawler->addContent('
    '); + $this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->addContent() uses text/html as the default type'); + + $crawler = new Crawler(); + $crawler->addContent('
    ', 'text/xml; charset=UTF-8'); + $this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->addContent() adds nodes from an XML string'); + + $crawler = new Crawler(); + $crawler->addContent('
    ', 'text/xml'); + $this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->addContent() adds nodes from an XML string'); + + $crawler = new Crawler(); + $crawler->addContent('foo bar', 'text/plain'); + $this->assertCount(0, $crawler, '->addContent() does nothing if the type is not (x|ht)ml'); + } + + /** + * @covers Symfony\Component\DomCrawler\Crawler::addDocument + */ + public function testAddDocument() + { + $crawler = new Crawler(); + $crawler->addDocument($this->createDomDocument()); + + $this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->addDocument() adds nodes from a \DOMDocument'); + } + + /** + * @covers Symfony\Component\DomCrawler\Crawler::addNodeList + */ + public function testAddNodeList() + { + $crawler = new Crawler(); + $crawler->addNodeList($this->createNodeList()); + + $this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->addNodeList() adds nodes from a \DOMNodeList'); + } + + /** + * @covers Symfony\Component\DomCrawler\Crawler::addNodes + */ + public function testAddNodes() + { + foreach ($this->createNodeList() as $node) { + $list[] = $node; + } + + $crawler = new Crawler(); + $crawler->addNodes($list); + + $this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->addNodes() adds nodes from an array of nodes'); + } + + /** + * @covers Symfony\Component\DomCrawler\Crawler::addNode + */ + public function testAddNode() + { + $crawler = new Crawler(); + $crawler->addNode($this->createNodeList()->item(0)); + + $this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->addNode() adds nodes from an \DOMNode'); + } + + public function testClear() + { + $crawler = new Crawler(new \DOMNode()); + $crawler->clear(); + $this->assertCount(0, $crawler, '->clear() removes all the nodes from the crawler'); + } + + public function testEq() + { + $crawler = $this->createTestCrawler()->filterXPath('//li'); + $this->assertNotSame($crawler, $crawler->eq(0), '->eq() returns a new instance of a crawler'); + $this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Crawler', $crawler, '->eq() returns a new instance of a crawler'); + + $this->assertEquals('Two', $crawler->eq(1)->text(), '->eq() returns the nth node of the list'); + $this->assertCount(0, $crawler->eq(100), '->eq() returns an empty crawler if the nth node does not exist'); + } + + public function testEach() + { + $data = $this->createTestCrawler()->filterXPath('//ul[1]/li')->each(function ($node, $i) { + return $i.'-'.$node->nodeValue; + }); + + $this->assertEquals(array('0-One', '1-Two', '2-Three'), $data, '->each() executes an anonymous function on each node of the list'); + } + + public function testReduce() + { + $crawler = $this->createTestCrawler()->filterXPath('//ul[1]/li'); + $nodes = $crawler->reduce(function ($node, $i) { + return $i == 1 ? false : true; + }); + $this->assertNotSame($nodes, $crawler, '->reduce() returns a new instance of a crawler'); + $this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Crawler', $nodes, '->reduce() returns a new instance of a crawler'); + + $this->assertCount(2, $nodes, '->reduce() filters the nodes in the list'); + } + + public function testAttr() + { + $this->assertEquals('first', $this->createTestCrawler()->filterXPath('//li')->attr('class'), '->attr() returns the attribute of the first element of the node list'); + + try { + $this->createTestCrawler()->filterXPath('//ol')->attr('class'); + $this->fail('->attr() throws an \InvalidArgumentException if the node list is empty'); + } catch (\InvalidArgumentException $e) { + $this->assertTrue(true, '->attr() throws an \InvalidArgumentException if the node list is empty'); + } + } + + public function testText() + { + $this->assertEquals('One', $this->createTestCrawler()->filterXPath('//li')->text(), '->text() returns the node value of the first element of the node list'); + + try { + $this->createTestCrawler()->filterXPath('//ol')->text(); + $this->fail('->text() throws an \InvalidArgumentException if the node list is empty'); + } catch (\InvalidArgumentException $e) { + $this->assertTrue(true, '->text() throws an \InvalidArgumentException if the node list is empty'); + } + } + + public function testExtract() + { + $crawler = $this->createTestCrawler()->filterXPath('//ul[1]/li'); + + $this->assertEquals(array('One', 'Two', 'Three'), $crawler->extract('_text'), '->extract() returns an array of extracted data from the node list'); + $this->assertEquals(array(array('One', 'first'), array('Two', ''), array('Three', '')), $crawler->extract(array('_text', 'class')), '->extract() returns an array of extracted data from the node list'); + + $this->assertEquals(array(), $this->createTestCrawler()->filterXPath('//ol')->extract('_text'), '->extract() returns an empty array if the node list is empty'); + } + + /** + * @covers Symfony\Component\DomCrawler\Crawler::filterXPath + */ + public function testFilterXPath() + { + $crawler = $this->createTestCrawler(); + $this->assertNotSame($crawler, $crawler->filterXPath('//li'), '->filterXPath() returns a new instance of a crawler'); + $this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Crawler', $crawler, '->filterXPath() returns a new instance of a crawler'); + + $crawler = $this->createTestCrawler()->filterXPath('//ul'); + + $this->assertCount(6, $crawler->filterXPath('//li'), '->filterXPath() filters the node list with the XPath expression'); + } + + /** + * @covers Symfony\Component\DomCrawler\Crawler::filter + */ + public function testFilter() + { + if (!class_exists('Symfony\Component\CssSelector\CssSelector')) { + $this->markTestSkipped('The "CssSelector" component is not available'); + } + + $crawler = $this->createTestCrawler(); + $this->assertNotSame($crawler, $crawler->filter('li'), '->filter() returns a new instance of a crawler'); + $this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Crawler', $crawler, '->filter() returns a new instance of a crawler'); + + $crawler = $this->createTestCrawler()->filter('ul'); + + $this->assertCount(6, $crawler->filter('li'), '->filter() filters the node list with the CSS selector'); + } + + public function testSelectLink() + { + $crawler = $this->createTestCrawler(); + $this->assertNotSame($crawler, $crawler->selectLink('Foo'), '->selectLink() returns a new instance of a crawler'); + $this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Crawler', $crawler, '->selectLink() returns a new instance of a crawler'); + + $this->assertCount(1, $crawler->selectLink('Fabien\'s Foo'), '->selectLink() selects links by the node values'); + $this->assertCount(1, $crawler->selectLink('Fabien\'s Bar'), '->selectLink() selects links by the alt attribute of a clickable image'); + + $this->assertCount(2, $crawler->selectLink('Fabien"s Foo'), '->selectLink() selects links by the node values'); + $this->assertCount(2, $crawler->selectLink('Fabien"s Bar'), '->selectLink() selects links by the alt attribute of a clickable image'); + + $this->assertCount(1, $crawler->selectLink('\' Fabien"s Foo'), '->selectLink() selects links by the node values'); + $this->assertCount(1, $crawler->selectLink('\' Fabien"s Bar'), '->selectLink() selects links by the alt attribute of a clickable image'); + + $this->assertCount(4, $crawler->selectLink('Foo'), '->selectLink() selects links by the node values'); + $this->assertCount(4, $crawler->selectLink('Bar'), '->selectLink() selects links by the node values'); + } + + public function testSelectButton() + { + $crawler = $this->createTestCrawler(); + $this->assertNotSame($crawler, $crawler->selectButton('FooValue'), '->selectButton() returns a new instance of a crawler'); + $this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Crawler', $crawler, '->selectButton() returns a new instance of a crawler'); + + $this->assertEquals(1, $crawler->selectButton('FooValue')->count(), '->selectButton() selects buttons'); + $this->assertEquals(1, $crawler->selectButton('FooName')->count(), '->selectButton() selects buttons'); + $this->assertEquals(1, $crawler->selectButton('FooId')->count(), '->selectButton() selects buttons'); + + $this->assertEquals(1, $crawler->selectButton('BarValue')->count(), '->selectButton() selects buttons'); + $this->assertEquals(1, $crawler->selectButton('BarName')->count(), '->selectButton() selects buttons'); + $this->assertEquals(1, $crawler->selectButton('BarId')->count(), '->selectButton() selects buttons'); + } + + public function testLink() + { + $crawler = $this->createTestCrawler('http://example.com/bar/')->selectLink('Foo'); + $this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Link', $crawler->link(), '->link() returns a Link instance'); + + $this->assertEquals('POST', $crawler->link('post')->getMethod(), '->link() takes a method as its argument'); + + $crawler = $this->createTestCrawler('http://example.com/bar')->selectLink('GetLink'); + $this->assertEquals('http://example.com/bar?get=param', $crawler->link()->getUri(), '->link() returns a Link instance'); + + try { + $this->createTestCrawler()->filterXPath('//ol')->link(); + $this->fail('->link() throws an \InvalidArgumentException if the node list is empty'); + } catch (\InvalidArgumentException $e) { + $this->assertTrue(true, '->link() throws an \InvalidArgumentException if the node list is empty'); + } + } + + public function testLinks() + { + $crawler = $this->createTestCrawler('http://example.com/bar/')->selectLink('Foo'); + $this->assertInternalType('array', $crawler->links(), '->links() returns an array'); + + $this->assertCount(4, $crawler->links(), '->links() returns an array'); + $links = $crawler->links(); + $this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Link', $links[0], '->links() returns an array of Link instances'); + + $this->assertEquals(array(), $this->createTestCrawler()->filterXPath('//ol')->links(), '->links() returns an empty array if the node selection is empty'); + } + + public function testForm() + { + $crawler = $this->createTestCrawler('http://example.com/bar/')->selectButton('FooValue'); + $this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Form', $crawler->form(), '->form() returns a Form instance'); + + $this->assertEquals(array('FooName' => 'FooBar'), $crawler->form(array('FooName' => 'FooBar'))->getValues(), '->form() takes an array of values to submit as its first argument'); + + try { + $this->createTestCrawler()->filterXPath('//ol')->form(); + $this->fail('->form() throws an \InvalidArgumentException if the node list is empty'); + } catch (\InvalidArgumentException $e) { + $this->assertTrue(true, '->form() throws an \InvalidArgumentException if the node list is empty'); + } + } + + public function testLast() + { + $crawler = $this->createTestCrawler()->filterXPath('//ul[1]/li'); + $this->assertNotSame($crawler, $crawler->last(), '->last() returns a new instance of a crawler'); + $this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Crawler', $crawler, '->last() returns a new instance of a crawler'); + + $this->assertEquals('Three', $crawler->last()->text()); + } + + public function testFirst() + { + $crawler = $this->createTestCrawler()->filterXPath('//li'); + $this->assertNotSame($crawler, $crawler->first(), '->first() returns a new instance of a crawler'); + $this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Crawler', $crawler, '->first() returns a new instance of a crawler'); + + $this->assertEquals('One', $crawler->first()->text()); + } + + public function testSiblings() + { + $crawler = $this->createTestCrawler()->filterXPath('//li')->eq(1); + $this->assertNotSame($crawler, $crawler->siblings(), '->siblings() returns a new instance of a crawler'); + $this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Crawler', $crawler, '->siblings() returns a new instance of a crawler'); + + $nodes = $crawler->siblings(); + $this->assertEquals(2, $nodes->count()); + $this->assertEquals('One', $nodes->eq(0)->text()); + $this->assertEquals('Three', $nodes->eq(1)->text()); + + $nodes = $this->createTestCrawler()->filterXPath('//li')->eq(0)->siblings(); + $this->assertEquals(2, $nodes->count()); + $this->assertEquals('Two', $nodes->eq(0)->text()); + $this->assertEquals('Three', $nodes->eq(1)->text()); + + try { + $this->createTestCrawler()->filterXPath('//ol')->siblings(); + $this->fail('->siblings() throws an \InvalidArgumentException if the node list is empty'); + } catch (\InvalidArgumentException $e) { + $this->assertTrue(true, '->siblings() throws an \InvalidArgumentException if the node list is empty'); + } + } + + public function testNextAll() + { + $crawler = $this->createTestCrawler()->filterXPath('//li')->eq(1); + $this->assertNotSame($crawler, $crawler->nextAll(), '->nextAll() returns a new instance of a crawler'); + $this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Crawler', $crawler, '->nextAll() returns a new instance of a crawler'); + + $nodes = $crawler->nextAll(); + $this->assertEquals(1, $nodes->count()); + $this->assertEquals('Three', $nodes->eq(0)->text()); + + try { + $this->createTestCrawler()->filterXPath('//ol')->nextAll(); + $this->fail('->nextAll() throws an \InvalidArgumentException if the node list is empty'); + } catch (\InvalidArgumentException $e) { + $this->assertTrue(true, '->nextAll() throws an \InvalidArgumentException if the node list is empty'); + } + } + + public function testPreviousAll() + { + $crawler = $this->createTestCrawler()->filterXPath('//li')->eq(2); + $this->assertNotSame($crawler, $crawler->previousAll(), '->previousAll() returns a new instance of a crawler'); + $this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Crawler', $crawler, '->previousAll() returns a new instance of a crawler'); + + $nodes = $crawler->previousAll(); + $this->assertEquals(2, $nodes->count()); + $this->assertEquals('Two', $nodes->eq(0)->text()); + + try { + $this->createTestCrawler()->filterXPath('//ol')->previousAll(); + $this->fail('->previousAll() throws an \InvalidArgumentException if the node list is empty'); + } catch (\InvalidArgumentException $e) { + $this->assertTrue(true, '->previousAll() throws an \InvalidArgumentException if the node list is empty'); + } + } + + public function testChildren() + { + $crawler = $this->createTestCrawler()->filterXPath('//ul'); + $this->assertNotSame($crawler, $crawler->children(), '->children() returns a new instance of a crawler'); + $this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Crawler', $crawler, '->children() returns a new instance of a crawler'); + + $nodes = $crawler->children(); + $this->assertEquals(3, $nodes->count()); + $this->assertEquals('One', $nodes->eq(0)->text()); + $this->assertEquals('Two', $nodes->eq(1)->text()); + $this->assertEquals('Three', $nodes->eq(2)->text()); + + try { + $this->createTestCrawler()->filterXPath('//ol')->children(); + $this->fail('->children() throws an \InvalidArgumentException if the node list is empty'); + } catch (\InvalidArgumentException $e) { + $this->assertTrue(true, '->children() throws an \InvalidArgumentException if the node list is empty'); + } + } + + public function testParents() + { + $crawler = $this->createTestCrawler()->filterXPath('//li[1]'); + $this->assertNotSame($crawler, $crawler->parents(), '->parents() returns a new instance of a crawler'); + $this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Crawler', $crawler, '->parents() returns a new instance of a crawler'); + + $nodes = $crawler->parents(); + $this->assertEquals(3, $nodes->count()); + + $nodes = $this->createTestCrawler()->filterXPath('//html')->parents(); + $this->assertEquals(0, $nodes->count()); + + try { + $this->createTestCrawler()->filterXPath('//ol')->parents(); + $this->fail('->parents() throws an \InvalidArgumentException if the node list is empty'); + } catch (\InvalidArgumentException $e) { + $this->assertTrue(true, '->parents() throws an \InvalidArgumentException if the node list is empty'); + } + } + + public function createTestCrawler($uri = null) + { + $dom = new \DOMDocument(); + $dom->loadHTML(' + + +
    Foo + Fabien\'s Foo + Fabien"s Foo + \' Fabien"s Foo + + Bar +    Fabien\'s Bar   + Fabien"s Bar + \' Fabien"s Bar + + GetLink + +
    + + +